/* Pair of socks in Picat. https://en.wikibooks.org/wiki/Puzzles/Logic_puzzles/Pair_of_Socks """ There are 10 black socks and 10 white socks(no left-right distinction) in the wardrobe. Your task is to draw the minimum number of socks at random to be sure you have a pair of a single color. How many socks should you draw? """ Here's a simple simulation of 100 runs [3,2,2,2,2,2,2,2,2,3,2,2,3,2,3,2,2,2,3,2,3,3,3,3,2,3,3,2,3,3,2,3,3,2,3,3,2,2,2,3,3,2,3,2,3,3,3,3,2,3,2,2,2,3,3,3,2,2,2,2,2,2,2,3,2,2,3,3,3,2,2,3,3,3,3,2,3,3,2,2,2,2,2,3,2,2,2,3,3,2,2,3,3,3,2,2,3,2,3,3] max = 3 I.e. we need to draw 3 socks to be sure to get a pair of single socks. Yes, this is overkill... This program was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ main => go. go ?=> Socks = ["Black" : _ in 1..10] ++ ["White" : _ in 1..10], Len = Socks.len, println(socks=Socks), _ = random2(), Ls = [], foreach(_ in 1..100) Found = [], foreach(N in 1..Len, break(Found == true)) Ks = get_k_random(N,1,Len), Rs = [ Socks[R] : R in Ks], Map = occurrences(Rs), if Map.get("Black",0) >= 2 ; Map.get("White",0) >= 2 then Ls := Ls ++ [N], Found := true end, end, end, println(Ls), println(max=Ls.max), nl. go => true. % Get k random unique numbers between From and To get_k_random(K, From, To) = Ls => Ls0 = [], while (Ls0.len < K) R = random(From,To), if not membchk(R,Ls) then Ls0 := Ls0 ++ [R] end end, Ls = Ls0. % % occurrences(List): % returns a map with all the keys and the % number of occurrences of each elements. % occurrences(List) = Map => Map = new_map(), foreach(E in List) Map.put(E, cond(Map.has_key(E),Map.get(E)+1,1)) end.