Kawazoe(@riverplus)さんのCodeIQの問題です。
問題はこちらのお世話になりました。解答もあります。
https://sw-logic.com/Portfolio/Programing/CodeIQ/2812.php
こちらにも情報があります。テストケースのデータもこちらのお世話になったようです。
https://posfie.com/@riverplus/p/blrCaku
両端が外に広がりますので、4*2^k-1秒後の赤と赤の間のマス目の数は2*4*2^k-1。
またマス目が赤と白交互になると次は外側にできた2個のみ残り、
2個と2個の間では、部分ごとの赤が前の変化を繰り返します。
4*2^0-1=3秒後の赤の数は4=4*2^0。
4*2^k-1秒後の赤の数が4*2^kと仮定すると、白の数が4*2^k-1となって
赤白交互になりますので、4*2^k秒後の赤の数は両端の2。
その後はそれぞれの赤は0秒から4*2^k-1秒の状態を繰り返しますので。4*2^k+4*2^k-1=2*4*2^k-1秒後の赤の数は2*4*2^k。すると白の数は2*2*4*2^k-1-2*4*2^k=2*4*2^k-1
となり赤と白が交互になりますので、2*4*2^k秒後の赤の数は2個
そこでn=n-max(4*2^k<n)としn<4となるまでnに同じ操作をして2をかけます。
(実際には計算しやすいよう最初にn=n0+1としています)
#julia ver 1.41,1.53,1.10.5
function solve(n0,a)
function f(n)
if n < 5
if n == 3 return 2
else return n
end
end
n1 = n-4*2^BigInt(trunc(log2(div(n,4))))
if n1 == 0
return n
else
return f(n1)*2
end
end
x = f(n0+1)
s = a == x ? "ok " : "no "
println(s,x)
end
solve(1 ,2)
solve(2 ,2)
solve(3 ,4)
solve(4 ,2)
solve(10 ,4)
solve(31 ,32)
solve(1023 ,1024)
solve(12345 ,64)
solve(999 ,256)
solve(67108863 ,67108864)
solve(67108864 ,2)
solve(67108865 ,4)
solve(100000000 ,4096)
solve(98765432 ,8192)
solve(31901471898837980949691369446728269823 ,21267647932558653966460912964485513216)
Prologも同じ解き方です。
%SWI-Prolog ver 7.42,7.64,9.29
%:-initialization(start). %ideone,Online Prolog Compiler
%start.
fn(N,R):-N<5,!,(N=:=3->R=2;R=N).
fn(N,R):-
X is N div 4,N1 is N-4*2^(floor(log(X)/log(2))),
(N1=:=0->R=N;(fn(N1,R1),R is 2*R1)).
solve(N,R):-N1 is N+1,fn(N1,R).
start:-f(N,A),(solve(N,R)->(R==A->Str=" ok ";Str=" no ");
write(fail)),write(" "),write(Str),writeln(N->R),fail.
start.
f(1 ,2).
f(2 ,2).
f(3 ,4).
f(4 ,2).
f(10 ,4).
f(31 ,32).
f(1023 ,1024).
f(12345 ,64).
f(999 ,256).
f(67108863 ,67108864).
f(67108864 ,2).
f(67108865 ,4).
f(100000000 ,4096).
f(98765432 ,8192).
f(31901471898837980949691369446728269823 ,21267647932558653966460912964485513216).