0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

どう書く過去問(第24回),CodeIQ(撤去作業の果てに現れる数列),タクシー数関連

Last updated at Posted at 2018-12-22

prolog advent calendar 12/16はタクシー数の記事で無限リストの話が出てきます。
私はそこでちょっと質問したのですが、それは「どう書く」の「多段階選抜」という問題を解いた時、
想定解では遅延評価(無限リスト)を使うようでしたが、
私は無限リストには不案内で普通の解き方で解いていましたので、
その辺の話題に興味があったからです。
ということで今回はその種の問題の解答を投稿します。

多段階選抜
問題はこちら->http://nabetani.sakura.ne.jp/hena/ord24eliseq/
Juliaではwhile ループで自然数の列を作りだし、必要なだけリストに貯めて置いて、コマンドが
 2-9のときは割り切れない数のみ次の段階に送る
 hのときは百個まで除きその後は次の段階に送る
 c,sのときは、ペアの数の中大きいほうが平方数や立方数でないときのみ
 小さいほうを次の段階に送る。
 CやSのときは平方数や立方数が来たら、平方数や立方数でない数が来るまでため込み、
 最小の数のみ次の段階に送る (平方数や立方数は消される場合もその前に一仕事するので)
Juliaにはcbrtという関数もありますが、誤差が小さいときに等しいと判定される可能性がありますので
組み込み関数は使いませんでした。(floorを使えばよいようですが完全かどうかわかりません)

# Julia 0.52,0.6
str="0   ss6cc24S   1,9,21,30,33,37,42,44,49,56
1  h  101,102,103,104,105,106,107,108,109,110
2   hh   201,202,203,204,205,206,207,208,209,210
3 	hhh 	301,302,303,304,305,306,307,308,309,310
4 	2 	1,3,5,7,9,11,13,15,17,19
5 	22 	1,5,9,13,17,21,25,29,33,37
6 	222 	1,9,17,25,33,41,49,57,65,73
7 	3 	1,2,4,5,7,8,10,11,13,14
8 	33 	1,2,5,7,10,11,14,16,19,20
9 	333 	1,2,7,10,14,16,20,23,28,29
10 	s 	1,2,4,5,6,7,9,10,11,12
11 	ss 	1,4,5,6,9,10,11,12,13,16
12 	sss 	4,5,9,10,11,12,16,17,18,19
13 	S 	1,3,4,6,7,8,9,11,12,13
14 	SS 	1,4,7,8,9,12,13,14,15,16
15 	SSS 	1,8,9,13,14,15,16,20,21,22
16 	c 	1,2,3,4,5,6,8,9,10,11
17 	cc 	1,2,3,4,5,8,9,10,11,12
18 	ccc 	1,2,3,4,8,9,10,11,12,13
19 	C 	1,3,4,5,6,7,8,10,11,12
20 	CC 	1,4,5,6,7,8,11,12,13,14
21 	CCC 	1,5,6,7,8,12,13,14,15,16
22 	23 	1,3,7,9,13,15,19,21,25,27
23 	32 	1,4,7,10,13,16,19,22,25,28
24 	2h 	201,203,205,207,209,211,213,215,217,219
25 	h2 	101,103,105,107,109,111,113,115,117,119
26 	sC 	1,4,5,6,7,9,10,11,12,13
27 	Cs 	1,4,5,6,7,8,10,11,12,13
28 	s468 	1,2,4,6,7,11,12,16,17,20
29 	S468 	1,3,4,7,8,12,13,16,18,21
30 	cc579 	1,2,3,4,8,9,11,13,15,16
31 	CC579 	1,4,5,6,8,11,13,15,17,18
32 	85 	1,2,3,4,6,7,9,10,12,13
33 	sh 	110,111,112,113,114,115,116,117,118,119
34 	94h 	150,151,154,155,156,158,159,160,163,164
35 	h9c8 	101,102,103,104,105,106,107,110,111,112
36 	Cc3s 	1,3,5,6,10,11,13,16,17,19
37 	cs4h6 	149,150,152,153,154,157,158,160,161,162
38 	84523c 	1,3,11,15,23,26,34,38,46,49
39 	54C78hS 	228,231,232,233,236,241,242,243,246,247
40 	65h7ccs 	151,152,153,154,157,158,160,163,164,165
41 	c95hSc2C 	145,147,151,153,156,159,162,164,168,171
42 	c5h3Ss794 	130,131,133,137,138,142,148,150,152,157
43 	7ShscC846 	129,130,131,134,135,139,141,142,146,148
44 	cshSCCS7ch 	253,254,256,259,260,261,263,264,265,266
45 	hhC7849Ss6C 	201,202,203,205,206,211,212,216,220,225
46 	hhsc3C987Ccs 	201,202,204,205,207,208,214,217,218,220
47 	SC7S8hc59ss2 	162,169,174,178,182,185,188,194,199,203
48 	s7S6c35C9CShc 	367,371,377,379,380,385,387,388,392,395
49 	4scC3hh982Cc5s 	422,426,430,434,447,451,459,463,471,479
50 	23h465Ssc9CchC 	1027,1033,1045,1047,1057,1069,1071,1075,1081,1093"


function pow(s,x)
    if s=='S' || s=='s'
        return x^2
    else
        return x^3
    end
end

function calc(str)
    n=0
    while true
        n+=1
        push!(st[1],n)
        for (j,s) in enumerate(str)
            if '2'<= s && s<='9'
                t[j]+=1
                if t[j]==parse(Int,s)
                    shift!(st[j])
                    t[j]=0
                    break
                else
                    push!(st[j+1],shift!(st[j]))
                end
            elseif s=='h'
                 if t[j]<100
                    t[j]+=1
                    shift!(st[j])
                    break
                else
                     push!(st[j+1],shift!(st[j]))

                end
            elseif s=='C' || s=='S'
                while pow(s,t[j])<st[j][end]
                t[j]+=1
                end
                if length(st[j])==1                #実は length 関係ない
                    if pow(s,t[j])==st[j][1]
                        break
                    else
                        push!(st[j+1],shift!(st[j]))
                    end
                else
                    if  pow(s,t[j])==st[j][end]
                        break
                    else
                        push!(st[j+1],st[j][1])
                        st[j]=[]
                    end
                end
            elseif s=='c' || s=='s'
                if length(st[j])==2
                    while pow(s,t[j])<st[j][2]
                        t[j]+=1
                    end
                    if pow(s,t[j])==st[j][2]
                        shift!(st[j])
                        break
                    else
                        push!(st[j+1],shift!(st[j]))
                    end
                else
                    break
                end
            end
        end
        if length(st[end])>9
           break
        end
     end
    return st[end]
end

t=Array{Int,1}(20)
str1=split(str,"\n")
res=[]
st=[]
for s in str1
    res=[]
    s=replace(s, r"\t", s" ")
    s1=split(s,r"\s+")
    st=[[]]
    for (i,v) in enumerate(s1[2])
        push!(st,[])
        t[i]=0
    end
    ans1=calc(s1[2])
    ans=join(ans1,",")
    if ans==strip(s1[3])
        sel="pass"
    else
        sel="fail"
    end
    print(sel," ",ans[1:end],"\n")
end

Prologでは、再帰でnを増やし、リストの長さが10を終了条件としている以外同様です。

%swi-Prolog  version 7.4.2
%start.
%:-initialization(start).   % ideone

pow(S,N,M,N,X):-((S=='S';S=='s')->X is N^2;X is N^3),X>=M,!.
pow(S,N,M,R,X):-N1 is N+1,pow(S,N1,M,R,X).

calc1('h',N,[P2,P3],R1,R2):-                    % ikkai no sousa
     !,N<100->(N1 is N+1,R1=N1,R2=[[],P3]);(R1=N,append(P3,P2,P31),R2=[[],P31]).
calc1(S,N,[P2,P3],R1,R2):-
     (S=='C';S=='S'),!,last(P2,M),pow(S,N,M,N1,X),R1=N1,
     (X=:=M->R2=[P2,P3];(P2=[H|_],append(P3,[H],P31),R2=[[],P31])).
calc1(S,N,[P2,P3],R1,R2):-
     (S=='c';S=='s'),!,length(P2,K),(K=\=2->(R1=N,R2=[P2,P3]);
     (last(P2,M),pow(S,N,M,N1,X),R1=N1,P2=[P21|P22],
     (X=:=M->R2=[P22,P3];(append(P3,[P21],P31),R2=[P22,P31])))).
calc1(S,N,[P2,P3],R1,R2):-
     atom_number(S,M),N1 is N+1,(N1=:=M->(R1=0,R2=[[],P3]);
     (R1=N1,append(P3,P2,P31),R2=[[],P31])).

calc([],_,[X],L,R1,L,R):-                     % itijun
     append(R1,[X],R),!.
calc(_,L2,[[]|T2],L0,R0,L,R):-
     append(L0,L2,L),append(R0,[[]|T2],R),!.       %N->V?,P2,P3->progression
calc([H1|T1],[N|T2],[P2,P3|T],L0,R0,L,R):-
     calc1(H1,N,[P2,P3],R1,[R2,R3]),append(L0,[R1],L4),append(R0,[R2],R4),
     calc(T1,T2,[R3|T],L4,R4,L,R).

solve(_,_,_,L,R):-                             % zentai no kurikaesi
     last(L,L1),length(L1,10),R=L1,!.
solve(N,L,NL,[H|T],R):-                                %N->V?
     append(H,[N],H1),calc(L,NL,[H1|T],[],[],NL1,RL1),
     N1 is N+1,solve(N1,L,NL1,RL1,R).

solve(L,R):-                                        %NL->VL?
     length(L,N),length(NL,N),maplist(=(0),NL),
     N1 is N+1,length(RL,N1),maplist(=([]),RL),solve(1,L,NL,RL,R),!.

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

pre([]):-!.
pre([_,B,C|T]):-
     atom_chars(B,L),solve(L,R),atomics_to_string(R,",",S),disp(S,C),pre(T).

disp(R,C):-(R==C->Str=" yes ";Str=" no  "),write(Str),writeln(R).

str("0 ss6cc24S  1,9,21,30,33,37,42,44,49,56
1 h  101,102,103,104,105,106,107,108,109,110
2 hh  201,202,203,204,205,206,207,208,209,210
3 hhh  301,302,303,304,305,306,307,308,309,310
4 2  1,3,5,7,9,11,13,15,17,19
5 22  1,5,9,13,17,21,25,29,33,37
6 222  1,9,17,25,33,41,49,57,65,73
7 3  1,2,4,5,7,8,10,11,13,14
8 33  1,2,5,7,10,11,14,16,19,20
9 333  1,2,7,10,14,16,20,23,28,29
10 s  1,2,4,5,6,7,9,10,11,12
11 ss  1,4,5,6,9,10,11,12,13,16
12 sss  4,5,9,10,11,12,16,17,18,19
13 S  1,3,4,6,7,8,9,11,12,13
14 SS  1,4,7,8,9,12,13,14,15,16
15 SSS  1,8,9,13,14,15,16,20,21,22
16 c  1,2,3,4,5,6,8,9,10,11
17 cc  1,2,3,4,5,8,9,10,11,12
18 ccc  1,2,3,4,8,9,10,11,12,13
19 C  1,3,4,5,6,7,8,10,11,12
20 CC  1,4,5,6,7,8,11,12,13,14
21 CCC  1,5,6,7,8,12,13,14,15,16
22 23  1,3,7,9,13,15,19,21,25,27
23 32  1,4,7,10,13,16,19,22,25,28
24 2h  201,203,205,207,209,211,213,215,217,219
25 h2  101,103,105,107,109,111,113,115,117,119
26 sC  1,4,5,6,7,9,10,11,12,13
27 Cs  1,4,5,6,7,8,10,11,12,13
28 s468  1,2,4,6,7,11,12,16,17,20
29 S468  1,3,4,7,8,12,13,16,18,21
30 cc579  1,2,3,4,8,9,11,13,15,16
31 CC579  1,4,5,6,8,11,13,15,17,18
32 85  1,2,3,4,6,7,9,10,12,13
33 sh  110,111,112,113,114,115,116,117,118,119
34 94h  150,151,154,155,156,158,159,160,163,164
35 h9c8  101,102,103,104,105,106,107,110,111,112
36 Cc3s  1,3,5,6,10,11,13,16,17,19
37 cs4h6  149,150,152,153,154,157,158,160,161,162
38 84523c  1,3,11,15,23,26,34,38,46,49
39 54C78hS  228,231,232,233,236,241,242,243,246,247
40 65h7ccs  151,152,153,154,157,158,160,163,164,165
41 c95hSc2C  145,147,151,153,156,159,162,164,168,171
42 c5h3Ss794  130,131,133,137,138,142,148,150,152,157
43 7ShscC846  129,130,131,134,135,139,141,142,146,148
44 cshSCCS7ch  253,254,256,259,260,261,263,264,265,266
45 hhC7849Ss6C  201,202,203,205,206,211,212,216,220,225
46 hhsc3C987Ccs  201,202,204,205,207,208,214,217,218,220
47 SC7S8hc59ss2  162,169,174,178,182,185,188,194,199,203
48 s7S6c35C9CShc  367,371,377,379,380,385,387,388,392,395
49 4scC3hh982Cc5s  422,426,430,434,447,451,459,463,471,479
50 23h465Ssc9CchC  1027,1033,1045,1047,1057,1069,1071,1075,1081,1093").

 
撤去作業の果てに現れる数列
http://nabetani.hatenablog.com/
https://sw-logic.com/Portfolio/Programing/CodeIQ/3011.php 問題と解答例
前問の作者が、CodeIQに出題されことについて書かれていましたので、読んでいましたら、
上記の問題とよく似た問題がありましたので解いてみました。
COdeIQの問題は、過去問を解いてもテストケースが少なくて自信がないのですが、
この問題は基本的には前問と同じですの大丈夫でしょう。
(どう書くの作者の方が、毎回多くのテストケースを作ってくださるのは有り難いです。)
 素数のn個前の数を除去するには、連続するn+1個の数をリストに貯めて、
 最後の数が素数なら最初の数を捨てて、次の段階にはなにも送らない。
 最後の数が素数でなければ最初の数を次の段階に移す。
 リストの要素がn+1より少なければ、何もせず次の段階に進む。
 最後の段階で集まった数が10未満ならx->x+1にして最初に戻る。

pri(2):-!.
pri(X):-not(syn(X)).
syn(X):-floor(sqrt(X),Y),between(2,Y,N),X mod N =:=0,!.

calc1(N,[P2,P3],R2):-
     length(P2,K),(K=\=N->(R2=[P2,P3]);
     (P2=[H|T],last(P2,M),(pri(M)->R2=[T,P3];(append(P3,[H],P31),R2=[T,P31])))).

calc([],[X],R1,R):-                     % itijun
     append(R1,[X],R),!.
calc(_,[[]|T2],R0,R):-
     append(R0,[[]|T2],R),!.       %P2,P3->progression
calc([H1|T1],[P2,P3|T],R0,R):-
     calc1(H1,[P2,P3],[R2,R3]),append(R0,[R2],R4),
     calc(T1,[R3|T],R4,R).

solve(_,_,L,R):-                             % zentai no kurikaesi
     last(L,L1),length(L1,10),R=L1,!.
solve(N,L,[H|T],R):-
     append(H,[N],H1),calc(L,[H1|T],[],RL1),
     N1 is N+1,solve(N1,L,RL1,R).

solve(L,R):-
     length(L,N),N1 is N+1,length(RL,N1),maplist(=([]),RL),
     maplist(plus(1),L,L1),solve(0,L1,RL,R),!.
     
start:-case(L,A),solve(L,R),disp(R,A),fail.
start.

disp(R,C):-(R==C->Str=" yes ";Str=" no  "),write(Str),writeln(R).

case([3,2,3],[3,6,9,15,19,22,23,27,30,31]).
case([2,3],[4,6,7,10,12,13,16,18,20,22]).

タクシー数
タクシー数とは、二つの正の三乗数の和として二通りに書ける最小の自然数ですが、
今回はタクシー数とその同型(「同型」と表示)を探します。
nを増やしつつnが「同型」の数かどうか調べるコードは、
advent calendar の導入部だけ読んで急遽考えました。
x=n div 2を求め、x以下の数の三乗根とxより大きくn以下の数の三乗根の組み合わせから、
各々の要素の三乗根の和がnになる二組があるか調べます。

%solve(4,R),write(R).
%:-initialization(main).

lim(N,R):-between(1,N,X),X^3>N,!,R is X-1.

taxi(N,R):-
     N1 is N div 2,lim(N1,LN),lim(N,HN),N4 is LN+1,findall(X:Y,(between(1,LN,X),
     between(N4,HN,Y),X^3+Y^3=:=N),R),length(R,M),M>=2,!.

solve(_,N,L,R):-length(L,N),reverse(L,R),!.
solve(M,N,L,R):-(taxi(M,L1)->L2=[L1|L];L2=L),M1 is M+1,solve(M1,N,L2,R).
solve(N,R):-solve(4,N,[],R).

main:-solve(4,R),write(R).

advent calendarの記事
https://qiita.com/sym_num/items/e618d36f482d0226b5db
を読み、また
https://math-jp.net/2017/03/26/taxi-number-2/
でエクセルで多くの「同型」を求めているのを見て、
上記のコード得られるのは妥当な時間内にせいぜい数個、一応メモ化でしたコードでも倍くらいでしたので、
4数から「同型」を求めるコードを書いてみる気になりました。
エレガントとはかけ離れていますが、
between(1,?,X),between(1,X-1,Y)のような感じで表の対角線より上を求め、表を大きくしていきます。
X,Yの三乗とその和を一組にしてリストに入れるとともに、そのリストに同じ和の組があれば、
その2組が求めるものです。
taxi/6の中にwritelnがあるのは、私の環境でデータが多いとき一括して表示できなかったからです。

%solve(100,N).
%:-initialization(main). 

taxi(M,M,L,R,L,R).
taxi(M,N,L,R,FL,FR):-
     V is M^3+N^3,E=N:M:V,(member(X:Y:V,L)->
     (writeln([N^3+M^3:X^3+Y^3=V]),R1=[[N,M,X,Y,V]|R]);R1=R),
     L1=[E|L],N1 is N+1,taxi(M,N1,L1,R1,FL,FR).

solve(X,R):-solve(X,1,[],[],L),reverse(L,R),!.          %N ko mituikeru
solve(X,_,_,R,R):-length(R,X).
solve(X,M,L,R,FR):-taxi(M,1,L,R,L1,R1),M1 is M+1,solve(X,M1,L1,R1,FR).

main:-solve(100,R).

2019.2.24追加
オフラインリアルタイムどう書くE30の問題をerlangのプロセス間通信を使って解いてみたら、
https://qiita.com/smallbigcats/items/f78fca99796cf160ef39
速さもまあまあで面白かったので、「多段階選抜」と「撤去作業の果てに現れる数列」
にも応用してみました。
多段階選抜
solve/2から各段の操作の情報を持たせてプロセスcalc/2を作ると、
calcが逐次的に下の段の情報を持った子のプロセス(calc)を作ります。
最後に情報を持たないプロセスができたら、
数字を求めるメッセージ(req)を親のプロセスに送ります。
親のプロセスは、reqが来たらその親にreqを送ります。
親から{data,N}が送られてきたら、calc1/5で子に渡す数字があるか調べ、
あればPid! {data,N}で子に送り、なければ親にreqを送ります。
これを繰り返します。
最下段のプロセスは、数字が10個になったら親に{ans,Nl}を送ります。
他のプロセスは{ans,Nl}メッセージが来たら、親に同じメッセージを送ります。
solveのループではreqが来たら次の数字を送り、
{ans,Nl}が来たら、Nlを戻り値とします。
その数値をsolve内で答え合わせして終わりです。
コードを短くするために、C,c,S,sをまとめましたので、
0の代わりに二乗でも三乗でも元の数字と同じにならない数字として-2を使っています。

%Erlang/OTP 21,Eshell V10.1 
% erl -> c(n24). ->n24:start().
-module(n24).
-export([calc/2,calc1/5,loop1/2,loop/2,solve/2,pow/3,str/0,start/0]).

pow(S,N,M)->
  if
    S =:=83 ; S =:=115->X = N*N;
    true->X = N*N*N
  end,
  if
    X>=M->{N,X};
    true->N1 = N+1,pow(S,N1,M)
  end.

calc1($h,Tn,On,Pid,Up)->
  receive
   {data,N}->
      if
        Tn<100->Tn1 = Tn+1,Up! req,calc1($h,Tn1,On,Pid,Up);
        true->Pid! {data,N},calc1($h,Tn,On,Pid,Up)
      end;
    req->
      Up! req,calc1($h,Tn,On,Pid,Up);
    {ans,Nl}->
       Up! {ans,Nl}
   end;
calc1(S,Tn,On,Pid,Up) when S=:=99;S=:=115;S=:=67;S=:=83->
  receive
    {data,N}->
      if
        On==-2,S=/=67,S=/=83->Up! req,calc1(S,Tn,N,Pid,Up);
        true->
           if
             S=:=99;S=:=115->Y=N,Z=On,{Tn1,X}=pow(S,Tn,Y);
             S=:=67;S=:=83->Y=On,Z=N,{Tn1,X}=pow(S,Tn,Y)
           end,
           if
             X=:=Y->Up! req,calc1(S,Tn1,N,Pid,Up);
             true->Pid! {data,Z},calc1(S,Tn1,N,Pid,Up)
           end
      end;
    req->
      Up! req,calc1(S,Tn,On,Pid,Up);
    {ans,Nl}->
      Up! {ans,Nl}
  end;
calc1(S,Tn,On,Pid,Up)->
  receive
    {data,N}->
      Tn1 = Tn+1,
      if
        Tn1==S-48->Up! req,calc1(S,0,On,Pid,Up);
        true->Pid! {data,N},calc1(S,Tn1,On,Pid,Up)
      end;
    req->
      Up! req,calc1(S,Tn,On,Pid,Up);
    {ans,Nl}->
      Up! {ans,Nl}
  end.

loop(Nl,Up)->
  Up! req,
  receive
     {data,N}->
        Nl1=Nl++[N],Ln=length(Nl1),
        if
          Ln<10->loop(Nl1,Up);
          true->Nl1
        end
  end.

calc([],Up)->
  Nl=loop([],Up),Up! {ans,Nl};
calc([S|T],Up)->
  Pid=spawn(n24,calc,[T,self()]),calc1(S,0,-2,Pid,Up).

loop1(N,Pid)->
  receive
    req->
       Pid! {data,N},N1 = N+1,loop1(N1,Pid);
    {ans,Nl}->Nl
  end.


solve(L,A)->
  Pid=spawn(n24,calc,[L,self()]),Nl=loop1(1,Pid),
  Sl=string:join(lists:map(fun(X)->integer_to_list(X) end,Nl),","),
  if
     Sl==A->Str="pass  ";
     true->Str="fail  "
  end,
  io:fwrite("~s~s~n",[Str,Sl]).

start()->
  S=str(),Str=string:tokens(S,"\n"),pre(Str).

pre([])-> ok;
pre([H|T])->
  [_,LS,AS]=string:tokens(H," \t"),
  solve(LS,AS),
  pre(T).

str()->
"0 	ss6cc24S 	1,9,21,30,33,37,42,44,49,56
1 	h 	101,102,103,104,105,106,107,108,109,110
2 	hh 	201,202,203,204,205,206,207,208,209,210
3 	hhh 	301,302,303,304,305,306,307,308,309,310
4 	2 	1,3,5,7,9,11,13,15,17,19
5 	22 	1,5,9,13,17,21,25,29,33,37
6 	222 	1,9,17,25,33,41,49,57,65,73
7 	3 	1,2,4,5,7,8,10,11,13,14
8 	33 	1,2,5,7,10,11,14,16,19,20
9 	333 	1,2,7,10,14,16,20,23,28,29
10 	s 	1,2,4,5,6,7,9,10,11,12
11 	ss 	1,4,5,6,9,10,11,12,13,16
12 	sss 	4,5,9,10,11,12,16,17,18,19
13 	S 	1,3,4,6,7,8,9,11,12,13
14 	SS 	1,4,7,8,9,12,13,14,15,16
15 	SSS 	1,8,9,13,14,15,16,20,21,22
16 	c 	1,2,3,4,5,6,8,9,10,11
17 	cc 	1,2,3,4,5,8,9,10,11,12
18 	ccc 	1,2,3,4,8,9,10,11,12,13
19 	C 	1,3,4,5,6,7,8,10,11,12
20 	CC 	1,4,5,6,7,8,11,12,13,14
21 	CCC 	1,5,6,7,8,12,13,14,15,16
22 	23 	1,3,7,9,13,15,19,21,25,27
23 	32 	1,4,7,10,13,16,19,22,25,28
24 	2h 	201,203,205,207,209,211,213,215,217,219
25 	h2 	101,103,105,107,109,111,113,115,117,119
26 	sC 	1,4,5,6,7,9,10,11,12,13
27 	Cs 	1,4,5,6,7,8,10,11,12,13
28 	s468 	1,2,4,6,7,11,12,16,17,20
29 	S468 	1,3,4,7,8,12,13,16,18,21
30 	cc579 	1,2,3,4,8,9,11,13,15,16
31 	CC579 	1,4,5,6,8,11,13,15,17,18
32 	85 	1,2,3,4,6,7,9,10,12,13
33 	sh 	110,111,112,113,114,115,116,117,118,119
34 	94h 	150,151,154,155,156,158,159,160,163,164
35 	h9c8 	101,102,103,104,105,106,107,110,111,112
36 	Cc3s 	1,3,5,6,10,11,13,16,17,19
37 	cs4h6 	149,150,152,153,154,157,158,160,161,162
38 	84523c 	1,3,11,15,23,26,34,38,46,49
39 	54C78hS 	228,231,232,233,236,241,242,243,246,247
40 	65h7ccs 	151,152,153,154,157,158,160,163,164,165
41 	c95hSc2C 	145,147,151,153,156,159,162,164,168,171
42 	c5h3Ss794 	130,131,133,137,138,142,148,150,152,157
43 	7ShscC846 	129,130,131,134,135,139,141,142,146,148
44 	cshSCCS7ch 	253,254,256,259,260,261,263,264,265,266
45 	hhC7849Ss6C 	201,202,203,205,206,211,212,216,220,225
46 	hhsc3C987Ccs 	201,202,204,205,207,208,214,217,218,220
47 	SC7S8hc59ss2 	162,169,174,178,182,185,188,194,199,203
48 	s7S6c35C9CShc 	367,371,377,379,380,385,387,388,392,395
49 	4scC3hh982Cc5s 	422,426,430,434,447,451,459,463,471,479
50 	23h465Ssc9CchC 	1027,1033,1045,1047,1057,1069,1071,1075,1081,1093".

撤去作業の果てに現れる数列
http://nabetani.hatenablog.com/entry/2018/10/03/221322
https://blog.goo.ne.jp/r-de-/a4cf8c21b28069ac8cb7cd0002e4576a?fm=entry_awc
テストケースは上記より拝借しました。
(先に投稿したprologのプログラムも改めて検証してみましたがすべてpassしました。)

%Erlang/OTP 21,Eshell V10.1 
% erl -> c(c50). ->c50:start().

-module(c50).
-export([pri/1,pri/2,f/2,start/0,take/2,loop2/4,loop1/2,loop/2]).

pri(X) when X<2->false;
pri(2)->true;
pri(X)->Y=trunc(math:floor(math:sqrt(X+1))),pri(Y,X).
pri(1,_)->true;
pri(Y,X)->
  if
    X rem Y =/=0->pri(Y-1,X);
    true->false
  end.

take([],Up)->
  Nl=loop([],Up),Up! {ans,Nl};
take([S|T],Up)->
  Pid=spawn(c50,take,[T,self()]), % Pid iranai?
  loop2(S,[],Pid,Up).

loop(Nl,Up)->
  Up! req,
  receive
     {data,N}->
        Nl1=Nl++[N],Ln=length(Nl1),
        if
          Ln<10->loop(Nl1,Up);
          true->Nl1
        end
  end.

loop2(S,Dl,Pid,Up)->
  receive
    {ans,Nl}->
       Up! {ans,Nl};
    {data,X}->
       if
         length(Dl)<S->Dl1=Dl++[X],Up! req,loop2(S,Dl1,Pid,Up);
         true->[H|T]=Dl,Dl1=T++[X],
           case pri(X) of
             true->Up! req;
             false->Pid! {data,H}
           end,
         loop2(S,Dl1,Pid,Up)
       end;
    req->
       Up! req,loop2(S,Dl,Pid,Up)
  end.

loop1(Fr,Pid)->
  receive
    req->
       Pid! {data,Fr},
       Fr1 = Fr+1,
       loop1(Fr1,Pid);
    {ans,Nl}->
    Nl
  end.

f(L,A)->
  Pid=spawn(c50,take,[L,self()]),
  Nl=loop1(0,Pid),
  if
    Nl==A->Str="pass  ";
    true->Str="fail  "
  end,
  io:format("~s~p~n",[Str,Nl]).

start()->
f([3,2,3],[3,6,9,15,19,22,23,27,30,31]),
f([2,3],[4,6,7,10,12,13,16,18,20,22]),
f([1,4,2,2,2,4,2,1,3,3,1,1,2,2,2,1,3,4,3,2],[0,1260,1327,1328,1329,1330,1331,1332,1333,1339]),
f([3,3,6,4,3,2,3,1,1,2,2,3,6,5,4,3,3,3,4,3],[1,1307,1313,1327,1328,1329,1330,1331,1332,1333]),
f([2,1,1,2,1,2,2,3,2,1,2,2,1,1,1,2,1,1,2,2],[2,1129,1130,1131,1134,1327,1328,1329,1330,1331]),
f([1,3,2,1,1,2,5,4,3,5,4,4,4,3,2,2,2,5,3,3],[3,61,1123,1328,1330,1916,2287,2470,2477,2480]),
f([1,4,2,1,1,3,2,1,3,4,1,1,3,1,4,2,2,2,4,2],[892,1262,1327,1332,1381,2447,2477,2478,2971,3023]),
f([5,2,2,1,3,4,2,4,4,1,5,2,5,2,2,5,5,3,4,1],[1669,2166,2557,2971,2973,3271,3739,3745,3787,3953]),
f([5,2,2,1,1,4,2,4,6,5,7,7,3,2,3,2,4,2,1,3],[513,1327,1329,1381,1382,1385,1631,1675,2171,3271]),
f([1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],[1129,1130,1327,1328,1329,1330,1331,1332,1333,1334]),
f([1,100,1,100,1,100,1,100,1,100,1,100,1,100,1,100,1,100,1,100],[169,200,204,209,214,354,356,701,702,763]),
f([100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100],[2,28,41,94,145,166,167,184,187,209]),
f([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20],[327,480,711,993,1263,1382,1735,2477,2499,3313]),
f([20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1],[85,224,271,272,274,275,292,294,295,296]).
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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?