/* Upside-down year in Picat. """ An upside-down year is a year which reads the same when the "year number" is turned upside down. That is when the digits which form the year appear the same when rotated 180 degrees. How many upside-down years have been from 0BC until now? When was the latest year that is the same upside down? Which is the next upside-down year? """ This is puzzle #39 from Kordemsky "The Moscow puzzles: 359 mathematical recreations". The upside-down numbers are 0 -> 0 1 -> 1 6 -> 9 8 -> 8 9 -> 6 Solution: Before 2021: [0,1,8,11,69,88,96,101,111,181,609,619,689,808,818,888,906,916,986,1001,1111,1691,1881,1961] len = 24 lastUpsideDownYear = 1961 All 1..4 digit years: [0,1,8,11,69,88,96,101,111,181,609,619,689,808,818,888,906,916,986,1001,1111,1691,1881,1961,6009,6119,6699,6889,6969,8008,8118,8698,8888,8968,9006,9116,9696,9886,9966] len = 39 nextUpsideDownYear = 6009 This model was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ import cp. main => go. go ?=> println("Before 2021:"), All = findall(X,(member(N,1..4),upside_down(N,2021,X))).map(convert), println(All), println(len=All.len), LastUpsideDownYear = All.max, println(lastUpsideDownYear=LastUpsideDownYear), nl, println("All 1..4 digit years:"), All2 = findall(X,(member(N,1..4),upside_down(N,_,X))).map(convert), println(All2), println(len=All2.len), % Find next upside down year append(_,[LastUpsideDownYear,NextUpsideDownYear],_,All2), println(nextUpsideDownYear=NextUpsideDownYear), nl. go => true. % Convert the array representation to a number convert(A) = Num => to_num(A,10,Num). upside_down(N,Limit, X) => UpsideDownNumbers = [0,1,6,8,9], UpsideDownNumbers2 = [0,1,9,8,6], X = new_list(N), X :: UpsideDownNumbers, foreach(I in 1..N) % Identify the pair of numbers element(T,UpsideDownNumbers,X[I]), element(T,UpsideDownNumbers2,X[N-I+1]) end, to_num(X,10,Year), if N > 1 then Year #> 0, X[1] #> 0 end, if nonvar(Limit) then Year #< Limit end, Vars = X ++ [Year], solve(Vars). % % converts a number Num to/from a list of integer List given a base Base % to_num(List, Base, Num) => Len = length(List), Num #= sum([List[I]*Base**(Len-I) : I in 1..Len]).