Skip to content

Instantly share code, notes, and snippets.

@deckarep
Last active December 29, 2015 23:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save deckarep/7742505 to your computer and use it in GitHub Desktop.
Save deckarep/7742505 to your computer and use it in GitHub Desktop.
The fox, gopher and bag of beans puzzle in Go -- https://coderwall.com/p/lb3eaw
/*
The fox, gopher and bag of beans puzzle in Go.
https://coderwall.com/p/lb3eaw
*/
package main
import (
"fmt"
"log"
)
//The good 'ol farmer
type Farmer struct {
}
//The gopher (goose) that the farmer purchased at the market
type Gopher struct {
}
func (g *Gopher) Eat(b *BagOfBeans, f *Farmer) {
if b != nil && f == nil {
log.Fatal("OOPS: Gopher just ate all the beans")
}
}
//The bag of beans that the farmer purchased at the market
type BagOfBeans struct {
}
//The fox that the farmer purchased at the market
type Fox struct {
}
func (fox *Fox) Eat(g *Gopher, f *Farmer) {
if g != nil && f == nil {
log.Fatal("OOPS: Fox ate gopher just now.")
}
}
//The boat where the farmer can ride and take only one item with him.
type Boat struct {
farmer *Farmer
gopher *Gopher
fox *Fox
beans *BagOfBeans
}
type Side int
const (
East = 0
West = 1
)
type Bank struct {
farmer *Farmer
fox *Fox
gopher *Gopher
beans *BagOfBeans
side Side
}
func (b *Bank) checkState() {
counter := 0
if b.fox != nil {
counter++
b.fox.Eat(b.gopher, b.farmer)
}
if b.gopher != nil {
counter++
b.gopher.Eat(b.beans, b.farmer)
}
if b.beans != nil {
counter++
}
if b.farmer != nil {
counter++
}
sd := "West"
if b.side == East {
sd = "East"
}
fmt.Printf("%s bank: %+v\n", sd, b)
if counter == 4 && b.side == West{
fmt.Println("!!YOU WIN!!")
}
}
func (b *Bank) Send(boat Boat) {
b.farmer = nil
if boat.gopher != nil {
b.gopher = nil
}
if boat.beans != nil {
b.beans = nil
}
if boat.fox != nil {
b.fox = nil
}
b.checkState()
river <- boat
}
func (b *Bank) Receive() {
boat := <-river
b.farmer = boat.farmer
if boat.gopher != nil {
b.gopher = boat.gopher
}
if boat.beans != nil {
b.beans = boat.beans
}
if boat.fox != nil {
b.fox = boat.fox
}
b.checkState()
}
//The river that the farmer must cross with all his belongings
var river = make(chan Boat, 1)
func main() {
//The west bank starts off empty
westBank := Bank{side: West}
//The east bank starts off with the farmer and his store bought items
eastBank := Bank{side: East}
//We create an instance of the farmer, fox, bag of beans, and lastly the gopher
eastBank.farmer = &Farmer{}
eastBank.fox = &Fox{}
eastBank.beans = &BagOfBeans{}
eastBank.gopher = &Gopher{}
//ONE SOLUTION IS BELOW
//Stage 1
eastBank.Send(Boat{farmer: eastBank.farmer, gopher: eastBank.gopher})
westBank.Receive()
//Stage 2
westBank.Send(Boat{farmer: westBank.farmer})
eastBank.Receive()
//Stage 3
eastBank.Send(Boat{farmer: eastBank.farmer, fox: eastBank.fox})
westBank.Receive()
//Stage 4
westBank.Send(Boat{farmer: westBank.farmer, gopher: westBank.gopher})
eastBank.Receive()
//Stage 5
eastBank.Send(Boat{farmer: eastBank.farmer, beans: eastBank.beans})
westBank.Receive()
//Stage 6
westBank.Send(Boat{farmer: westBank.farmer})
eastBank.Receive()
//Stage 7
eastBank.Send(Boat{farmer: eastBank.farmer, gopher: eastBank.gopher})
westBank.Receive()
//var str string
//fmt.Scanln(&str)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment