LoginSignup
1
0

CodeIQ:「ウッド・キーパー」問題の解答

Posted at

Kawazoe(@riverplus)さんのCodeIQの問題です。
問題はこちらのお世話になりました。解答もあります。
->https://sw-logic.com/Portfolio/Programing/CodeIQ/3314.php
こちらに関連の情報があります。
->https://togetter.com/li/1125965
テストケースはあちこちからかき集めたような気がします。

左下から右上に上がる斜線ごとに右端から積み上げます。
ある線上の数<=右隣の線上の数+1となります。
ある状態から①と②の両方を試みる事を繰り返します。
①残りの丸太の数をc、左端の数をnとするとc-nとn+1の小さい方を左に並べる
②左端の丸太を一つ除く
最後に①の場合の数と②の場合の数を足します。
prologでかきました。
functor/3とtwoar/3を使って二次元配列を作りメモ化します。
キーはcとn、値はその時点までの場合の数です。

%:-initialization(start).    %ideone
%start.

twoar(F,0,_).      % 二次元配列、メモ化に使用
twoar(F,X,Y):-arg(X,F,V),functor(V,z,Y),X1 is X-1,twoar(F,X1,Y).
data(F,X,Y,V):-arg(X,F,V1),arg(Y,V1,V). %データの入出力

tum1(0,_,_,1):-!.
tum1(_,0,_,0):-!.
tum1(C,N,F,R):-
    data(F,C,N,R),nonvar(R),!.
tum1(C,N,F,R):-
    C1 is C-N,M is min(C1,N+1),tum1(C1,M,F,R2),N2 is N-1,
    tum1(C,N2,F,R3),R is R2+R3,data(F,C,N,R).

solve(C,B):-
    functor(F,x,C),N1 is integer(sqrt(C*2)),twoar(F,C,N1),
    (tum1(C,1,F,R)->(R=:=B->Str=" ok  ";Str=" no  "); write(fail)),
    write(" "),write(Str),writeln(R),!.   

start:-f(C,B),solve(C,B),fail.

f(1,1).
f(3,2).
f(4,3).
f(5,5).
f(10,78).
f(11,135).
f(60,72875530905117).

1
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
1
0