パズル万華鏡

現在、プログラミング技術の紹介と解説をしています。

数の五線星形問題・考察(3)

 数の五線星形問題・考察(3)を紹介します。


考察(3)

 五線星形の10個の○の中に、1から12までの数字の内、10個を選び入れる。
5本の直線上に並ぶ数の和(A+C+F+I,A+D+G+J,B+C+D+E,B+F+H+J,E+G+H+I)が
いずれも同じになる配置を考察する。
f:id:isemba:20151102151031j:plain
 1~12までの数から10個の数を選んだ和をM、5本の直線上に並ぶ数の和をmとする。

  A+C+F+I=A+D+G+J=B+C+D+E=B+F+H+J=E+G+H+I=m

A+B+C+D+E+F+G+H+I+J=M

 このとき、5m=2M が成り立つ。

したがって、Mは55以上75以下であるから、2×55≦5m≦2×75となり、
22≦m≦30を得る。

プログラム(FS131.bas)からつぎの結果を得た。
f:id:isemba:20151102151102j:plain
●プログラムの工夫

・集合{1,2,…,12}上の長さ10の部分順列をすべて生成していく。

・生成される順列P(1)P(2)…P(10)と辺上の数A,B,…,Jの対応
f:id:isemba:20151102151126j:plain
・五線星形の対称性から、AにA,B,E,I,Jの最小値を割り当て、B<Eが成り立つものを求める。

●プログラム(FS131.bas)

' << FS131.bas >>
' Tiny Basic
' 数の五線星形問題を解くプログラム。
'
Public N:     ' 集合{1,2,…,12}の要素数。
Public M:     ' 辺の合計値。
Public R:     ' 集合{1,2,…,12}上の部分順列の長さ。
Public COUNT: ' 部分順列の個数。
Public P(12): ' 部分順列を保存する配列
'
' 初期設定。
N=12
R=10
'
Do
  ' 辺の合計値Mの読み込み。                     
  Read M                                      
  If M <= 0 Then Exit Do
  '                                         
  ' 初期設定。                              
  COUNT=0                                   
  For I=1 To N: P(I)=I: Next I              
  '                                         
  ' 部分順列の生成。                        
  Call Perm (1)                             
  Print"辺の合計値=";M;" 解の個数:";COUNT            
  Print                                     
Loop
'
' データ。
Data 22,23,24,25,26,27,28,29,30,0
End                                      
'
' 部分順列をすべて生成する手続き。
' Kは部分順列K番目の要素を意味する。
Sub Perm(K)
  If K = 3 Then
    If P(2) < P(1) Then Exit Sub
  End If
  '
  If K = 6 Then
    If P(5) < P(1) Then Exit Sub
    If P(5) < P(2) Then Exit Sub
    S=P(2)+P(3)+P(4)+P(5)
    If S <> M Then Exit Sub
  End If
  '
  If K = 10 Then
    If P(9) < P(1) Then Exit Sub
    S=P(1)+P(3)+P(6)+P(9)
    If S <> M Then Exit Sub
    S=P(5)+P(7)+P(8)+P(9)
    If S <> M Then Exit Sub
  End If
  '
  If K = 11 Then
    If P(10) < P(1) Then Exit Sub
    S=P(1)+P(4)+P(7)+P(10)
    If S <> M Then Exit Sub
    S=P(2)+P(6)+P(8)+P(10)
    If S <> M Then Exit Sub
  End If
  '
  If K > R Then
    ' 解の表示。
    COUNT=COUNT+1                                
    Print Using"[##]";COUNT;                     
    For I=1 To R: Print Using"###";P(I);: Next I
    Print
    Exit Sub
  End If
  '
  ' つぎの位置の要素を指定する。
  For I=K To N
    W=P(K): P(K)=P(I): P(I)=W
    Call Perm(K+1)
    W=P(K): P(K)=P(I): P(I)=W
  Next I
End Sub

実行結果
f:id:isemba:20151102151248j:plain
f:id:isemba:20151102151300j:plain