package day20 import ( "fmt" "log" "os" "strings" ) func Run() int { fmt.Println("hello from dya 20") filename := "day20/example2" modules := ReadModules(filename) log.Print("got modules:\n", modules) low, high := PropagateButtonPress(modules) log.Printf("got low %d and high %d\n", low, high) log.Print("modules after single button press:\n", modules) return 0 } func PropagateButtonPress(modules map[string]Module) (lowSignalsCount, highSignalsCount int) { signals := []Signal{{From: "button", To: "broadcast", PulseType: LowPulse}} lowSignalsCount += 1 for len(signals) > 0 { curSignal := signals[0] signals = signals[1:] log.Printf("%s -%s-> %s", curSignal.From, curSignal.PulseType, curSignal.To) receivingModule, found := modules[curSignal.To] if !found { panic(fmt.Sprintf("signal %+v can't find it's recepient\n", curSignal)) } newSignals := receivingModule.Receive(curSignal) // all newSignals will have same type newSignalsAmount := len(newSignals) if newSignalsAmount > 0 { signals = append(signals, newSignals...) someNewSignal := newSignals[0] if someNewSignal.PulseType == HighPulse { highSignalsCount += newSignalsAmount } else { lowSignalsCount += newSignalsAmount } } } return } // process sends single `low pulse` directly to "broadcast" func ReadModules(filename string) map[string]Module { result := make(map[string]Module) bytes, err := os.ReadFile(filename) if err != nil { panic(fmt.Sprint("error reading file: ", filename)) } text := strings.TrimSpace(string(bytes)) for _, line := range strings.Split(text, "\n") { switch { case IsLineBroadcast(line): parsed := ParseBroadcast(line) result["broadcast"] = &parsed case IsLineFlipFlop(line): parsed := ParseFlipFlop(line) result[parsed.Name] = &parsed case IsLineConjunction(line): parsed := ParseConjunction(line) result[parsed.Name] = &parsed } log.Println(line) } buttonModule := Button{} result["button"] = &buttonModule outputModule := Output{} result["output"] = &outputModule return result } func InitStuffs(allModules map[string]Module) { for _, module := range allModules { if conjunction, ok := module.(*Conjunction); ok { conjunction.RegisterInputs(allModules) } } }