オフラインリアルタイムどう書くE17の問題を解いてみた(prolog,erlang)

問題->http://nabetani.sakura.ne.jp/hena/orde17palin/


prolog
  　初めの数だけ普通に計算し桁ごとにリストに入れています。
　あとはリバースして左端に1を足し左から計算しています。
　prologはパズルを解くのには楽なのですが、遅いし、
　スタックオーバーになるしで、桁が多くなるとだめでした。

```prolog:kaibunsu.pl
tenton(0,_,L,L):-!.
tenton(X,B,L,RL):-X1 is X div B,R1 is X-(X1*B),
                  tenton(X1,B,[R1|L],RL).
tton(_,[],L,L):-!.
tton(B,[H],L,RL):-H>=B->(H1 is H-B,tton(B,[1],[H1|L],RL));
                 tton(B,[],[H|L],RL).
tton(B,[H1,H2|T],L,RL):-H1>=B->(H11 is H1-B,H21 is H2+1,
                      tton(B,[H21|T],[H11|L],RL))
                     ;(reverse([H1,H2|T],L1),
                     append(L1,L,L3),tton(B,[],L3,RL)).
calc(0,_,_,C):-write(C).
calc(N,B,L,C):-reverse(L,[H|T]),(L==[H|T]->C1 is C+1;C1=C),
               H1 is H+1,N1 is N-1,tton(B,[H1|T],[],
               RL),calc(N1,B,RL,C1).
res(X,Y,B):-tenton(X,B,[],RL),N is Y-X,calc(N,B,RL,0).
```

erlang
　erlangはほんとにprologに似ていますね。
　こちらは何とか最後の問題まで解けました。

```erlang:kaibubsu.erl
-module (kaibunsu).
-export([res/3]).

tenton(0,_,L)->L;
tenton(X,B,L)->X1 = X div B,R1 = X-(X1*B),
               tenton(X1,B,[R1|L]).
tton(_,[],L)->L;
tton(B,[H],L)->if H>=B->H1 = H-B,tton(B,[1],[H1|L]);
               true->tton(B,[],[H|L]) end;
tton(B,[H1|T],L)->if H1>=B -> H11 = H1-B,[H2|T1]=T,
                  H21 = H2+1,tton(B,[H21|T1],[H11|L]);
                  true->L1=lists:reverse([H1|T])
                  ,L3=lists:append(L1,L),tton(B,[],L3) end.
calc(0,_,_,C)->io:write(C);
calc(N,B,L,C)->[H|T]=lists:reverse(L),
              if L==[H|T]->C1 = C+1; true->C1=C end,
              H1 = H+1,N1 = N-1,RL=tton(B,[H1|T],[]),calc(N1,B,RL,C1).
res(X,Y,B)->RL=tenton(X,B,[]),N = Y-X,calc(N,B,RL,0).
```
2017.10.4追加
　　prologで、基本的に上位桁半分とそれを逆転した下位桁で
　　回文数を作る方法です。
　　この方法には気づいていましたが、適当に回文数を作って、
　　後から設問の範囲に入っているか確かめることに思い至らず、
　　複雑すぎると思っていました。
　　変数名を考えるのが面倒で、読みにいですが悪しからず。

```prolog
%kaibunsuu. hanatyoko 17.09.02-10.2   
%  hanbun+/\d?/+reverse(hanbun）
tenton(0,_,L,L):-!.
tenton(X,B,L,RL):-X1 is X div B,R1 is X-(X1*B),
    　　　　　　   tenton(X1,B,[R1|L],RL).
ntoten(_,[],XR,XR):-!.
ntoten(B,[H|T],X,XR):-X1 is X*B+H,ntoten(B,T,X1,XR).

tton(_,[],L,RL):-reverse(L,RL),!.
tton(B,[H],L,RL):-H>=B->(H1 is H-B,tton(B,[1],[H1|L],RL));
                 tton(B,[],[H|L],RL).
tton(B,[H1,H2|T],L,RL):-H1>=B->(H11 is H1-B,H21 is H2+1,
                      tton(B,[H21|T],[H11|L],RL))
                     ;(reverse([H1,H2|T],L1),
                     append(L1,L,L3),tton(B,[],L3,RL)).

sho(_,0,[]):-!.        %hanbun no list
sho([H|T],N,[H|X1]):-N1 is N-1,sho(T,N1,X1).

check11([Y],[X]):-Y=<X,!.
check11([YH|YT],[XH|XT]):-
　　YH<XH->true;(YH>XH->false;check11(YT,XT)).
check1([YH|YT],[XH|XT]):-
　　length(YT,YN),length(XT,XN),
    (YN=XN->check11([YH|YT],[XH|XT]);(YN<XN->true)).

calco(_,B,_,_,_,B,C,C):-!.            %kisuu keta
calco(F,B,RX,RY,RX2,N,C,CR):-
　　RX3=[N|RX2],reverse(RX3,RX4),append(RX4,RX2,RX5),
    (check1(RY,RX5)->(F=1,CR=C);(check1(RX,RX5)->C1 is C+1;C1=C)),
    N1 is N+1,calco(F,B,RX,RY,RX2,N1,C1,CR).

calce(F,B,RX,RY,RX2,C,CR):-
　　reverse(RX2,RX3),append(RX3,RX2,RX4),   %guusuu keta
   (check1(RY,RX4)->(F=1,CR=C);(check1(RX,RX4)->CR is C+1;CR=C)).

solve(F,_,_,_,_,_,C,C):-F==1,!. 
solve(F,B,X,Y,[],1,C,CR):-
　　calco(F,B,X,Y,[],0,C,C1),RX2=[1],solve(F,B,X,Y,RX2,0,C1,CR).
solve(F,B,X,Y,RX2,1,C,CR):-
　　calco(F,B,X,Y,RX2,0,C,C1),RX2=[H|T],H1 is H+1,
    tton(B,[H1|T],[],RX22),length(RX2,N2),length(RX22,N3),
    (N2<N3->solve(F,B,X,Y,RX22,0,C1,CR);solve(F,B,X,Y,RX22,1,C1,CR)).
solve(F0,B,X,Y,[],0,C,CR):-
    calco(F,B,X,Y,[],0,C,C1),RX2=[1],solve(F0,B,X,Y,RX2,0,C1,CR).
solve(F0,B,X,Y,RX2,0,C,CR):-
    calce(F,B,X,Y,RX2,C,C1),RX2=[H|T],H1 is H+1,
    tton(B,[H1|T],[],RX22),
    length(RX2,N2),length(RX22,N3),(N2<N3->(RX22=[_|RX25],
    solve(F,B,X,Y,RX25,1,C1,CR));solve(F,B,X,Y,RX22,0,C1,CR)).

res(X,Y,B):-
    tenton(Y,B,[],RY),tenton(X,B,[],RX),
    length(RX,NX0),NX is NX0 div 2,MX is NX0 mod 2,
    sho(RX,NX,RX1),reverse(RX1,RX2),solve(_,B,RX,RY,RX2,MX,0,C),
    write(C),!.

%res(12,34,5).

```
ところで、ツイートしていただいたらしいのですが
読みに行けないような・・・