```1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 ``` ```/* #1 The goat will eat the cabbage. #2 The goat will eat the gun if the hunter is not there. #3 The wolf will eat the goat. #4 The wolf eat the monkey if he can't hide on the washing machine #5 The hunter will kill the wolf with the help of his gun #6 You need the gun to convince the hunter to come into the boat. #7 The monkey will turn on the washing machine and destroy its contents if not playing with the cabbage. #8 The monkey will throw the cabbage at the wolf if they're on opposite sides ( The wolf will flee ) #9 You need help from the hunter to lift the washing machine. U = gun u = gun in washing machine H = hunter W = washing machine M = monkey O = wolf G = goat C = cabbage c = cabbage in washing machine */ include('stdlib.pika'); enum = function { for (i = 0; i < \$n; ++i) [\$[i]] = i; }; enum(@GUN, @WASHER_GUN, @HUNTER, @WASHER, @MONKEY, @WOLF, @GOAT, @CABBAGE, @WASHER_CABBAGE); ITEM_CHARS = 'UuHWMOGCc'; INIT_LEFT = 'U_HWMOGC_'; INIT_RIGHT = '_________'; GOAL_STATE = '_________/U_HWMOGC_P'; got = function { (\$0{\$1} === ITEM_CHARS{\$1}); }; add = function { (\$0{:\$1} # ITEM_CHARS{\$1} # \$0{\$1 + 1:}) }; drop = function { (\$0{:\$1} # '_' # \$0{\$1 + 1:}) }; fail = function { args(@l, @r); if (got(r, GOAT) && got(r, CABBAGE)) ( 'goat eats cabbage' ) else if (got(r, GOAT) && got(r, GUN) && !got(r, HUNTER)) ( 'goat eats gun' ) else if (got(r, WOLF) && got(r, GOAT)) ( 'wolf eats goat' ) else if (got(r, WOLF) && got(r, MONKEY) && !got(r, WASHER)) ( 'wolf eats monkey' ) else if (got(r, HUNTER) && got(r, GUN) && got(r, WOLF)) ( 'hunter shoots wolf' ) else if (got(r, MONKEY) && got(r, WASHER_GUN) && !got(r, CABBAGE)) ( 'monkey destroys gun in washing machine' ) else if (got(r, MONKEY) && got(r, WASHER_CABBAGE)) ( 'monkey destroys cabbage in washing machine' ) else if (got(r, MONKEY) && got(r, CABBAGE) && got(l, WOLF)) ( 'monkey throws cabbage at wolf' ) else ''; }; prune(@::visited); ::currentChain.n = 0; move = function { args(@l, @r, @side, @depth, @desc); ::currentChain[depth] = desc; ++depth; ::currentChain.n = depth; if (side === 0) { s = l # 'P' # '/' # r; } else { s = r # '/' # l # 'P'; }; if (!exists(@::visited[s]) || ::visited[s] > depth) { //print(repeat(' ', depth) # desc # ': ' # s); ::visited[s] = depth; if (s === GOAL_STATE) { //print(repeat(' ', depth) # ' **** SOLUTION **** '); clone(@::currentChain, @::bestChain); } else if ((s = fail(l, r)) !== '') { //print(repeat(' ', depth) # s # '!') } else { move(r, l, 1 - side, depth, 'cross empty'); if (got(l, GUN)) move(add(r, GUN), drop(l, GUN), 1 - side, depth, 'cross with gun'); if (got(l, HUNTER) && got(l, GUN)) move(add(r, HUNTER), drop(l, HUNTER), 1 - side, depth, 'threaten hunter into boat and cross'); if (got(l, WASHER) && got(l, HUNTER) && !got(l, WASHER_CABBAGE) && !got(l, WASHER_GUN)) move(add(r, WASHER), drop(l, WASHER), 1 - side, depth, 'cross with washing machine that hunter helps lifting'); if (got(l, MONKEY)) move(add(r, MONKEY), drop(l, MONKEY), 1 - side, depth, 'cross with monkey'); if (got(l, WOLF)) move(add(r, WOLF), drop(l, WOLF), 1 - side, depth, 'cross with wolf'); if (got(l, GOAT)) move(add(r, GOAT), drop(l, GOAT), 1 - side, depth, 'cross with goat'); if (got(l, CABBAGE)) move(add(r, CABBAGE), drop(l, CABBAGE), 1 - side, depth, 'cross with cabbage'); if (got(l, GUN) && got(l, WASHER) && !got(l, WASHER_CABBAGE)) move(add(drop(l, GUN), WASHER_GUN), r, side, depth, 'place gun into washing machine'); if (got(l, CABBAGE) && got(l, WASHER) && !got(l, WASHER_GUN)) move(add(drop(l, CABBAGE), WASHER_CABBAGE), r, side, depth, 'place cabbage into washing machine'); if (got(l, WASHER_GUN)) move(add(drop(l, WASHER_GUN), GUN), r, side, depth, 'remove gun from washing machine'); if (got(l, WASHER_CABBAGE)) move(add(drop(l, WASHER_CABBAGE), CABBAGE), r, side, depth, 'remove cabbage from washing machine'); } } }; move(INIT_LEFT, INIT_RIGHT, 0, 0, 'starting'); for (i = 1; i < ::bestChain.n; ++i) { print(i # '. ' # ::bestChain[i]); }; ===================================================================== 1. place gun into washing machine 2. cross with goat 3. cross empty 4. cross with monkey 5. cross with goat 6. remove gun from washing machine 7. place cabbage into washing machine 8. cross with wolf 9. cross with monkey 10. remove cabbage from washing machine 11. cross with cabbage 12. cross empty 13. cross with washing machine that hunter helps lifting 14. cross empty 15. cross with monkey 16. cross with cabbage 17. cross with goat 18. cross with wolf 19. threaten hunter into boat and cross 20. cross empty 21. cross with gun 22. cross empty 23. cross with cabbage 24. place cabbage into washing machine 25. cross with monkey 26. cross with wolf 27. remove cabbage from washing machine 28. place gun into washing machine 29. cross with goat 30. cross with monkey 31. cross empty 32. cross with goat 33. remove gun from washing machine ```