Wolf , Goat , Cabbage Puzzle!

Problem Statement

The wolf, goat and cabbage problem is a river crossing puzzle. It dates back to at least the 9th century and has entered the folklore of several cultures. A farmer went to a market and purchased a wolf, a goat, and a cabbage. On his way home, the farmer came to the bank of a river and rented a boat. But crossing the river by boat, the farmer could carry only himself and a single one of his purchases: the wolf, the goat, or the cabbage If left unattended together, the wolf would eat the goat, or the goat would eat the cabbage.The farmer’s challenge was to carry himself and his purchases to the far bank of the river, leaving each purchase intact.

My Solution

Initially, we mention the abbreviated form of the characters of the story and also mention the forbidden states.

import os 
import time 

names = {"F": "Farmer",
         "W": "Wolf",
         "G": "Goat",
         "C": "Cabbage"}

forbidden_states = [{"W", "G"}, {"G", "C"}, {"G", "C", "W"}]

Re-define the story

 print("""
#### WOLF, GOAT and CABBAGE PROBLEM ####

Once upon a time a farmer went to a market and purchased a wolf, a goat, and a cabbage. On his way home, the farmer came
to the bank of a river and rented a boat. But crossing the river by boat, the farmer could carry only himself and a single
one of his purchases: the wolf, the goat, or the cabbage.

If left unattended together, the wolf would eat the goat, or the goat would eat the cabbage.

The farmer's challenge was to carry himself and his purchases to the far bank of the river, leaving each purchase intact.
How did he do it?
""")
    input("Press enter to continue.")

For better presentation of the output we define a clear function

def clear():
     print("*" * 60, "\n")

Define the current state of the puzzle

def print_state(state):
    left_bank, right_bank = state
    print("#### CURRENT STATE OF PUZZLE ####")
    print()
    left_bank_display = [names[item] for item in left_bank]
    right_bank_display = [names[item] for item in right_bank]
    print(left_bank_display, "|", right_bank_display if right_bank else "[]")

Which item do we wish to move is defined here

def get_move():
    print("Which item do you wish to take across the river?")
    answer = ""
    while answer.upper() not in ["F", "W", "G", "C"]:
        answer = input("Just Farmer (f), Wolf (w), Goat (g) or Cabbage (c)? ")

    return answer.upper()

Actual logic is applied here

def process_move(move, state):
    # We need to "think ahead" to see if move is illegal.
    temp_state = [state[0].copy(), state[1].copy()]
    containing_set = 0 if move in state[0] else 1
    if "F" not in state[containing_set]:
        print("Illegal move.")
        print()
        time.sleep(1)
        return state
    if containing_set == 0:
        temp_state[0].difference_update({move, "F"})
        temp_state[1].update([move, "F"])
    elif containing_set == 1:
        temp_state[1].difference_update({move, "F"})
        temp_state[0].update([move, "F"])
    if temp_state[0] not in forbidden_states and temp_state[1] not in forbidden_states:
        state = [temp_state[0].copy(), temp_state[1].copy()]
    else:
        print("Illegal move.")
        print()
        time.sleep(1)
    print()
    return state

def is_win(state):
    return state[1] == {"F", "W", "G", "C"}

The main function of the program

def main():
    left_bank = {"F", "W", "G", "C"}
    right_bank = set()
    state = [left_bank, right_bank]
    print_story()
    while not is_win(state):
        clear()
        print_state(state)
        move = get_move()
        state = process_move(move, state)

    print("Well done - you solved the puzzle!")
    main()

The output!

#### WOLF, GOAT and CABBAGE PROBLEM ####

Once upon a time a farmer went to a market and purchased a wolf, a goat, and a cabbage. On his way home, the farmer came
to the bank of a river and rented a boat. But crossing the river by boat, the farmer could carry only himself and a single
one of his purchases: the wolf, the goat, or the cabbage.

If left unattended together, the wolf would eat the goat, or the goat would eat the cabbage.

The farmer's challenge was to carry himself and his purchases to the far bank of the river, leaving each purchase intact.
How did he do it?

Press enter to continue.
************************************************************ 

#### CURRENT STATE OF PUZZLE ####

['Cabbage', 'Wolf', 'Farmer', 'Goat'] | []
Which item do you wish to take across the river?
Just Farmer (f), Wolf (w), Goat (g) or Cabbage (c)? F,G
Just Farmer (f), Wolf (w), Goat (g) or Cabbage (c)? G

************************************************************ 

#### CURRENT STATE OF PUZZLE ####

['Wolf', 'Cabbage'] | ['Farmer', 'Goat']
Which item do you wish to take across the river?
Just Farmer (f), Wolf (w), Goat (g) or Cabbage (c)? F

************************************************************ 

#### CURRENT STATE OF PUZZLE ####

['Wolf', 'Farmer', 'Cabbage'] | ['Goat']
Which item do you wish to take across the river?
Just Farmer (f), Wolf (w), Goat (g) or Cabbage (c)? F,C
Just Farmer (f), Wolf (w), Goat (g) or Cabbage (c)? C

************************************************************ 

#### CURRENT STATE OF PUZZLE ####

['Wolf'] | ['Cabbage', 'Farmer', 'Goat']
Which item do you wish to take across the river?
Just Farmer (f), Wolf (w), Goat (g) or Cabbage (c)? F,G
Just Farmer (f), Wolf (w), Goat (g) or Cabbage (c)? G

************************************************************ 

#### CURRENT STATE OF PUZZLE ####

['Wolf', 'Farmer', 'Goat'] | ['Cabbage']
Which item do you wish to take across the river?
Just Farmer (f), Wolf (w), Goat (g) or Cabbage (c)? F,W
Just Farmer (f), Wolf (w), Goat (g) or Cabbage (c)? W

************************************************************ 

#### CURRENT STATE OF PUZZLE ####

['Goat'] | ['Wolf', 'Farmer', 'Cabbage']
Which item do you wish to take across the river?
Just Farmer (f), Wolf (w), Goat (g) or Cabbage (c)? F

************************************************************ 

#### CURRENT STATE OF PUZZLE ####

['Farmer', 'Goat'] | ['Wolf', 'Cabbage']
Which item do you wish to take across the river?
Just Farmer (f), Wolf (w), Goat (g) or Cabbage (c)? F,G
Just Farmer (f), Wolf (w), Goat (g) or Cabbage (c)? F,G
Just Farmer (f), Wolf (w), Goat (g) or Cabbage (c)? G

Well done - you solved the puzzle!