Created
February 28, 2017 01:31
-
-
Save misternu/6e9fbfe4b1e16d1e32a933e3cd1e10bf to your computer and use it in GitHub Desktop.
This solves a riddle way too explicitly, yay!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| def game_rules(items) | |
| boat_west = items[0] | |
| wolf_west = items[1] | |
| duck_west = items[2] | |
| grain_west = items[3] | |
| return false if (!wolf_west && !duck_west) && boat_west | |
| return false if (!duck_west && !grain_west) && boat_west | |
| return false if (wolf_west && duck_west) && !boat_west | |
| return false if (duck_west && grain_west) && !boat_west | |
| true | |
| end | |
| def game_rules2(items) | |
| !(items[0] && (!items[1] && !items[2])) && | |
| !(items[0] && (!items[2] && !items[3])) && | |
| !(!items[0] && (items[1] && items[2])) && | |
| !(!items[0] && (items[2] && items[3])) | |
| end | |
| def game_rules3(items) | |
| !(items[0] && ((!items[1] && !items[2]) || (!items[2] && !items[3]))) && | |
| !(!items[0] && ((items[1] && items[2]) || (items[2] && items[3]))) | |
| end | |
| def game_rules4(items) | |
| !(items[0] && !items[2] && (!items[1] || !items[3])) && | |
| !(!items[0] && items[2] && (items[1] || items[3])) | |
| end | |
| # Where items is A, B, C, D | |
| # NOT(A AND NOT(C) AND (NOT(B) OR NOT(D))) AND NOT(NOT(A) AND NOT(C) AND (A OR C)) | |
| def test(&block) | |
| p yield([false, false, false, false]) == true | |
| p yield([false, false, false, true]) == true | |
| p yield([false, false, true, false]) == true | |
| p yield([false, false, true, true]) == false # Duck alone with grain | |
| p yield([false, true, false, false]) == true | |
| p yield([false, true, false, true]) == true | |
| p yield([false, true, true, false]) == false # Wolf alone with duck | |
| p yield([false, true, true, true]) == false # All alone without boat | |
| p yield([true, false, false, false]) == false # All alone without boat | |
| p yield([true, false, false, true]) == false # Wolf alone with duck | |
| p yield([true, false, true, false]) == true | |
| p yield([true, false, true, true]) == true | |
| p yield([true, true, false, false]) == false # Duck alone with grain | |
| p yield([true, true, false, true]) == true | |
| p yield([true, true, true, false]) == true | |
| p yield([true, true, true, true]) == true | |
| end | |
| # test { |state| game_rules(state) } | |
| # test { |state| game_rules2(state) } | |
| # test { |state| game_rules3(state) } | |
| # test { |state| game_rules4(state) } | |
| def all_moves(items) | |
| # find the possible moves from this current state, even illegal ones | |
| moves = [] | |
| if items[0] | |
| # Then we are moving the boat from west to east | |
| moves << [false] + items[1..-1] | |
| # If there is a wolf here, try bringing it too | |
| moves << [false, false] + items[2..-1] if items[1] | |
| # If there is a duck here, try bringing it too | |
| moves << [false] + [items[1]] + [false] + [items[3]] if items[2] | |
| # If there is grain here, try bringing it too | |
| moves << [false] + items[1..2] + [false] if items[3] | |
| else | |
| # Then we are moving the boat from east to west | |
| moves << [true] + items[1..-1] | |
| # If there is a wolf here, try bringing it too | |
| moves << [true, true] + items[2..-1] if !items[1] | |
| # If there is a duck here, try bringing it too | |
| moves << [true] + [items[1]] + [true] + [items[3]] if !items[2] | |
| # If there is grain here, try bringing it too | |
| moves << [true] + items[1..2] + [true] if !items[3] | |
| end | |
| moves | |
| end | |
| def all_moves2(items) | |
| moves = [] | |
| # Try moving just the boat | |
| moves << [!items[0]] + items[1..-1] | |
| # If the boat is with the wolf, move the wolf | |
| moves << [!items[0], !items[1], items[2], items[3]] if items[0] == items[1] | |
| # If the boat is with the duck, move the duck | |
| moves << [!items[0], items[1], !items[2], items[3]] if items[0] == items[2] | |
| # If the boat is with the grain, move the grain | |
| moves << [!items[0], items[1], items[2], !items[3]] if items[0] == items[3] | |
| # Return the moves | |
| moves | |
| end | |
| # starting game state = [true, true, true, true] | |
| def solve(items = [true, true, true, true], previous_states = []) | |
| return previous_states + [items] if items.none? | |
| # Get all the moves | |
| moves = all_moves2(items) | |
| # Keep only the ones that are legal and we haven't tried on this branch | |
| viable_moves = moves.select do |move| | |
| game_rules4(move) && !previous_states.include?(move) | |
| end | |
| # Try all the viable moves (What happens here if there are no moves?) | |
| viable_moves.each do |move| | |
| new_previous_states = previous_states.dup.push(items) | |
| result = solve(move, new_previous_states) | |
| return result if result | |
| end | |
| # Alas, this branch is dead | |
| return false | |
| end | |
| solve.each do |step| | |
| p step | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment