Logic puzzle
// Solve this logic puzzle: | |
// https://xmonader.github.io/prolog/2018/12/21/solving-murder-prolog.html | |
package main | |
import ( | |
"fmt" | |
"github.com/unixpickle/approb" | |
) | |
const ( | |
Bathroom = iota | |
DiningRoom | |
Kitchen | |
LivingRoom | |
Pantry | |
Study | |
) | |
const ( | |
George = iota | |
John | |
Robert | |
Barbara | |
Christine | |
Yolanda | |
) | |
const ( | |
Bag = iota | |
Firearm | |
Gas | |
Knife | |
Poison | |
Rope | |
) | |
type Configuration struct { | |
People []int | |
Weapons []int | |
} | |
func main() { | |
for people := range approb.Perms(6) { | |
for weapons := range approb.Perms(6) { | |
cfg := &Configuration{people, weapons} | |
if !clue1(cfg) || !clue2(cfg) || !clue3(cfg) || !clue4(cfg) || !clue5(cfg) || | |
!clue6(cfg) || !clue7(cfg) || !clue8(cfg) || !clue9(cfg) { | |
continue | |
} | |
fmt.Println("person,weapon:", cfg.People[Pantry], cfg.Weapons[Pantry]) | |
} | |
} | |
} | |
func clue1(cfg *Configuration) bool { | |
return isMan(cfg.People[Kitchen]) && (cfg.Weapons[Kitchen] == Knife || cfg.Weapons[Kitchen] == Gas) | |
} | |
func clue2(cfg *Configuration) bool { | |
if cfg.People[Study] == Barbara { | |
return cfg.People[Bathroom] == Yolanda | |
} else if cfg.People[Study] == Yolanda { | |
return cfg.People[Bathroom] == Barbara | |
} else { | |
return false | |
} | |
} | |
func clue3(cfg *Configuration) bool { | |
bagRoom := indexOf(cfg.Weapons, Bag) | |
if cfg.People[bagRoom] == Barbara || cfg.People[bagRoom] == George { | |
return false | |
} | |
return bagRoom != Bathroom && bagRoom != DiningRoom | |
} | |
func clue4(cfg *Configuration) bool { | |
if cfg.Weapons[Study] != Rope { | |
return false | |
} | |
return !isMan(cfg.People[Study]) | |
} | |
func clue5(cfg *Configuration) bool { | |
return cfg.People[LivingRoom] == John || cfg.People[LivingRoom] == George | |
} | |
func clue6(cfg *Configuration) bool { | |
return cfg.Weapons[DiningRoom] != Knife | |
} | |
func clue7(cfg *Configuration) bool { | |
return cfg.People[Study] != Yolanda && cfg.People[Pantry] != Yolanda | |
} | |
func clue8(cfg *Configuration) bool { | |
firearmRoom := indexOf(cfg.Weapons, Firearm) | |
return cfg.People[firearmRoom] == George | |
} | |
func clue9(cfg *Configuration) bool { | |
return cfg.Weapons[Pantry] == Gas | |
} | |
func isMan(person int) bool { | |
return person < 3 | |
} | |
func indexOf(l []int, x int) int { | |
for i, y := range l { | |
if y == x { | |
return i | |
} | |
} | |
panic("unreachable") | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment