/* Collecting lucky coupons in Picat. https://brainstellar.com/puzzles/probability/206 """ A soda company is holding a contest where everyone who collects one each of N different coupons wins some prize. You get a coupon with each purchase of a soda, and each coupon is equally likely. What’s the expected number of soda bottles you have to buy in order to collect all the coupons? """ Cf - ppl_coupon_collectors_problem.pi - ppl_coupon_collectors3.pi - my Gamble model gamble_collecting_lucky_coupons.rkt This program was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ import ppl_distributions, ppl_utils. import util. main => go. /* var : len Probabilities (truncated): 22: 0.0487000000000000 21: 0.0448000000000000 25: 0.0445000000000000 23: 0.0439000000000000 ......... 90: 0.0001000000000000 89: 0.0001000000000000 85: 0.0001000000000000 77: 0.0001000000000000 mean = 29.151 Histogram (total 10000) 10.000: 31 # (0.003 / 0.003) 12.300: 121 ###### (0.012 / 0.015) 14.600: 312 ############### (0.031 / 0.046) 16.900: 958 ############################################## (0.096 / 0.142) 19.200: 803 ###################################### (0.080 / 0.222) 21.500: 935 ############################################# (0.093 / 0.316) 23.800: 875 ########################################## (0.087 / 0.403) 26.100: 1257 ############################################################ (0.126 / 0.529) 28.400: 745 #################################### (0.074 / 0.604) 30.700: 643 ############################### (0.064 / 0.668) 33.000: 776 ##################################### (0.078 / 0.746) 35.300: 444 ##################### (0.044 / 0.790) 37.600: 402 ################### (0.040 / 0.830) 39.900: 421 #################### (0.042 / 0.872) 42.200: 229 ########### (0.023 / 0.895) 44.500: 192 ######### (0.019 / 0.914) 46.800: 144 ####### (0.014 / 0.929) 49.100: 181 ######### (0.018 / 0.947) 51.400: 93 #### (0.009 / 0.956) 53.700: 83 #### (0.008 / 0.965) 56.000: 82 #### (0.008 / 0.973) 58.300: 65 ### (0.006 / 0.979) 60.600: 38 ## (0.004 / 0.983) 62.900: 51 ## (0.005 / 0.988) 65.200: 20 # (0.002 / 0.990) 67.500: 19 # (0.002 / 0.992) 69.800: 18 # (0.002 / 0.994) 72.100: 13 # (0.001 / 0.995) 74.400: 13 # (0.001 / 0.996) 76.700: 5 (0.001 / 0.997) 79.000: 6 (0.001 / 0.997) 81.300: 7 (0.001 / 0.998) 83.600: 7 (0.001 / 0.999) 85.900: 1 (0.000 / 0.999) 88.200: 3 (0.000 / 0.999) 90.500: 3 (0.000 / 1.000) 92.800: 1 (0.000 / 1.000) 95.100: 0 (0.000 / 1.000) 97.400: 1 (0.000 / 1.000) 99.700: 2 (0.000 / 1.000) */ go ?=> reset_store, run_model(10_000,$model,[show_probs_trunc,mean,show_histogram]), nl, % show_store_lengths,nl, % fail, nl. go => true. collecting_coupons(A,N) = Res => if N == A.remove_dups.len then Res = A else Res = collecting_coupons(A ++ [random_integer1(N)],N) end. model() => N = 10, A = collecting_coupons([],N), add("len",A.len).