問題はこちら->http://nabetani.sakura.ne.jp/hena/orde23nokoch/
解法は、基本的には問題の数を変換ルールの逆順に
① 4又は5で割って、余りから傾きを出す
② 前の段階の傾きと合成して新しい傾きを出す
③ 余りが0のときは商それ以外のときは商に1を足して新しい数とし①に戻る
の繰り返しです。
商が0のときの処理をすっきり書けなかったのが残念です。
s1が剰余と傾きの関係、conが傾きの合成のリストです。

sl([4:1:'0',4:2:'+',4:3:'-',5:1:'0',5:2:'+',5:3:'0',5:4:'-']).
con(['0':'0':'0','0':'-':'-','0':'+':'+','-':'0':'-','-':'-':'+',
    '-':'+':'0','+':'0':'+','+':'-':'0','+':'+':'-']).

solv(0,_,S,S):-!.
solv(N,[],S,'x'):-N>0.
solv(N,[H|T],S,SR):-
     X is N div H,Y0 is N mod H,(Y0==0->(X1 is X-1,Y=1);(X1=X,Y=Y0)),
     sl(L),member(H:Y:S1,L),con(L1),member(S:S1:S2,L1),
     (X1==0->N1=0;N1 is X1+1),solv(N1,T,S2,SR) .

solve(N,L,D):-
     solv(N,L,'0',S),(D==S,Str="pass ";Str=" fail "),write(" "),write(Str),writeln(S).

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

pre([]):-!.
pre([_,B,C,D|T]):-
     atom_number(B,N),atom_codes(C,L),atom_chars(D1,D),
     maplist(plus(-93),L,L1),reverse(L1,L2),solve(N,L2,D1),pre(T).

str("0  120,aabb        0
1       100,a   x
2       3,a     -
3       3,b     0
4       9,aa    -
5       10,bb   +
6       11,ab   -
7       12,ba   0
8       7,aaa   0
9       17,baa  +
10      28,bba  -
11      82,bba  +
12      35,baa  -
13      254,babb        +
14      462,abba        x
15      226,bbba        0
16      345,bbba        0
17      256,aaaa        0
18      11,aaab         -
19      241,abaab       -
20      490,aabaa       0
21      1305,bbbaa      0
22      1102,ababa      -
23      1077,abbab      -
24      281,aabaa       -
25      2218,abbaaa     +
26      4095,bbabbb     +
27      2750,abbaab     +
28      5573,bbaaba     +
29      6644,aaabba     x
30      8109,bbbbba     +
31      3860,aaaabbb    +
32      59222,bbbbbba   0
33      14956,baabbab   -
34      14894,ababbba   +
35      3163,aaaaaab    -
36      21917,babaaaa   +
37      178620,aabbbaab         x
38      96709,babbaaaa  0
39      74116,abababaa  -
40      22025,abbbbabb  0
41      8612,aaaabbaa   -
42      153868,bbbabbab         -
43      747769,abbabaaba        x
44      541589,baabbbbab        -
45      787443,ababbbbab        -
46      129549,ababaaaaa        0
47      837323,aabbbabab        x
48      140592,bbbbabbab        +
49      219669,ababbabbab       -
50      500261,bbababaabb       -
51      966503,aaabababbb       0
52      443603,baabaababb       +
53      3912,aabbababaa         0
54      2926358,bbabbbbaba      0
55      18104279,bbbaababbab    -
56      3849980,aaabaaaaaba     0
57      9276072,baabaabaaab     0
58      11202113,baaaaabbbba    0
59      5432578,abaabbaaaaa     -
60      17363025,bbaabababbb    0
61      24147656,baabaabbbbab   0
62      1078733,bbbaaaabbbbb    +
63      38623426,abaabababbaa   -
64      19312285,bbaababbaaba   +
65      11485959,baaaaababaaa   -
66      36831104,babbbbbbabab   +       ").

ちょっと勘違いしていました。
slとsolvはつぎのほうが良いです。

sl([4:0:'0',4:1:'0',4:2:'+',4:3:'-',5:0:'0',5:1:'0',5:2:'+',5:3:'0',5:4:'-']).

solv(0,_,S,S):-!.
solv(N,[],_,'x'):-N>0,!.
solv(N,[H|T],S,SR):-
     X is N div H,Y is N mod H,(Y==0->X1 is X-1;X1=X),
     sl(L),member(H:Y:S1,L),con(L1),member(S:S1:S2,L1),
     (X1==0->N1=0;N1 is X1+1),solv(N1,T,S2,SR) .

2018.4.9追加
剰余が0のときもすっきり書く方法があったはずだと思っていましたが、
mattsanさんのプログラムにありました。(初めの方の文の”商が0のとき”は剰余の間違いです)
->https://gist.github.com/mattsan/25928c25808ef36560f0135173cbe3c6
最初に問題の数から1を引けば、(Y==0->X1 is X-1;X1=X)も(X1==0->N1=0;N1 is X1+1)も
いらないのでした。(slの規則が変わってきますが)
一次元配列と二次元配列の間の変換などに使っていたのにすっかり忘れていました。
最初の勘違いといい年はとりたくないものです。

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.