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?

CodeIQ:「トライアングル・メイズ」問題の解答

Last updated at Posted at 2025-03-01

Kawazoe(@riverplus)さんのCodeIQの問題です。
問題はこちらの御世話になりました。解答例もあります。
->https://blog.goo.ne.jp/r-de-r/e/22ef7c56ea8f751e2dfb5975bc15337e
こちらにも情報があります。
->https://posfie.com/@riverplus/p/ipsiQ2P

複雑に見えますが、レベルnの図は3つのレベルn-1の図が3点でつながっていて、
其々の中の経路は独立。
レベルnの図の上から終点までの経路をf(n)通りとします。
3つのレベルn-1の図に関して、左上をA、左下をB、右下をCとしますと
Aの上からAの右下(Cの上)に行く道がf(n-1)通り、
Aの右下から終点に行く道がf(n-1)通り、
Aの上からAの左下(Bの上)に行く経路は1通り、
Bの上からBの右下に行く道がf(n-1)通り、
Bの右下(Cの左下)から終点に行く道が1通り。
よってf(n)=f(n-1)*f(n-1)+1*f(n-1)*1=f(n-1)*(f(n-1)+1)
上記では時間がかかりますので、f(2)=f(1)*(f(1)+1),f(3)=f(2)*(f(2)+1)...
というように小さいほうから計算します。

#julia ver 1.41,1.53,1.10.3

function solve(n,a)
  m = 1000003
  ret = 1
  for k in 1 : n-1
      ret = mod(ret*(ret+1),m)
  end
  ret = mod(ret,m)
  s = a == ret ? "ok " : "no "
  println(s,n,"->",ret)
end

solve(1,1)
solve(2,2)
solve(3,6)
solve(4,42)
solve(10,998593)
solve(100,682181)
solve(10000,240663)
solve(19849813,533577)
solve(99999999,454267)
solve(100000000,342482)

このままPrologに移すと時間がかかりすぎですので、剰余の周期性を利用します。
先ずレベル1<=K=Mの範囲でX=F(k) mod Mを計算して辞書(キーはX,データはK)
に登録し、同じキーが出てくるのを探します。
loop/6のK1とK番目が同じ数字で、その後k1からk-1番までの数字をくりかえします。
そこで、(n-(k1-1)) mod (k-k1)が繰り返しの中でのnの順番で、
それに繰り返しの前の(k1-1)を足したものが求める順番(レベル)です。
さらに辞書のデータ(レベル)からキーを求めます。
SWI-prologの辞書はあまり早くありませんが、簡単にデータからキーを探せます。

%SWI-Prolog ver 7.42,7.64,9.25
%:-initialization(start).   %ideone,Online Prolog Compiler
%start.

loop(M,K,D,DR,X,R):-
    (get_dict(X,D,K1)->(DR=D,R=[K1,K,X]);
    (D1=D.put(X,K),X1 is X*(X+1) mod M,K1 is K+1,loop(M,K1,D1,DR,X1,R))).

solve(N,D,[_,K,_],R):-K>N,!,get_dict(R,D,N).
solve(N,D,[K1,K,_],R):-Y is (N-K1+1) mod (K-K1)+ K1-1 ,get_dict(R,D,Y).

start:-
    M=1000003,D=dic{},loop(M,1,D,D1,1,L),f(N,A),
    (solve(N,D1,L,R)->(R==A->Str=" ok  ";Str=" no  ");
    write(fail)),write(" "),write(Str),writeln(N->R),fail.
start.

f(1,1).
f(2,2).
f(3,6).
f(4,42).
f(10,998593).
f(100,682181).
f(10000,240663).
f(19849813,533577).
f(99999999,454267).
f(100000000,342482).


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?