From 7f300d2d0fad07d4c097c9116f96dd797744b388 Mon Sep 17 00:00:00 2001 From: Nyan Date: Sun, 23 Mar 2025 23:40:31 -0400 Subject: [PATCH 1/3] small refactor, added -s switch to show only answer --- go/cmd/zebra/el-garro/main.go | 45 ++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/go/cmd/zebra/el-garro/main.go b/go/cmd/zebra/el-garro/main.go index f55823a..5e96b8d 100644 --- a/go/cmd/zebra/el-garro/main.go +++ b/go/cmd/zebra/el-garro/main.go @@ -2,12 +2,13 @@ package main import ( "fmt" + "os" "time" ) var Logging bool = true -func Solve(initialPopulation int, selectCount int, childrenCount, newRandomCount int, mutationStrenght int, fitnessTarget int) { +func Solve(initialPopulation int, selectCount int, childrenCount int, newRandomCount int, mutationStrenght int, fitnessTarget int) { started := time.Now() population := make([]Candidate, 0, initialPopulation) @@ -35,25 +36,10 @@ func Solve(initialPopulation int, selectCount int, childrenCount, newRandomCount zebraOwner := "" if Logging { - fmt.Print("\nFitness target reached. Best candidate:\n\n") - fmt.Println(" | Color | Country | Pet | Drink | Hobby |") - fmt.Println("---|------------|------------|------------|------------|------------|") + PrintCandidate(population[0]) } - for i, house := range population[0] { - if Logging { - fmt.Printf( - "%02d | %s | %s | %s | %s | %s |\n", - i+1, - StringPad(house.Color, 10), - StringPad(house.Nationality, 10), - StringPad(house.Pet, 10), - StringPad(house.Drink, 10), - StringPad(house.Hobby, 10), - ) - - } - + for _, house := range population[0] { if house.Drink == "water" { waterDrinker = house.Nationality } @@ -86,8 +72,29 @@ func Solve(initialPopulation int, selectCount int, childrenCount, newRandomCount } +func PrintCandidate(candidate Candidate) { + fmt.Print("\nFitness target reached. Best candidate:\n\n") + fmt.Println(" | Color | Country | Pet | Drink | Hobby |") + fmt.Println("---|------------|------------|------------|------------|------------|") + + for i, house := range candidate { + fmt.Printf( + "%02d | %s | %s | %s | %s | %s |\n", + i+1, + StringPad(house.Color, 10), + StringPad(house.Nationality, 10), + StringPad(house.Pet, 10), + StringPad(house.Drink, 10), + StringPad(house.Hobby, 10), + ) + } +} + func main() { - Logging = true + if len(os.Args) == 2 && os.Args[1] == "-s" { + Logging = false + } + initialPopulation := 50000 // Big initial population adds diversity stablePopulation := 2000 From c7258b53db2c92b98e8bab42b651bcf3cc126b6e Mon Sep 17 00:00:00 2001 From: Nyan Date: Mon, 7 Apr 2025 15:41:39 -0400 Subject: [PATCH 2/3] Full rewrite, faster, better, stronger --- go/cmd/zebra/el-garro/creature.go | 266 +++++++++++++++++++++ go/cmd/zebra/el-garro/genetics.go | 266 --------------------- go/cmd/zebra/el-garro/genetics/genetics.go | 69 ++++++ go/cmd/zebra/el-garro/go.mod | 2 +- go/cmd/zebra/el-garro/main.go | 120 +++------- go/cmd/zebra/el-garro/structs.go | 11 - go/cmd/zebra/el-garro/utils.go | 59 ----- 7 files changed, 372 insertions(+), 421 deletions(-) create mode 100644 go/cmd/zebra/el-garro/creature.go delete mode 100644 go/cmd/zebra/el-garro/genetics.go create mode 100644 go/cmd/zebra/el-garro/genetics/genetics.go delete mode 100644 go/cmd/zebra/el-garro/structs.go delete mode 100644 go/cmd/zebra/el-garro/utils.go diff --git a/go/cmd/zebra/el-garro/creature.go b/go/cmd/zebra/el-garro/creature.go new file mode 100644 index 0000000..e05deb5 --- /dev/null +++ b/go/cmd/zebra/el-garro/creature.go @@ -0,0 +1,266 @@ +package main + +import ( + "math/rand" + "zebra/genetics" +) + +type House struct { + Color string + Nationality string + Pet string + Drink string + Hobby string +} + +type ZebraPuzzle struct { + Genes []*House + fitness float64 +} + +func (z *ZebraPuzzle) Fitness() float64 { + if z.fitness != 0 { + return z.fitness + } + + genes := z.Genes + + fitness := 0.0 + houses := len(genes) + + // There are five houses, I shouldn't check this rule but whatever + if houses == 5 { + fitness += 1 + } + + // The Englishman lives in the red house + for i := range houses { + if genes[i].Nationality == "English" { + if genes[i].Color == "Red" { + fitness += 1 + } + + break + } + } + + // The Spaniard owns the dog. + for i := range houses { + if genes[i].Nationality == "Spaniard" { + if genes[i].Pet == "Dog" { + fitness += 1 + } + + break + } + } + + // The person in the green house drinks coffee. + for i := range houses { + if genes[i].Color == "Green" { + if genes[i].Drink == "Coffee" { + fitness += 1 + } + + break + } + } + + // The Ukrainian drinks tea. + for i := range houses { + if genes[i].Nationality == "Ukrainian" { + if genes[i].Drink == "Tea" { + fitness += 1 + } + + break + } + } + + // The green house is immediately to the right of the ivory house. + for i := range houses { + if genes[i].Color == "Green" { + if i != 0 && genes[i-1].Color == "Ivory" { + fitness += 1 + } + break + } + } + + // The snail owner likes to go dancing. + for i := range houses { + if genes[i].Pet == "Snail" { + if genes[i].Hobby == "Dancing" { + fitness += 1 + } + + break + } + } + + // The person in the yellow house is a painter. + for i := range houses { + if genes[i].Color == "Yellow" { + if genes[i].Hobby == "Painting" { + fitness += 1 + } + + break + } + } + + // The person in the middle house drinks milk. + if genes[houses/2].Drink == "Milk" { + fitness += 1 + } + + // The Norwegian lives in the first house. + if genes[0].Nationality == "Norwegian" { + fitness += 1 + } + + // The person who enjoys reading lives in the house next to the person with the fox. + for i := range houses { + if genes[i].Hobby == "Reading" { + if i != 0 && genes[i-1].Pet == "Fox" { + fitness += 1 + } else if i != houses-1 && genes[i+1].Pet == "Fox" { + fitness += 1 + } + + break + } + } + + // The painter's house is next to the house with the horse. + for i := range houses { + if genes[i].Hobby == "Painting" { + if i != 0 && genes[i-1].Pet == "Horse" { + fitness += 1 + } else if i != houses-1 && genes[i+1].Pet == "Horse" { + fitness += 1 + } + + break + } + } + + // The person who plays football drinks orange juice. + for i := range houses { + if genes[i].Hobby == "Football" { + if genes[i].Drink == "Juice" { + fitness += 1 + } + + break + } + } + + // The Japanese person plays chess. + for i := range houses { + if genes[i].Nationality == "Japanese" { + if genes[i].Hobby == "Chess" { + fitness += 1 + } + + break + } + } + + // The Norwegian lives next to the blue house. + for i := range houses { + if genes[i].Nationality == "Norwegian" { + if i != 0 && genes[i-1].Color == "Blue" { + fitness += 1 + } else if i != houses-1 && genes[i+1].Color == "Blue" { + fitness += 1 + } + + break + } + } + + z.fitness = fitness + return fitness +} + +func (z *ZebraPuzzle) New() genetics.Creature { + var colors []string = shuffle([]string{"Red", "Green", "Ivory", "Yellow", "Blue"}) + var nationalities []string = shuffle([]string{"English", "Spaniard", "Ukrainian", "Norwegian", "Japanese"}) + var pets []string = shuffle([]string{"Dog", "Snail", "Fox", "Horse", "Zebra"}) + var drinks []string = shuffle([]string{"Coffee", "Tea", "Milk", "Juice", "Water"}) + var hobbies []string = shuffle([]string{"Dancing", "Painting", "Reading", "Football", "Chess"}) + + genes := make([]*House, 0, 5) + + for i := range len(colors) { + house := House{ + Color: colors[i], + Nationality: nationalities[i], + Pet: pets[i], + Drink: drinks[i], + Hobby: hobbies[i], + } + + genes = append(genes, &house) + } + + return &ZebraPuzzle{Genes: genes} +} + +func (z *ZebraPuzzle) Mutate(strenght float64) { + // Mutation consists swappping 1 random property between 2 random houses + + genes := z.Genes + + for _ = range int(strenght) { + h1 := rand.Intn(len(genes)) + h2 := rand.Intn(len(genes)) + if h1 == h2 { + continue + } + + prop := rand.Intn(5) + + if prop == 0 { + genes[h1].Color, genes[h2].Color = genes[h2].Color, genes[h1].Color + } else if prop == 1 { + genes[h1].Drink, genes[h2].Drink = genes[h2].Drink, genes[h1].Drink + } else if prop == 2 { + genes[h1].Hobby, genes[h2].Hobby = genes[h2].Hobby, genes[h1].Hobby + } else if prop == 3 { + genes[h1].Nationality, genes[h2].Nationality = genes[h2].Nationality, genes[h1].Nationality + } else if prop == 4 { + genes[h1].Pet, genes[h2].Pet = genes[h2].Pet, genes[h1].Pet + } else { + panic("WTF") + } + } +} + +func (z *ZebraPuzzle) Clone() genetics.Creature { + var genes []*House + + for i := range len(z.Genes) { + house := House{ + Color: z.Genes[i].Color, + Nationality: z.Genes[i].Nationality, + Pet: z.Genes[i].Pet, + Drink: z.Genes[i].Drink, + Hobby: z.Genes[i].Hobby, + } + + genes = append(genes, &house) + } + + return &ZebraPuzzle{Genes: genes} +} + +func shuffle[T any](slice []T) []T { + for i := range slice { + j := rand.Intn(i + 1) + slice[i], slice[j] = slice[j], slice[i] + } + + return slice +} diff --git a/go/cmd/zebra/el-garro/genetics.go b/go/cmd/zebra/el-garro/genetics.go deleted file mode 100644 index 3cd15be..0000000 --- a/go/cmd/zebra/el-garro/genetics.go +++ /dev/null @@ -1,266 +0,0 @@ -package main - -import ( - "math/rand" -) - -func GenerateRandom() Candidate { - var colors []string = Shuffle([]string{"red", "green", "ivory", "yellow", "blue"}) - var nationalities []string = Shuffle([]string{"english", "spaniard", "ukrainian", "norwegian", "japanese"}) - var pets []string = Shuffle([]string{"dog", "snail", "fox", "horse", "zebra"}) - var drinks []string = Shuffle([]string{"coffee", "tea", "milk", "juice", "water"}) - var hobbies []string = Shuffle([]string{"dancing", "painting", "reading", "football", "chess"}) - - var result Candidate - - for i := range len(colors) { - house := House{ - Color: colors[i], - Nationality: nationalities[i], - Pet: pets[i], - Drink: drinks[i], - Hobby: hobbies[i], - } - - result = append(result, &house) - } - - return result -} - -func GenerateChild(parent Candidate, mutationStrenght int) Candidate { - var child Candidate - - for i := range len(parent) { - house := House{ - Color: parent[i].Color, - Nationality: parent[i].Nationality, - Pet: parent[i].Pet, - Drink: parent[i].Drink, - Hobby: parent[i].Hobby, - } - - child = append(child, &house) - } - - Mutate(child, mutationStrenght) - return child -} - -func Mutate(candidate Candidate, strenght int) { - for _ = range strenght { - h1 := rand.Intn(len(candidate)) - h2 := rand.Intn(len(candidate)) - if h1 == h2 { - continue - } - - prop := rand.Intn(5) - - if prop == 0 { - candidate[h1].Color, candidate[h2].Color = candidate[h2].Color, candidate[h1].Color - } else if prop == 1 { - candidate[h1].Drink, candidate[h2].Drink = candidate[h2].Drink, candidate[h1].Drink - } else if prop == 2 { - candidate[h1].Hobby, candidate[h2].Hobby = candidate[h2].Hobby, candidate[h1].Hobby - } else if prop == 3 { - candidate[h1].Nationality, candidate[h2].Nationality = candidate[h2].Nationality, candidate[h1].Nationality - } else if prop == 4 { - candidate[h1].Pet, candidate[h2].Pet = candidate[h2].Pet, candidate[h1].Pet - } else { - panic("WTF") - } - } -} - -func Fitness(candidate Candidate) int { - fitness := 0 - houses := len(candidate) - - // There are five houses - if houses == 5 { - fitness += 1 - } - - // The Englishman lives in the red house - for i := range houses { - if candidate[i].Nationality == "english" { - if candidate[i].Color == "red" { - fitness += 1 - } - - break - } - } - - // The Spaniard owns the dog. - for i := range houses { - if candidate[i].Nationality == "spaniard" { - if candidate[i].Pet == "dog" { - fitness += 1 - } - - break - } - } - - // The person in the green house drinks coffee. - for i := range houses { - if candidate[i].Color == "green" { - if candidate[i].Drink == "coffee" { - fitness += 1 - } - - break - } - } - - // The Ukrainian drinks tea. - for i := range houses { - if candidate[i].Nationality == "ukrainian" { - if candidate[i].Drink == "tea" { - fitness += 1 - } - - break - } - } - - // The green house is immediately to the right of the ivory house. - for i := range houses { - if candidate[i].Color == "green" { - if i != 0 && candidate[i-1].Color == "ivory" { - fitness += 1 - } - break - } - } - - // The snail owner likes to go dancing. - for i := range houses { - if candidate[i].Pet == "snail" { - if candidate[i].Hobby == "dancing" { - fitness += 1 - } - - break - } - } - - // The person in the yellow house is a painter. - for i := range houses { - if candidate[i].Color == "yellow" { - if candidate[i].Hobby == "painting" { - fitness += 1 - } - - break - } - } - - // The person in the middle house drinks milk. - if candidate[houses/2].Drink == "milk" { - fitness += 1 - } - - // The Norwegian lives in the first house. - if candidate[0].Nationality == "norwegian" { - fitness += 1 - } - - // The person who enjoys reading lives in the house next to the person with the fox. - for i := range houses { - if candidate[i].Hobby == "reading" { - if i != 0 && candidate[i-1].Pet == "fox" { - fitness += 1 - } else if i != houses-1 && candidate[i+1].Pet == "fox" { - fitness += 1 - } - - break - } - } - - // The painter's house is next to the house with the horse. - for i := range houses { - if candidate[i].Hobby == "painting" { - if i != 0 && candidate[i-1].Pet == "horse" { - fitness += 1 - } else if i != houses-1 && candidate[i+1].Pet == "horse" { - fitness += 1 - } - - break - } - } - - // The person who plays football drinks orange juice. - for i := range houses { - if candidate[i].Hobby == "football" { - if candidate[i].Drink == "juice" { - fitness += 1 - } - - break - } - } - - // The Japanese person plays chess. - for i := range houses { - if candidate[i].Nationality == "japanese" { - if candidate[i].Hobby == "chess" { - fitness += 1 - } - - break - } - } - - // The Norwegian lives next to the blue house. - for i := range houses { - if candidate[i].Nationality == "norwegian" { - if i != 0 && candidate[i-1].Color == "blue" { - fitness += 1 - } else if i != houses-1 && candidate[i+1].Color == "blue" { - fitness += 1 - } - - break - } - } - - return fitness -} - -func Select(population []Candidate, count int) []Candidate { - selected := make([]Candidate, 0, count) - - for _ = range count { - bestFit := -1 - bestItem := -1 - - for i, v := range population { - if v == nil { - continue - } - - if fit := Fitness(v); fit > bestFit { - if Contains(selected, population[i]) { - population[i] = nil - continue - } - - bestFit = fit - bestItem = i - } - } - - if bestItem != -1 { - selected = append(selected, population[bestItem]) - population[bestItem] = nil - } - - } - - return selected -} diff --git a/go/cmd/zebra/el-garro/genetics/genetics.go b/go/cmd/zebra/el-garro/genetics/genetics.go new file mode 100644 index 0000000..abb164c --- /dev/null +++ b/go/cmd/zebra/el-garro/genetics/genetics.go @@ -0,0 +1,69 @@ +package genetics + +import ( + "math/rand" +) + +type Creature interface { + New() Creature + Fitness() float64 + Mutate(strenght float64) + Clone() Creature +} + +type Simulator struct { + Population []Creature + Creature Creature + mutationStrenght float64 + generationNumber int +} + +func (s *Simulator) GetGenerationNumber() int { + return s.generationNumber +} + +func (s *Simulator) Initialize(population int, mutationStrenght float64) { + s.generationNumber = 0 + s.mutationStrenght = mutationStrenght + + s.Population = make([]Creature, 0, population) + + for _ = range population { + s.Population = append(s.Population, s.Creature.New()) + } +} + +func (s *Simulator) Step() { + + // Select + s.shuffle() + mid := len(s.Population) / 2 + for i := range mid { + if s.Population[i].Fitness() < s.Population[i+mid].Fitness() { + s.Population[i] = s.Population[i+mid] + } + + if s.Population[i].Fitness() > s.Population[0].Fitness() { + s.Population[0], s.Population[i] = s.Population[i], s.Population[0] + } + } + + // Clone and Mutate + for i := range mid { + s.Population[i+mid] = s.Population[i].Clone() + s.Population[i+mid].Mutate(s.mutationStrenght) + } + + s.generationNumber++ +} + +func (s *Simulator) GetBestCreature() Creature { + return s.Population[0] +} + +func (s *Simulator) shuffle() { + for i := range s.Population { + j := rand.Intn(i + 1) + s.Population[i], s.Population[j] = s.Population[j], s.Population[i] + } +} diff --git a/go/cmd/zebra/el-garro/go.mod b/go/cmd/zebra/el-garro/go.mod index a3588f9..e99dcd3 100644 --- a/go/cmd/zebra/el-garro/go.mod +++ b/go/cmd/zebra/el-garro/go.mod @@ -1,3 +1,3 @@ module zebra -go 1.23.2 +go 1.24.1 diff --git a/go/cmd/zebra/el-garro/main.go b/go/cmd/zebra/el-garro/main.go index 5e96b8d..f51d7c6 100644 --- a/go/cmd/zebra/el-garro/main.go +++ b/go/cmd/zebra/el-garro/main.go @@ -2,77 +2,44 @@ package main import ( "fmt" - "os" + "strings" "time" + "zebra/genetics" ) -var Logging bool = true - -func Solve(initialPopulation int, selectCount int, childrenCount int, newRandomCount int, mutationStrenght int, fitnessTarget int) { +func Solve(population int, mutationStrenght float64, targetFitness float64) { started := time.Now() - population := make([]Candidate, 0, initialPopulation) - for _ = range initialPopulation { - population = append(population, GenerateRandom()) + simulator := genetics.Simulator{ + Creature: &ZebraPuzzle{}, } - bestFit := 0 - generation := 0 - for { - // The best candidates pass directly to the new generation - population = Select(population, selectCount) - - // Periodic report - if fit := Fitness(population[0]); fit > bestFit || generation%100 == 0 { - bestFit = fit - if Logging { - fmt.Printf("Generation=%07d, BestFitness=%02d, TargetFitness=%02d, TimeElapsed=%v\n", generation, bestFit, fitnessTarget, time.Since(started)) - } - } - - // Found a solution - if bestFit >= fitnessTarget { - waterDrinker := "" - zebraOwner := "" - - if Logging { - PrintCandidate(population[0]) - } + simulator.Initialize(population, mutationStrenght) - for _, house := range population[0] { - if house.Drink == "water" { - waterDrinker = house.Nationality - } - - if house.Pet == "zebra" { - zebraOwner = house.Nationality - } - } - - fmt.Printf("\nResponse: The zebra is owned by the <%s> and the <%s> drinks water", zebraOwner, waterDrinker) - - break - } + for { - // Reproduce and mutate - for i := range len(population) { - for _ = range childrenCount { - population = append(population, GenerateChild(population[i], mutationStrenght)) - } + if simulator.GetGenerationNumber()%100 == 0 || simulator.GetBestCreature().Fitness() >= targetFitness { + fmt.Printf("Generation=%07d, BestFitness=%05.2f, TargetFitness=%05.2f, TimeElapsed=%v\n", + simulator.GetGenerationNumber(), + simulator.GetBestCreature().Fitness(), + targetFitness, + time.Since(started), + ) } - // Add some new random candidates - for _ = range newRandomCount { - population = append(population, GenerateRandom()) + if simulator.GetBestCreature().Fitness() >= targetFitness { + PrintCandidate(simulator.GetBestCreature().(*ZebraPuzzle)) + break } - generation += 1 - + simulator.Step() } } -func PrintCandidate(candidate Candidate) { +func PrintCandidate(c *ZebraPuzzle) { + candidate := c.Genes + fmt.Print("\nFitness target reached. Best candidate:\n\n") fmt.Println(" | Color | Country | Pet | Drink | Hobby |") fmt.Println("---|------------|------------|------------|------------|------------|") @@ -81,42 +48,27 @@ func PrintCandidate(candidate Candidate) { fmt.Printf( "%02d | %s | %s | %s | %s | %s |\n", i+1, - StringPad(house.Color, 10), - StringPad(house.Nationality, 10), - StringPad(house.Pet, 10), - StringPad(house.Drink, 10), - StringPad(house.Hobby, 10), + stringPad(house.Color, 10), + stringPad(house.Nationality, 10), + stringPad(house.Pet, 10), + stringPad(house.Drink, 10), + stringPad(house.Hobby, 10), ) } } func main() { - if len(os.Args) == 2 && os.Args[1] == "-s" { - Logging = false - } + population := 10000 + mutation := 1.0 + targetFitness := 15.0 - initialPopulation := 50000 // Big initial population adds diversity - stablePopulation := 2000 - - selected := int(float64(stablePopulation) * 0.05) // Keep the best 5% of the population - random := int(float64(stablePopulation) * 0.05) // Add diversity with a random 5% - childrenPerParent := int(float64(stablePopulation-selected-random) / float64(selected)) - mutation := 5 - targetFitness := 15 - - if Logging { - fmt.Print( - "\n| Population Breakdown |", - "\n| ----------------------|------------ ", - "\n| Initial Population | ", initialPopulation, - "\n| Stable Population | ", stablePopulation, - "\n| Survivors | ", selected, - "\n| Randomized | ", random, - "\n| Children per Survivor | ", childrenPerParent, - "\n| Mutation amount | ", mutation, - "\n\n", - ) + Solve(population, mutation, targetFitness) +} + +func stringPad(text string, maxlen int) string { + if len(text) >= maxlen { + return text[:maxlen] } - Solve(initialPopulation, selected, childrenPerParent, random, mutation, targetFitness) + return text + strings.Repeat(" ", maxlen-len(text)) } diff --git a/go/cmd/zebra/el-garro/structs.go b/go/cmd/zebra/el-garro/structs.go deleted file mode 100644 index ea5ba30..0000000 --- a/go/cmd/zebra/el-garro/structs.go +++ /dev/null @@ -1,11 +0,0 @@ -package main - -type House struct { - Color string - Nationality string - Pet string - Drink string - Hobby string -} - -type Candidate []*House diff --git a/go/cmd/zebra/el-garro/utils.go b/go/cmd/zebra/el-garro/utils.go deleted file mode 100644 index 63f9d65..0000000 --- a/go/cmd/zebra/el-garro/utils.go +++ /dev/null @@ -1,59 +0,0 @@ -package main - -import ( - "math/rand" - "strings" -) - -func Shuffle(slice []string) []string { - for i := range slice { - j := rand.Intn(i + 1) - slice[i], slice[j] = slice[j], slice[i] - } - - return slice -} - -func StringPad(text string, maxlen int) string { - if len(text) >= maxlen { - return text[:maxlen] - } - - return text + strings.Repeat(" ", maxlen-len(text)) -} - -func IsEqual(c1 Candidate, c2 Candidate) bool { - for i := range len(c1) { - if c1[i].Color != c2[i].Color { - return false - } - - if c1[i].Drink != c2[i].Drink { - return false - } - - if c1[i].Hobby != c2[i].Hobby { - return false - } - - if c1[i].Nationality != c2[i].Nationality { - return false - } - - if c1[i].Pet != c2[i].Pet { - return false - } - } - - return true -} - -func Contains(population []Candidate, candidate Candidate) bool { - for _, v := range population { - if IsEqual(v, candidate) { - return true - } - } - - return false -} From 9f1973d426bd788a295a510f71ca6b43eb015973 Mon Sep 17 00:00:00 2001 From: Nyan Date: Mon, 7 Apr 2025 16:13:53 -0400 Subject: [PATCH 3/3] added flag --- go/cmd/zebra/el-garro/main.go | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/go/cmd/zebra/el-garro/main.go b/go/cmd/zebra/el-garro/main.go index f51d7c6..1d103c2 100644 --- a/go/cmd/zebra/el-garro/main.go +++ b/go/cmd/zebra/el-garro/main.go @@ -2,11 +2,14 @@ package main import ( "fmt" + "os" "strings" "time" "zebra/genetics" ) +var verbose bool = false + func Solve(population int, mutationStrenght float64, targetFitness float64) { started := time.Now() @@ -18,7 +21,7 @@ func Solve(population int, mutationStrenght float64, targetFitness float64) { for { - if simulator.GetGenerationNumber()%100 == 0 || simulator.GetBestCreature().Fitness() >= targetFitness { + if verbose && (simulator.GetGenerationNumber()%100 == 0 || simulator.GetBestCreature().Fitness() >= targetFitness) { fmt.Printf("Generation=%07d, BestFitness=%05.2f, TargetFitness=%05.2f, TimeElapsed=%v\n", simulator.GetGenerationNumber(), simulator.GetBestCreature().Fitness(), @@ -28,7 +31,25 @@ func Solve(population int, mutationStrenght float64, targetFitness float64) { } if simulator.GetBestCreature().Fitness() >= targetFitness { - PrintCandidate(simulator.GetBestCreature().(*ZebraPuzzle)) + if verbose { + PrintCandidate(simulator.GetBestCreature().(*ZebraPuzzle)) + } else { + waterDrinker := "" + zebraOwner := "" + + for _, house := range simulator.GetBestCreature().(*ZebraPuzzle).Genes { + if house.Drink == "Water" { + waterDrinker = house.Nationality + } + + if house.Pet == "Zebra" { + zebraOwner = house.Nationality + } + } + + fmt.Printf("%s %s\n", waterDrinker, zebraOwner) + } + break } @@ -58,6 +79,10 @@ func PrintCandidate(c *ZebraPuzzle) { } func main() { + if len(os.Args) == 2 && os.Args[1] == "-v" { + verbose = true + } + population := 10000 mutation := 1.0 targetFitness := 15.0