平成11年10月26日
[流れ星]第32回
数学的な応募問題<解答募集期間:10月26日〜11月8日>
[素数・△数・□数]
太郎さんは、「
数学ができないから、嫌い」というやる気のない生徒をどのようにして引きつけるかを、考えながら授業をしています。「それは、いかにして生徒に感動を与えられるかにかかってきます。そのために教材や教具を使い、また、情報機器をも使っています。心への感動は、生徒が動いてくれることを信じていますから」。さらに、数学教師としてやりがいを持って、生徒に丁寧に接していくつもりです。生徒からの質問が大好きです。さて、今回の問題です。
「0から9までの数字を1列に並べ、隣り合う2数から9つの2桁の整数を作る。
このとき、この2数が整数が、素数なら3点、四角数なら2点、三角数なら1点
のように得点が与えることにする。
できるだけ高い得点が得られるように、0から9までの数字を1列に並べてください。
例えば、1234567890の場合、左から順にできる9個の2桁の整数を調べると、
12…0点、 23…素数なので3点、 34…0点、 45…三角数なので1点
56…0点、 67…素数なので3点、 78…三角数なので1点、
89…素数なので3点、 90…0点
したがって、合計11点となる。ただし、次のことに注意してください。
@ たとえば、「02」は「2」とみなす。
A 四角数かつ三角数のときは、2+1=3点とする。
B 三角数とは、1,3,6,10,15,21,28,36,45,55,66,78,91 です。
C 四角数とは、1,4,9,16,25,36,49,64,81 です。
D 素数は自分で考えてください。
<参考文献>:数とその歴史53話(上垣渉 何森仁 共著):三省堂
太郎さんは、一番高得点の並び方を実際知りません。生徒に、並べてもらって、得点を調べてもらおうと考えています。
<ch3cooh>さんからの解答 10月26日受信 31日更新
こんにちは、
ch3coohです(毎度お世話になります)何か、答えを求める理論があるのかもしれませんが・・・とりあえず、理論を思い付かなかったので、プログラムに実行させました。
32問の答え(同一スコアの解答なし)
score : value-list
23 : 0 2 5 3 6 4 1 7 8 9
02:3
25:2
53:3
36:3
64:2
41:3
17:3
78:1
89:3
プログラムのNを変更すると、N進数の場合について求めることが可能です。
例えば、8進数(同一スコア 多数)
16 : 0 2 1 3 4 5 7 6
9進数
25 : 6 5 2 1 8 7 4 0 3
25 : 6 5 8 7 4 0 3 2 1
25 : 6 7 4 0 3 2 5 8 1
25 : 6 7 8 1 4 0 3 2 5
12進数(同一スコアのリスト)
24 : 8 4 5 6 9 1 3 0 2 7 10 11
24 : 8 4 5 6 9 1 3 0 2 10 11 7
24 : 8 4 10 11 5 6 9 1 3 0 2 7
24 : 8 4 10 11 7 5 6 9 1 3 0 2
24 : 8 4 11 5 6 9 1 3 0 2 7 10
24 : 8 4 11 5 6 9 1 3 0 2 10 7
24 : 8 4 11 7 5 6 9 1 3 0 2 10
24 : 8 4 11 10 7 5 6 9 1 3 0 2
24 : 10 7 5 6 9 1 3 0 2 8 4 11
24 : 10 7 8 4 11 5 6 9 1 3 0 2
24 : 10 8 4 11 5 6 9 1 3 0 2 7
24 : 10 8 4 11 7 5 6 9 1 3 0 2
24 : 10 11 5 6 9 1 3 0 2 7 8 4
24 : 10 11 7 5 6 9 1 3 0 2 8 4
24 : 10 11 7 8 4 5 6 9 1 3 0 2
24 : 10 11 8 4 5 6 9 1 3 0 2 7
20進数
計算時間がかかりすぎるので、あきらめたとなります。(プログラムは単純なループで作成していますが、
もう少し高速化の方法があるかもしれません。)この計算は、(現時点で)結構速いコンピュータで解いたため、
そこそこの時間で解答を得ることが出来ましたが、コンピュータが遅い時代では大変だったと思います。
極限値を求める計算などでは、その収束のスピードが経済性に大きな影響を与えると思います。(最も顕著な例がπの算出)高校レベルでの微分・積分や極限値の算出では、収束の速度まで厳密に求めませんが、実用性のある知識とするには、誤差の程度や収束の速度の問題は重要な課題ではないでしょうか?
以上 プログラム
#include <stdio.h>
#define N 10 int score_table[N*N] ;
void gen_tbl( void )
{int i, j ;for( i= 0 ; i< N*N ; i++ )
score_table[i]= 0 ;j= 1 ;
for( i= 2 ; j< N*N ; i++ )
score_table[j]= 1 ;j+= i ;}j= 1 ;
for( i= 3 ; j< N*N ; i+=2 )
{score_table[j]+= 2 ;j+= i ;}
for( i= 2 ; i< N*N ; i++ )
{for( j= 2 ; j*j< i ; j++ )
if ( i%j== 0 ) break ;
if ( j*j> i ) score_table[i]+= 3 ;}
#ifdef DEBUG3
for( i= 0 ; i< N*N ; i++ )
printf( "%3d : %d\n", i, score_table[i] ) ;
#endif}
intcount_score( int *value )
{int r, i, v ;r= 0 ;
for( i= 0 ; i< N-1 ; i++ )
{v= value[i]*N+value[i+1] ;
#ifdef DEBUG1
printf( "(%2d,%2d)", v, score_table[v] ) ;#endif
r+= score_table[v] ;}
#ifdef DEBUG1
printf( ":%4d\n", r ) ;
#endif
return r ;}
intmain( void )
{int i, j, max_score ;
int flags[N] ;
int list[N] ;
int max_list[N] ;
gen_tbl( ) ;
for( i= 0 ; i< N ; i++ )
{flags[i]= 0 ;}
i= 0 ;max_score= 0 ;
list[0]= -1 ;
do{list[i]++ ;
#ifdef DEBUG2
for( j= 0 ; j< i ; j++ ) putchar( ' ' ) ;
printf( "%2d : %2d\n", i, list[i] ) ;
#endif
if ( list[i]== N )
{i-- ;if ( i>= 0 ) flags[list[i]]= 0 ;
continue ;}
if ( flags[list[i]]== 0 )
{if ( i== N-1 )
{j= count_score( list ) ;
if ( max_score< j )
{max_score= j ;
for( j= 0 ; j< N ; j++ )
max_list[j]= list[j] ;
#ifdef DEBUG4
printf( "%4d :", max_score ) ;
for( j= 0 ; j< N ; j++ )
printf( "%2d", max_list[j] ) ;
putchar( '\n' ) ;
#endif}
} else {flags[list[i]]= i+1 ;
i++ ;list[i]= -1 ;}}}
while( i>= 0 ) ;
printf( "%4d :", max_score ) ;
for( i= 0 ; i< N ; i++ )
printf( "%2d", max_list[i] ) ;
putchar( '\n' ) ;
return 0 ;}
<浜田明巳>さんからの解答 29日受信 31日更新
第32回数学的な応募問題[素数・△数・□数]解答
早々と23点という答が出てしまった問題ですが,ようやく私も十進basicでの解答プログラムが出来上がったので,投稿します.工夫も全然していないプログラムで恥ずかしい限りですが,これが今のところ私の限界です.十進basicですと,解答が簡単にテキストファイルで掃き出されるので,これでプログラムを作ってみました.
以下の7通りの場合があります.
23 0 2 5 3 6 4 1 7 8 9
23 0 2 5 3 6 4 1 9 7 8
23 0 2 5 9 7 8 3 6 4 1
23 8 3 6 4 1 0 2 5 9 7
23 8 3 6 4 7 1 0 2 5 9
23 8 9 7 1 0 2 5 3 6 4
23 8 9 7 3 6 4 1 0 2 5
!mondai32.bas
option base 0
dim j(9)
let max=0
for j0=0 to 9
let j(0)=j0
for j1=0 to 9
if j0<>j1 then
let j(1)=j1
for j2=0 to 9
if j0<>j2 and j1<>j2 then
let j(2)=j2
for j3=0 to 9
if j0<>j3 and j1<>j3 and j2<>j3 then
let j(3)=j3
for j4=0 to 9
if j0<>j4 and j1<>j4 and j2<>j4 and j3<>j4 then
let j(4)=j4
for j5=0 to 9
if j0<>j5 and j1<>j5 and j2<>j5 and j3<>j5 and j4<>j5 then
let j(5)=j5
for j6=0 to 9
if j0<>j6 and j1<>j6 and j2<>j6 and j3<>j6 and j4<>j6 and j5<>j6 then
let j(6)=j6
for j7=0 to 9
if j0<>j7 and j1<>j7 and j2<>j7 and j3<>j7 and j4<>j7 and j5<>j7 and j6<>j7 then
let j(7)=j7
for j8=0 to
if j0<>j8 and j1<>j8 and j2<>j8 and j3<>j8 and j4<>j8 and j5<>j8 and j6<>j8 and j7<>j8 then
let j(8)=j8
let j(9)=9
for jj=0 to 8
let j(9)=j(9)+jj-j(jj)
next jj
let ten=0
for jj=0 to 8
let check=10*j(jj)+j(jj+1)
let ten=ten+3*sosuu(check)
let suu=(sqr(1+8*check)-1)*0.5
let ten=ten+seisuu(suu)
let suu=sqr(check)
let ten=ten+2*seisuu(suu)
next jj
if ten>=max then
if ten>max then
let max=ten
end if
print max;
for jj=0 to 9
print j(jj);
next jj
end if
end if
next j8
end if
next j7
end if
next j6
end if
next j5
end if
next j4
end if
next j3
end if
next j2
end if
next j1
next j0
end
external function sosuu(x)
if x=1 then
let sosuu=0
else
let yakusuu=0
let j=2
do while yakusuu=0 and j<=int(sqr(x))
if mod(x,j)=0 then
let yakusuu=1
end if
let j=j+1
loop
let sosuu=1-yakusuu
end if
end function
external function seisuu(x)
if int(x)=x then
let seisuu=1
else
let seisuu=0
end if
end function
素数問題なので,最初は素数の値を標準装備されている関数で簡単に求める事が出来るubasicでプログラムを組みました.しかし,DOSのプログラムではマルチタスクではないので,時間のかかる計算は不向きでしたので,Windowsのプログラムに移植した訳です.
<浜田明巳>さんからの解答その2 11月2日受信 3日更新
第32回数学的な応募問題[素数・△数・□数]解答その2
前回十進basicで解答プログラムを作ったのですが,その後エクセルのマクロに移植し走らせたところ,十進basicのよりも計算スピードが早い事が分かりました.参考までにこのプログラムも投稿します.ワードのマクロに移植しても同様です.
23 0 2 5 3 6 4 1 7 8 9
23 0 2 5 3 6 4 1 9 7 8
23 0 2 5 9 7 8 3 6 4 1
23 8 3 6 4 1 0 2 5 9 7
23 8 3 6 4 7 1 0 2 5 9
23 8 9 7 1 0 2 5 3 6 4
23 8 9 7 3 6 4 1 0 2 5
Sub mondai32() 'mondai32
Dim j(9), j0, j1, j2, j3, j4, j5, j6, j7, j8, jj As Integer
Dim ten, check, max As Integer: max = 0
Dim suu As Double
Range("A1").Select
For j0 = 0 To 9: j(0) = j0
For j1 = 0 To 9
If j0 <> j1 Then
j(1) = j1
For j2 = 0 To 9
If j0 <> j2 And j1 <> j2 Then
j(2) = j2
For j3 = 0 To 9
If j0 <> j3 And j1 <> j3 And j2 <> j3 Then
j(3) = j3
For j4 = 0 To 9
If j0 <> j4 And j1 <> j4 And j2 <> j4 And j3 <> j4 Then
j(4) = j4
For j5 = 0 To
If j0 <> j5 And j1 <> j5 And j2 <> j5 And j3 <> j5 And j4 <> j5 Then
j(5) = j5
For j6 = 0 To 9
If j0 <> j6 And j1 <> j6 And j2 <> j6 And j3 <> j6 And j4 <> j6 And j5 <> j6 Then
j(6) = j6
For j7 = 0 To 9
If j0 <> j7 And j1 <> j7 And j2 <> j7 And j3 <> j7 And j4 <> j7 And j5 <> j7 And j6 <> j7 Then
j(7) = j7
For j8 = 0 To 9
If j0 <> j8 And j1 <> j8 And j2 <> j8 And j3 <> j8 And j4 <> j8 And j5 <> j8 And j6 <> j8 And j7 <> j8 Then
j(8) = j8
j(9) = 9: For jj = 0 To 8: j(9) = j(9) + jj - j(jj): Next
ten = 0
For jj = 0 To 8: check = 10 * j(jj) + j(jj + 1)
ten = ten + 3 * sosuu(check)
suu = (Sqr(1 + 8 * check) - 1) * 0.5
ten = ten + seisuu(suu)
suu = Sqr(check): ten = ten + 2 * seisuu(suu)
Next If ten >= max
Then
max = ten
ActiveCell.FormulaR1C1 = max
For jj = 0 To 9
SendKeys "{right}", True
ActiveCell.FormulaR1C1 = j(jj)
Next
SendKeys "{down}", True
For jj = 0 To 10: SendKeys "{left}", True: Nex
End If
End If
Next
End If
Next
End If
Next
End If
Next
End If
Next
End If
Next
End If
Next
End If
Next
Next
Beep
End Sub
Private Function sosuu(ByVal x As Integer) As Integer
Dim yakusuu, j As Integer
If x = 1 Then
sosuu = 0
Else
yakusuu = 0: j = 2
While yakusuu = 0 And j <= Int(Sqr(x))
yakusuu = -(x Mod j = 0): j = j + 1
Wend
sosuu = 1 - yakusuu
End If
End Function
Private Function seisuu(ByVal x As Double) As Integer
seisuu = -(Int(x) = x)
End Function
<自宅>
mizuryu@aqua.ocn.ne.jp最初のページへもどる