/* Colorful numbers (Rosetta code) in Picat. http://rosettacode.org/wiki/Colorful_numbers """ A colorful number is a non-negative base 10 integer where the product of every sub group of consecutive digits is unique. E.G. 24753 is a colorful number. 2, 4, 7, 5, 3, (2×4)8, (4×7)28, (7×5)35, (5×3)15, (2×4×7)56, (4×7×5)140, (7×5×3)105, (2×4×7×5)280, (4×7×5×3)420, (2×4×7×5×3)840 Every product is unique. 2346 is not a colorful number. 2, 3, 4, 6, (2×3)6, (3×4)12, (4×6)24, (2×3×4)48, (3×4×6)72, (2×3×4×6)144 The product 6 is repeated. Single digit numbers are considered to be colorful. A colorful number larger than 9 cannot contain a repeated digit, the digit 0 or the digit 1. As a consequence, there is a firm upper limit for colorful numbers; no colorful number can have more than 8 digits. Task * Write a routine (subroutine, function, procedure, whatever it may be called in your language) to test if a number is a colorful number or not. * Use that routine to find all of the colorful numbers less than 100. * Use that routine to find the largest possible colorful number. Stretch * Find and display the count of colorful numbers in each order of magnitude. * Find and show the total count of all colorful numbers. Colorful numbers have no real number theory application. They are more a recreational math puzzle than a useful tool. """ This program was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ import util. main => go. go => Colorful = [N : N in 0..100, colorful_number(N)], Len = Colorful.len, foreach({C,I} in zip(Colorful,1..Len)) printf("%2d%s",C, cond(I mod 10 == 0, "\n"," ")) end, nl, println(len=Len), nl. go2 => N = 98765431, Found = false, while (Found == false) if colorful_number(N) then println(N=colorful), Found := true end, N := N - 1 end, nl. go3 => TotalC = 0, foreach(I in 1..8) C = 0, printf("Digits %d: ", I), foreach(N in lb(I)..ub(I)) if colorful_number(N) then C := C + 1 end end, println(C), TotalC := TotalC + C end, println(total=TotalC), nl. % Brute force colorful_number(N) => N < 10 ; (X = N.to_string, X.len <= 8, not membchk('0',X), not membchk('1',X), distinct(X), [prod(S.map(to_int)) : S in findall(S,(append(_,S,_,X),S != [])) ].distinct). distinct(L) => L.len == L.remove_dups.len. % Lower and upper bounds for the full check % For N=3: lb=123 and ub=987 lb(N) = cond(N < 2, 0, [I.to_string : I in 1..N].join('').to_int). ub(N) = [I.to_string : I in 9..-1..9-N+1].join('').to_int.