オフラインリアルタイムどう書くE20 の問題

問題はこちら->http://nabetani.sakura.ne.jp/hena/orde20maze/

今回も配列を使い地道に解きました。
配列は、prologより他の言語のほうが使いやすいので、まずnimから。
升目を一つおきに、その間に、壁のある所は'x'を、ないところは空白を配置しました。
壁のパターンがわかりませんでしたので、全部手入力にしました。

```nim

import os

type
  List0=array[2,int]
  List=seq[List0]

const
  field=[['x','x','x','x','x','x','x','x','x','x','x','x','x'],
       ['x','0',' ','1','x','2',' ','3',' ','4',' ','5','x'],
       ['x',' ',' ',' ',' ','x',' ',' ',' ','x',' ',' ','x'],
       ['x','6','x','7',' ','8',' ','9',' ','A','x','B','x'],
       ['x',' ',' ','x',' ','x',' ',' ',' ','x',' ','x','x'],
       ['x','C',' ','D','x','E','x','F',' ','G','x','H','x'],
       ['x',' ',' ','x',' ',' ',' ','x',' ',' ',' ',' ','x'],
       ['x','I','x','J',' ','K',' ','L',' ','M','x','N','x'],
       ['x',' ',' ',' ',' ','x',' ','x',' ',' ',' ',' ','x'],
       ['x','O','x','P',' ','Q',' ','R','x','S',' ','T','x'],
       ['x','x',' ',' ',' ','x',' ',' ',' ',' ',' ','x','x'],
       ['x','U',' ','V',' ','W','x','X','x','Y',' ','Z','x'],
       ['x','x','x','x','x','x','x','x','x','x','x','x','x']]

  str0=["DE","EK","01","LG","A1","GJ","FK","LV","27","0O","G1","ZH","AB","KX","1G","WX",
        "3L","9Y","EX","BG","7K","E3","SW","BM","3C","H9","J3","GX","2Z","8H","Z7","0B","U9",
        "Z0","0N","U8","XZ","H0","CH","WB","0R","DZ","NI","QC","6U","PO","RI","UO","WO","OX"]

  cal=[[-1,0,-2,0],[1,0,2,0],[0,-1,0,-2],[0,1,0,2]]

proc noin(xy:List0,pass:List):bool=
  for data in pass:
    if data==xy:
      return false
  return true

proc solve(n:int,list,pass:List,to:char):int=
    var n1=n+1
    var
      list1:List
      pass1=pass
    list1= @[]
    for data in list:                         #kouho
      var x =data[0]
      var y =data[1]
      for cel in cal:                         #4 houkou
         if field[cel[0]+x][cel[1]+y] != 'x': #kabe ga nakereba
             var x1=cel[2]+x                  #mou hitotu susumu
             var y1=cel[3]+y
             if field[x1][y1] == to:
                return n1
             else:
                if noin([x1,y1],pass1):      #tuuka reki
                   list1.add([x1,y1])
                   pass1.add([x1,y1])
    if list1!= @[]:
       return solve(n1,list1,pass1,to)

proc solve0()=
  var
    fr:int
    to:char
    code:int
    pass:List
    list:List
  for data in str0:
      #n=0
      pass= @[]
      code=ord(data[0])
      if code<60:
        fr=code-48
      else:
        fr=code-55
      var y=(fr mod 6)*2+1
      var x=(fr div 6)*2+1
      list= @[]
      list.add([x,y])
      to=data[1]
      var n=solve(0,list,pass,to)
      echo(n)

solve0()
```
prologでもfunctorを使って二次元配列を定義して解いてみました。

```prolog

field([['x','x','x','x','x','x','x','x','x','x','x','x','x'],
       ['x','0',' ','1','x','2',' ','3',' ','4',' ','5','x'],
       ['x',' ',' ',' ',' ','x',' ',' ',' ','x',' ',' ','x'],
       ['x','6','x','7',' ','8',' ','9',' ','A','x','B','x'],
       ['x',' ',' ','x',' ','x',' ',' ',' ','x',' ','x','x'],
       ['x','C',' ','D','x','E','x','F',' ','G','x','H','x'],
       ['x',' ',' ','x',' ',' ',' ','x',' ',' ',' ',' ','x'],
       ['x','I','x','J',' ','K',' ','L',' ','M','x','N','x'],
       ['x',' ',' ',' ',' ','x',' ','x',' ',' ',' ',' ','x'],
       ['x','O','x','P',' ','Q',' ','R','x','S',' ','T','x'],
       ['x','x',' ',' ',' ','x',' ',' ',' ',' ',' ','x','x'],
       ['x','U',' ','V',' ','W','x','X','x','Y',' ','Z','x'],
       ['x','x','x','x','x','x','x','x','x','x','x','x','x']]).

cal([[1,0,2,0],[-1,0,-2,0],[0,1,0,2],[0,-1,0,-2]]).

ar(F):-functor(F,x,13),twoar(F,13,13),field(L),maked(13,0,L,F).  %list->array

twoar(F,0,_).                                           % two dimension array
twoar(F,X,Y):-arg(X,F,V),functor(V,y,Y),X1 is X-1,twoar(F,X1,Y).

data(F,X,Y,V):-arg(X,F,V1),arg(Y,V1,V).                 %ar[X,Y]

maked(N0,N0,_,F).                                       %list data-> array data
maked(N0,N,L,F):-nth0(N,L,V),plus(N,1,N1),arg(N1,F,V1),maked1(N0,0,V,V1),maked(N0,N1,L,F).
maked1(N0,N0,_,F).
maked1(N0,N,L,F):-nth0(N,L,V),plus(N,1,N1),arg(N1,F,V),maked1(N0,N1,L,F).

choice([],P0,P0,_,_,[]).                                %kouho P0->tuka rireki
choice([H|T],P0,P,CL,F,L):-choice(T,P0,P1,CL,F,L1),check1(H,P1,P,CL,F,L2),append(L1,L2,L).
check1(_,P0,P0,[],_,[]).
check1([X,Y],P0,P,[[DX,DY,DX1,DY1]|T],F,L):-
      check1([X,Y],P0,P1,T,F,L1),plus(X,DX,X1),plus(Y,DY,Y1),plus(X,DX1,X2),plus(Y,DY1,Y2),
      ((not(data(F,X1,Y1,'x')),subtract(P1,[[X2,Y2]],P1))->
      (append(L1,[[X2,Y2]],L),append(P1,[[X2,Y2]],P));(P=P1,L=L1)).

check2([],_,_):-!,fail.
check2([[X,Y]|T],F,B):-data(F,X,Y,V),(V==B->true;check2(T,F,B)).

start:-str(S),split_string(S,"\n,\s","\s",L0),pre(L0).

solve(_,[],_,_,_,_).
solve(N,L,P,F,B,Q):-
      cal(CL),choice(L,P,P1,CL,F,L1),(check2(L1,F,B)->disp(N,Q);
      (plus(N,1,N1),solve(N1,L1,P1,F,B,Q))).

disp(N,Q):-atom_number(Q,NQ),(N==NQ->Str=" yes ";Str=" no  "),write(Str),write(N),write("\n").

pre([]).
pre([_,P,Q|T]):-
      atom_chars(P,[A,B]),string_codes(A,[NA]),(NA<60->FR is NA-48;FR is NA-55),
      Y is (FR mod 6)*2+2,X is (FR div 6)*2+2,ar(F),solve(1,[[X,Y]],[],F,B,Q),pre(T).

str("0       DE      13
1       EK      1
2       01      1
3       LG      2
4       A1      4
5       GJ      4
6       FK      4
7       LV      4
8       27      4
9       0O      4
10      G1      5
11      ZH      5
12      AB      5
13      KX      5
14      1G      5
15      WX      5
16      3L      5
17      9Y      5
18      EX      6
19      BG      6
20      7K      7
21      E3      7
22      SW      7
23      BM      7
24      3C      7
25      H9      7
26      J3      7
27      GX      8
28      2Z      8
29      8H      8
30      Z7      8
31      0B      8
32      U9      9
33      Z0      10
34      0N      10
35      U8      10
36      XZ      10
37      H0      11
38      CH      13
39      WB      13
40      0R      13
41      DZ      13
42      NI      13
43      QC      14
44      6U      14
45      PO      15
46      RI      16
47      UO      17
48      WO      17
49      OX      18").

```