RosettaCodeData/Task/Hailstone-sequence/Picat/hailstone-sequence-1.picat

57 lines
1.1 KiB
Plaintext

import util.
go =>
println("H27:"),
H27 = hailstoneseq(27),
H27Len = H27.len,
println(len=H27.len),
println(take(H27,4)++['...']++drop(H27,H27Len-4)),
nl,
println("Longest sequence < 100_000:"),
longest_seq(99_999),
nl.
% The Hailstone value of a number
hailstone(N) = N // 2, N mod 2 == 0 => true.
hailstone(N) = 3*N+1, N mod 2 == 1 => true.
% Sequence for a number
hailstoneseq(N) = Seq =>
Seq := [N],
while (N > 1)
N := hailstone(N),
Seq := Seq ++ [N]
end.
%
% Use a map to cache the lengths.
% Here we don't care about the actual sequence.
%
longest_seq(Limit) =>
Lens = new_map(), % caching the lengths
MaxLen = 0,
MaxN = 1,
foreach(N in 1..Limit-1)
M = N,
CLen = 1,
while (M > 1)
if Lens.has_key(M) then
CLen := CLen + Lens.get(M) - 1,
M := 1
else
M := hailstone(M), % call the
CLen := CLen + 1
end
end,
Lens.put(N, CLen),
if CLen > MaxLen then
MaxLen := CLen,
MaxN := N
end
end,
println([maxLen=MaxLen, maxN=MaxN]),
nl.