/* Drunk Ant in Picat. https://brainstellar.com/puzzles/probability/202 """ An ant is standing on one corner of a cube & can only walk on the edges. The ant is drunk and from any corner, it moves randomly by choosing any edge! What is the expected number of edges the ant travels, to reach the opposite corner? Answer: 10 """ Cf my Gamble model gamble_drunk_ant.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. /* 0-based 4--------5 / | / | 0--------1 | | | | | | | | | | 6-----|--7 | / | / 2--------3 Edges: 0 -> 1 2 4 1 -> 0 3 5 2 -> 0 3 6 3 -> 1 2 7 4 -> 0 5 6 5 -> 1 4 7 6 -> 2 4 7 7 -> 3 5 6 Converting to 1-based in the model. var : a Probabilities (truncated): [1,5,6,8]: 0.0412000000000000 [1,3,4,8]: 0.0367000000000000 [1,2,6,8]: 0.0364000000000000 [1,5,7,8]: 0.0355000000000000 ......... [1,2,1,2,1,2,1,2,1,5,1,2,1,2,4,3,4,8]: 0.0001000000000000 [1,2,1,2,1,2,1,2,1,3,1,2,6,5,7,8]: 0.0001000000000000 [1,2,1,2,1,2,1,2,1,2,6,2,4,8]: 0.0001000000000000 [1,2,1,2,1,2,1,2,1,2,4,3,1,5,6,8]: 0.0001000000000000 Mean (truncated) mean = [[1,5,6,8] = 0.0412,[1,3,4,8] = 0.0367,[1,2,6,8] = 0.0364,[1,5,7,8] = 0.0355,[1,3,7,8] = 0.0346,[1,2,4,8] = 0.0346,[1,2,1,5,7,8] = 0.0055,[1,2,6,5,7,8] = 0.0051,[1,2,4,3,4,8] = 0.0051,[1,3,7,3,7,8] = 0.005,[1,5,7,3,4,8] = 0.0049,[1,2,1,3,7,8] = 0.0049,[1,2,1,2,6,8] = 0.0048,[1,3,4,2,4,8] = 0.0047,[1,2,1,2,4,8] = 0.0047,[1,5,6,2,4,8] = 0.0046,[1,5,1,5,6,8] = 0.0044,[1,5,1,3,7,8] = 0.0044,[1,2,6,2,6,8] = 0.0044,[1,2,6,2,4,8] = 0.0044] var : len Probabilities (truncated): 3: 0.2190000000000000 5: 0.1689000000000000 7: 0.1379000000000000 9: 0.1040000000000000 ......... 65: 0.0001000000000000 63: 0.0001000000000000 59: 0.0001000000000000 57: 0.0001000000000000 mean = 10.051 */ go ?=> reset_store, run_model(10_000,$model,[show_probs_trunc,mean]), nl, % show_store_lengths,nl, % fail, nl. go => true. add1(N) = N + 1. % Convert from (Gamble's) 0-based edges() = [[1,2,4], [0,3,5], [0,3,6], [1,2,7], [0,5,6], [1,4,7], [2,4,7], [3,5,6]].flatten.map(add1).chunks_of(3). model() => Start = 1, End = 8, Edges = edges(), OK = false, A = [Start], while (OK == false) Pos = A.last, if Pos == End then OK := A else A := A ++ [uniform_draw(Edges[Pos])] end end, Len = A.len - 1, % Don't count the start node add("a",A), add("len",Len).