diff --git a/day20/propagation_test.go b/day20/propagation_test.go index f10c952..414a9fc 100644 --- a/day20/propagation_test.go +++ b/day20/propagation_test.go @@ -93,3 +93,13 @@ func TestPropagateButtonPressExample2FourSteps(t *testing.T) { } } + +func TestExample1TheQuestion(t *testing.T) { + filename := "example1" + modules := ReadModules(filename) + InitStuffs(modules) + + low, high := Count10000ButtonPresses(modules) + t.Log("got low and high: ", low, high) + t.Log("response is: ", low * high) +} diff --git a/day20/pulsePropagation.go b/day20/pulsePropagation.go index 74015d2..bc0503c 100644 --- a/day20/pulsePropagation.go +++ b/day20/pulsePropagation.go @@ -15,11 +15,54 @@ func Run() int { InitStuffs(modules) log.Print("got modules:\n", modules) - low, high := PropagateButtonPress(modules) + low, high := Count10000ButtonPresses(modules) log.Printf("got low %d and high %d\n", low, high) - log.Print("modules after single button press:\n", modules) - return 0 + return low * high +} + +func Count10000ButtonPresses(modules map[string]Module) (lowSignalsCount, highSignalsCount int) { + count := 10000 + type counts struct { + low, high int + step int + } + countsAfterState := make(map[string]counts) + // after each button press check if reached already known state - cycle is present. + // then calculate amount of signals before the loop - how much was on that previous state. + // then diff - how much added after the loop + + // for now let's just print the info on loop + + for i := 0; i < count; i++ { + stepLow, stepHigh := PropagateButtonPress(modules) + lowSignalsCount += stepLow + highSignalsCount += stepHigh + log.Printf("after step %d low is %d and high is %d", i, lowSignalsCount, highSignalsCount) + state := ModulesState(modules) + + prevCounts, found := countsAfterState[state] + if found { + loopLen := i - prevCounts.step + + log.Printf(">>> found loop. from step %d to step %d. of len %d", + prevCounts.step, i, loopLen) + + multiplication := count / loopLen + + lowCountInCycle := lowSignalsCount - prevCounts.low + highCountInCycle := highSignalsCount - prevCounts.high + + lowSignalsCount = lowCountInCycle * multiplication + highSignalsCount = highCountInCycle * multiplication + + return + } + + countsAfterState[state] = counts{stepLow, stepHigh, i} + } + + return } func PropagateButtonPress(modules map[string]Module) (lowSignalsCount, highSignalsCount int) {