プログラミングなどなど

プログラミングに関係しそうな内容を

Prolog:3x3の魔法陣の解を求める

gprologのFDの練習として、SPINで以前に書いた3x3の魔法陣の解を求めてみます。gprologのソースファイルにはサンプルが含まれています。その中にmagsq.plがあり、魔法陣のサイズを指定できるものがあります。

ソース ms.pl

/* 魔法陣 */
ms(MS) :-

  MS = [ V11, V12, V13,
         V21, V22, V23,
         V31, V32, V33 ],

  /* 各要素は1〜9である。*/
  fd_domain(MS, 1, 9),

  /* 各要素の値は異なる。*/
  fd_all_different(MS),

  /* 行の和は15である。*/
  V11 + V12 + V13 #= 15,
  V21 + V22 + V23 #= 15,
  V31 + V32 + V33 #= 15,

  /* 列の和は15である。*/
  V11 + V21 + V31 #= 15,
  V12 + V22 + V32 #= 15,
  V13 + V23 + V33 #= 15,

  /* 対角の和は15である。*/
  V11 + V22 + V33 #= 15,
  V31 + V22 + V13 #= 15,

  fd_labeling(MS).

/* 出力用の述語 */
pp([V11, V12, V13, V21, V22, V23, V31, V32, V33]) :-
  write(V11), write(' '), write(V12), write(' '), write(V13), nl,
  write(V21), write(' '), write(V22), write(' '), write(V23), nl,
  write(V31), write(' '), write(V32), write(' '), write(V33), nl.

実行

$ gprolog
GNU Prolog 1.4.5 (64 bits)
Compiled Mar 17 2020, 23:55:22 with gcc
By Daniel Diaz
Copyright (C) 1999-2020 Daniel Diaz
| ?- ['ms.pl'].
:
| ?- ms(Ans),pp(Ans).
2 7 6
9 5 1
4 3 8

Ans = [2,7,6,9,5,1,4,3,8] ? ;
2 9 4
7 5 3
6 1 8

Ans = [2,9,4,7,5,3,6,1,8] ? ;
4 3 8
9 5 1
2 7 6

Ans = [4,3,8,9,5,1,2,7,6] ? ;
4 9 2
3 5 7
8 1 6

Ans = [4,9,2,3,5,7,8,1,6] ? ;
6 1 8
7 5 3
2 9 4

Ans = [6,1,8,7,5,3,2,9,4] ? ;
6 7 2
1 5 9
8 3 4

Ans = [6,7,2,1,5,9,8,3,4] ? ;
8 1 6
3 5 7
4 9 2

Ans = [8,1,6,3,5,7,4,9,2] ? ;
8 3 4
1 5 9
6 7 2

Ans = [8,3,4,1,5,9,6,7,2] ? ;

(1 ms) no