package main import ( "bufio" "fmt" "os" "strings" ) // Rule ... type Rule struct { Color string Contains map[string]int } func findContainingColors(rules []Rule, target string) []string { found := make(map[string]int) for _, r := range rules { if _, ok := r.Contains[target]; ok { found[r.Color]++ for _, i := range findContainingColors(rules, r.Color) { found[i]++ } } } result := make([]string, 0, len(found)) for i := range found { result = append(result, i) } return result } func findColorsContained(rules []Rule, target string) map[string]int { result := make(map[string]int) for _, r := range rules { if r.Color == target { for color, count := range r.Contains { result[color] += count found := findColorsContained(rules, color) for foundColor, foundCount := range found { result[foundColor] += foundCount * count } } break } } return result } // Task1 ... func Task1(input []Rule) int { return len(findContainingColors(input, "shiny gold")) } // Task2 ... func Task2(input []Rule) int { var result int for _, count := range findColorsContained(input, "shiny gold") { result += count } return result } func main() { input := make([]Rule, 0, 100) file, _ := os.Open("input.txt") scanner := bufio.NewScanner(file) for scanner.Scan() { var color string line := scanner.Text() parts := strings.Split(line, " bags contain ") color = parts[0] parts = strings.Split(parts[1], ", ") rule := Rule{ Color: color, Contains: make(map[string]int), } for _, p := range parts { var c int var a, b string fmt.Sscanf(p, "%d %s %s", &c, &a, &b) rule.Contains[a+" "+b] = c } input = append(input, rule) } file.Close() result := Task1(input) fmt.Printf("Task 1: %d\n", result) result = Task2(input) fmt.Printf("Task 2: %d\n", result) }