/* Euler #40 in Picat. """ An irrational decimal fraction is created by concatenating the positive integers: 0.123456789101112131415161718192021... It can be seen that the 12th digit of the fractional part is 1. If dn represents the nth digit of the fractional part, find the value of the following expression. d1 × d10 × d100 × d1000 × d10000 × d100000 × d1000000 """ This Picat model was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ import util. main => go. go => time(euler40). % Improved version of euler40d by Neng-Fa: 0.09s euler40 => I = 1, DLen = 1, Prod = 1, Index = 10, % Index = 10, 100, 1000, ..., 1000000 while (DLen <= 1000000) I := I + 1, IStr = I.to_string(), IStrLen = IStr.length, if (DLen+IStrLen>=Index) then Prod := Prod*IStr[Index-DLen].toint(), Index := Index*10 end, DLen := DLen+IStrLen end, println(Prod). % % 0.107s % euler40a => garbage_collect(200_000_000), D=flatten([to_string(I) : I in 1..210000]), Prod = prod([D[10**I].to_integer() : I in 1..6]), println(Prod). % % 0.204s % euler40b => /* % This version is _extremely_ slow D = "", foreach(I in 1..1000000) D := D ++ I.to_integer(), if I mod 10000 == 0 then writeln(i=I), printf("%s\n", [D[J] : J in 1..10]) end end, */ % This is much faster, though still very slow (~8s) % D=to_string(flatten([to_string(I) : I in 1..1000000])), % This is acceptable: ~1.3s garbage_collect(200_000_000), % -> 0.204 D=to_string(flatten([to_string(I) : I in 1..210000])), println(len=D.length), writeln([D[10**I].to_integer() : I in 1..6]), Prod = prod([D[10**I].to_integer() : I in 1..6]), println(Prod). % Very slow euler40c => I = 1, Len = 1, D = "1", while (Len <= 1000000) I := I + 1, S := I.to_string(), D := D ++ S, Len := Len + S.length, if I mod 1000 == 0 then writeln([i=I,len=Len]) end end, println(len=D.length), writeln([D[10**J].to_integer() : J in 1..6]), Prod = prod([D[10**J].to_integer() : J in 1..6]), println(Prod). % Very slow euler40d => I = 1, D = "1", while (D.length <= 1000000) % while (D.length <= 200000) I := I + 1, D := D ++ I.to_string(), if I mod 100 == 0 then % writeln([i=I,len=D.length]) writeln([i=I]) end end, println(len=D.length), writeln([D[10**J].to_integer() : J in 1..6]), Prod = prod([D[10**J].to_integer() : J in 1..6]), println(Prod). % Very slow euler40e => writeln(euler40e), I = 1, D = "", while (int_len(I) <= 1000000) I := I + 1, D := D ++ I.to_string(), if I mod 10000 == 0 then writeln(I) end end, println(len=D.length), writeln([D[10**J].to_integer() : J in 1..6]), Prod = prod([D[10**J].to_integer() : J in 1..6]), println(Prod). int_len(V) = Len => Len = 1, while (V > 9) Len := Len + 1, V := V div 10 end. toint(I) = to_integer(I).