/* Frustration patience (simulation) in Picat. From https://community.wolfram.com/groups/-/m/t/1609558 """ Frustration solitaire is a game that has roots stemming from the early 1700's. The rules of the game are simple: a dealer calls out the ranks of cards in order Ace, Two, Three, . . . and so on. At the same time the dealer draws a card from a sufficiently well shuffled deck. If the rank of the card drawn matches the rank of the card the dealer says you lose the game. ... Now we shouldn't feel too bad about losing. The name "frustration" solitaire stems from the fact that the percentage of winning is actually very low. In 2009, Doyle et. al. found out that the percentage of winning a game of frustration solitaire is approximately 1.62%. ... In our 100,000 games of frustration solitaire we won 1.61% of the time, hence the title of "frustration" solitaire is very well deserved. """ This Picat model was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ main => go. % Run N random runs and show the probability of winning go => garbage_collect(200_000_000), _ = random2(), Ranks = [J : _ in 1..4, J in 1..13], N = 100_000, R = sum([1 : J in 1..N, frustration(shuffle(Ranks)) == 0]), println(r=R), println(R/N), nl. % Show the distributions of number of matches. % (0 is winning, all else are losses): % map)[0 = 1581,1 = 6882,2 = 14350,3 = 19870,4 = 20203,5 = 16159,6 = 10552,7 = 5837,8 = 2814,9 = 1148,10 = 402,11 = 145,12 = 44,13 = 11,14 = 2] go2 => _ = random2(), Ranks = [J : _ in 1..4, J in 1..13], N = 100_000, R = [frustration(shuffle(Ranks)): _ in 1..N], println(occurrences(R)), nl. % Show one run in detail go3 => garbage_collect(200_000_000), _ = random2(), Ranks = [J : _ in 1..4, J in 1..13], R = shuffle(Ranks), println(R), println(frustration(Ranks)), println([[1+(I mod 13),Ranks[I+1],cond(1+(I mod 13) ==R[I+1],1,0)] : I in 0..Ranks.len-1]), nl. % Returns the number of matches in the Ranks list. frustration(Ranks) = sum([1 : I in 0..Ranks.len-1, 1+(I mod 13) == Ranks[I+1]]). % % Shuffles the list List. % shuffle(List) = List2 => List2 = List, Len = List.length, foreach(I in 1..Len) R2 = 1+(random() mod Len), List2 := swap(List2,I,R2) end. % % Swap position I <=> J in list L % swap(L,I,J) = L2, list(L) => L2 = L, T = L2[I], L2[I] := L2[J], L2[J] := T. % % Number of occurrences of each elements in List. % occurrences(List) = Map => Map = new_map(), foreach(E in List) Map.put(E, cond(Map.has_key(E),Map.get(E)+1,1)) end.