Last active
December 29, 2015 23:19
-
-
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
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
/* | |
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