/* FizzBuzz in Picat. http://rosettacode.org/wiki/FizzBuzz """ Write a program that prints the numbers from 1 to 100. But for multiples of three print "Fizz" instead of the number and for the multiples of five print "Buzz". For numbers which are multiples of both three and five print "FizzBuzz". """ Model created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ import util. import cp. import planner. main => go. go => fizzbuzz(100, fb1), fizzbuzz(100, fb2), fizzbuzz(100, fb3), fizzbuzz4(100), fizzbuzz(100, fb5), fizzbuzz6(100), fizzbuzz7(100), fizzbuzz7b(100), fizzbuzz8(100), fizzbuzz9(100), fizzbuzz9b(100), fizzbuzz10(100), fizzbuzz11(100), nl. go2 => foreach(I in 1..100) FB = fb2(I), printf("%w,%w\n",I,FB) end, nl. fizzbuzz(N, Goal) => printf("Testing %w\n", $Goal), foreach(I in 1..N) printf("%w ", apply(Goal,I)) end, nl. % using a map fizzbuzz4(N) => println("fizzbuzz4"), FB = [I : I in 1..N], Map = [(3="Fizz"),(5="Buzz"),(15="FizzBuzz")], foreach(I in FB,K=V in Map) if I mod K == 0 then FB[I] := V end end, println(FB). % another approach: use a template for the pattern fizzbuzz6(N) => println("\nfizzbuzz6"), F = [_,_,fizz,_,buzz,fizz,_,_,fizz,buzz,_,fizz,_,_,fizzbuzz], FF = [F : _I in 1..1+N div F.length].flatten(), foreach(I in 1..N) (var(FF[I]) -> print(I) ; print(FF[I])), print(" ") end, nl. % a little of the same idea as fizzbuzz6 fizzbuzz7(N) => println("\nfizzbuzz7"), F = new_list(N), FV = [3,5,15], FN = ["Fizz","Buzz","FizzBuzz"], foreach(I in 1..N, {Val,Name} in zip(FV,FN)) if I mod Val == 0 then F[I] := Name end end, foreach(I in 1..N) printf("%w ", cond(var(F[I]),I, F[I])) end, nl. fizzbuzz7b(N) => println("\nfizzbuzz7bx"), F = [0 : _I in 1..N], FV = [3,5,15], FN = ["Fizz","Buzz","FizzBuzz"], foreach(I in 1..N, {Val,Name} in zip(FV,FN)) if I mod Val == 0 then F[I] := Name end end, foreach(I in 1..N) printf("%w ", cond(F[I] == 0, I, F[I])) end, nl. fizzbuzz8(N) => println("\nfizzbuzz8"), plan(N,Plan), println(Plan.reverse()), nl. fizzbuzz9(N) => println("\nfizzbuzz9"), fb9(N,[],L), println(L), nl. fizzbuzz9b(N) => println("\nfizzbuzz9b"), fb9b(N,[],L), println(L), nl. % % plain imperative approach % fb1(I) = V => V = I.to_string(), if I mod 15 == 0 then V := "FizzBuzz" elseif I mod 3 == 0 then V := "Fizz" elseif I mod 5 == 0 then V := "Buzz" end. % % pattern matching + conditions in head % fb2(I) = "FizzBuzz", I mod 15 == 0 => true. fb2(I) = "Fizz", I mod 3 == 0 => true. fb2(I) = "Buzz", I mod 5 == 0 => true. fb2(I) = I.to_string() => true. % % string concatenation and cond/3 % fb3(I) = cond(I mod 3 == 0, "Fizz", "") ++ cond(I mod 5 == 0, "Buzz", "") ++ cond(not ((I mod 3 == 0; I mod 5==0)), I.to_string(), ""). % % pattern matching % fb5(I) = fb5b(I, I mod 3, I mod 5). fb5b(_I,0,0) = "FizzBuzz". fb5b(_I,_,0) = "Buzz". fb5b(_I,0,_) = "Fizz". fb5b(I,_,_) = I. % % Traditional LP % fb9(N,L1,L) ?=> N = 0, L = L1.reverse(). fb9(N,L1,L) ?=> N mod 15 == 0, fb9(N-1,L1 ++ ["FizzBuzz"], L). fb9(N,L1,L) ?=> N mod 5 == 0, fb9(N-1,L1 ++ ["Buzz"], L). fb9(N,L1,L) ?=> N mod 3 == 0, fb9(N-1,L1 ++ ["Fizz"], L). fb9(N,L1,L) => % N mod 3 > 0, % N mod 5 > 0, fb9(N-1,L1 ++ [N.to_string()], L). % % LP variant with conditions % fb9b(N,L1,L), N = 0 ?=> L = L1.reverse(). fb9b(N,L1,L),N mod 15 == 0 ?=> fb9b(N-1,L1 ++ ["FizzBuzz"], L). fb9b(N,L1,L), N mod 5 == 0 ?=> fb9b(N-1,L1 ++ ["Buzz"], L). fb9b(N,L1,L), N mod 3 == 0 ?=> fb9b(N-1,L1 ++ ["Fizz"], L). fb9b(N,L1,L), N mod 3 > 0, N mod 5 > 0 => fb9b(N-1,L1 ++ [N.to_string()], L). % % planner variant, for fizzbuzz8 % final(Goal) => Goal == 0. action(H,To,Move,Cost) ?=> H mod 15 == 0, Move = "FizzBuzz", To = H-1, Cost = 1. action(H,To,Move,Cost) ?=> H mod 5 == 0, Move = "Buzz", To = H-1, Cost = 1. action(H,To,Move,Cost) ?=> H mod 3 == 0, Move = "Fizz", To = H-1, Cost = 1. action(H,To,Move,Cost) => H mod 3 > 0, H mod 5 > 0, Move = H.to_string(), To = H-1, Cost = 1. fizzbuzz10(N) => println(fizzbuzz10), V = [_,'Fizz','Buzz','FizzBuzz'], foreach(I in 1..N) T = 1, ((I mod 3 == 0) -> T := T+1 ; true), ((I mod 5 == 0) -> T := T+2 ; true), V[1] := I, print(V[T]), I < N -> print(",") ; true end, nl,nl. fizzbuzz11(N) => println(fizzbuzz11), % [cond(FB=="",I,FB):I in 1..100,FB=cond(I mod 3==0,"Fizz","")++cond(I mod 5==0,"Buzz","")].println(), [cond(P=="",I,P):I in 1..100,(I mod 3==0->P="Fizz";P=""),(I mod 5==0->P:=P++"Buzz";true)].println(), nl.