LoginSignup
0
0

More than 5 years have passed since last update.

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

Last updated at Posted at 2017-09-16

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

prolog
 初めの数だけ普通に計算し桁ごとにリストに入れています。
 あとはリバースして左端に1を足し左から計算しています。
 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に似ていますね。
 こちらは何とか最後の問題まで解けました。

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で、基本的に上位桁半分とそれを逆転した下位桁で
  回文数を作る方法です。
  この方法には気づいていましたが、適当に回文数を作って、
  後から設問の範囲に入っているか確かめることに思い至らず、
  複雑すぎると思っていました。
  変数名を考えるのが面倒で、読みにいですが悪しからず。

%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).

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

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0