diff --git a/day20/modules.go b/day20/modules.go index ede91a6..6aaffe1 100644 --- a/day20/modules.go +++ b/day20/modules.go @@ -28,6 +28,7 @@ type Module interface { Receive(s Signal) []Signal Outputs() []string StateSnapshot() string + MermaidFlow() string } // Modules @@ -76,6 +77,14 @@ func (ff *FlipFlop)StateSnapshot() string { return ff.String() } +func (ff *FlipFlop)MermaidFlow() string { + result := "\n" + for _, toName := range ff.OutputNames { + result += fmt.Sprintf("%s --> %s\n", ff.Name, toName) + } + return result +} + func IsLineFlipFlop(line string) bool { return strings.HasPrefix(line, "%") } @@ -117,6 +126,14 @@ func (b *Broadcast)StateSnapshot() string { return b.String() } +func (b *Broadcast)MermaidFlow() string { + result := "\n" + for _, toName := range b.OutputNames { + result += fmt.Sprintf("%s --> %s\n", "broadcast", toName) + } + return result +} + func IsLineBroadcast(line string) bool { return strings.HasPrefix(line, "broadcaster") } @@ -186,6 +203,15 @@ func (c *Conjunction)StateSnapshot() string { return fmt.Sprintf("[conjunction '%s' -> %+v]", c.Name, c.MostRecentPulseFromInputIsHigh) } +func (c *Conjunction)MermaidFlow() string { + result := "\n" + for _, toName := range c.OutputNames { + result += fmt.Sprintf("%s --> %s\n", c.Name, toName) + } + return result + +} + func IsLineConjunction(line string) bool { return strings.HasPrefix(line, "&") } @@ -223,6 +249,10 @@ func (b *Button)StateSnapshot() string { return b.String() } +func (b *Button)MermaidFlow() string { + return "button --> broadcast\n" +} + type Output struct {} func (o *Output)Receive(s Signal) []Signal { @@ -241,3 +271,7 @@ func (o *Output)String() string { func (o *Output)StateSnapshot() string { return o.String() } + +func (o *Output)MermaidFlow() string { + return "" +} diff --git a/day20/my-mermaid.mmd b/day20/my-mermaid.mmd new file mode 100644 index 0000000..7050e12 --- /dev/null +++ b/day20/my-mermaid.mmd @@ -0,0 +1,170 @@ +flowchart LR + +zd --> ln +zd --> gf + +vz --> cr +vz --> vc + +ch --> db +ch --> mc + +qm --> gm + +cc --> nn + +qk --> vc + +sr --> gf +sr --> vl + +lr --> sb + +hv --> lr + +cl --> qx +cl --> bf + +xm --> db + +sf --> bp + +tj --> lc +tj --> gf + +rz --> qx +rz --> cv + +vc --> lr +vc --> hd +vc --> ks +vc --> qn +vc --> gx +vc --> nh +vc --> hv + +bf --> qx +bf --> pf + +jd --> qx +jd --> vm + +ds --> cc + +vm --> cl + +ff --> pl + +th --> rx + +gm --> tj +gm --> gf + +fj --> zd + +mc --> ds +mc --> db + +ks --> vz +button --> broadcast + +cv --> xz + +kt --> qx +kt --> rz + +qj --> xm +qj --> db + +bx --> qx +bx --> qp + +fn --> pr +fn --> gf + +qp --> cb +qp --> qx + +cd --> pm +cd --> vc + +nh --> hv + +pl --> sf +pl --> db + +qq --> qm +qq --> gf + +xf --> th + +zl --> th + +pf --> qx + +qn --> th + +jz --> qj +jz --> db + +pr --> gf + +vl --> gf +vl --> fj + +sb --> ks +sb --> vc + +cr --> gx +cr --> vc + +lc --> gf +lc --> fn + +xn --> th + +nn --> ff +nn --> db + +ln --> gf +ln --> qq + +pm --> vc +pm --> qk + +xz --> jd + +gx --> cd + +broadcast --> sr +broadcast --> ch +broadcast --> hd +broadcast --> bx + +qx --> cb +qx --> cv +qx --> bx +qx --> xz +qx --> vm +qx --> zl + +db --> ff +db --> ds +db --> sf +db --> ch +db --> cc +db --> xf + +cb --> kt + +bp --> db +bp --> jz + +gf --> fj +gf --> qm +gf --> xn +gf --> sr + +hd --> vc +hd --> nh + diff --git a/day20/my-mermaid.mmd.svg b/day20/my-mermaid.mmd.svg new file mode 100644 index 0000000..d0e6aee --- /dev/null +++ b/day20/my-mermaid.mmd.svg @@ -0,0 +1 @@ +
cc
nn
xz
jd
qq
qm
gf
ln
bp
db
jz
cb
kt
rz
qx
cv
ks
vz
gx
cd
cr
vc
ch
mc
ds
hv
lr
pm
qk
hd
qn
nh
gm
xm
sb
tj
lc
vm
qj
bf
pf
broadcast
sr
bx
th
rx
fn
qp
pr
vl
fj
ff
pl
sf
xf
button
zd
zl
xn
cl
\ No newline at end of file diff --git a/day20/notes.org b/day20/notes.org index 7846847..2b0717a 100644 --- a/day20/notes.org +++ b/day20/notes.org @@ -15,10 +15,10 @@ we will take snapshot of state, String() repr of all executors should be enough, and save amount of signals sent so far * also, i suppose i'd want to have entry points for fiddling with single executors to be test cases. * modules to implement -** TODO Broadcast -** TODO Flip-Flop -** TODO Conjunction -** TODO Button +** DONE Broadcast +** DONE Flip-Flop +** DONE Conjunction +** DONE Button * i guess each module could test if string is it's a representation of this type and would be able to parse it? into it's own struct? well, those are just functions, since only methods are associated, so ok @@ -35,3 +35,35 @@ go test sunshine.industries/aoc2023/day20 -v -run TestParseFlipFlop #+end_src * yikes. if i don't know the 'inputs' to the conjunction, don't know how to check for 'all high' let's add registering after the map is read. +* well. for part 2 brute force doesn't work. +how could i examine inputs to the 'rx' to see when it will receive 'low'? + +i suppose inputs could be on prime cycles, which would align to all required values only on a very big step? + +let's do some kind of visualiztion? + +how would i do graphql or mermaidjs? + +flowchard in mermaid should be it + +go run . > day20/my-mermaid.mmd +* so, looking at the thingy. +rx is produced by &th +which has inputs of + 11:&xn -> th + 14:&qn -> th + 16:&xf -> th + 32:&zl -> th + + +for rx to receive a low pulse. +&th should receive High Pulse, while all other inputs alse remembered as high. + +this is not too easy. +but first let's check if loops over +- xn +- qn +- xh +- zl + +are manageable. diff --git a/day20/propagation_test.go b/day20/propagation_test.go index 414a9fc..1d8e680 100644 --- a/day20/propagation_test.go +++ b/day20/propagation_test.go @@ -10,7 +10,7 @@ func TestPropagateButtonPressExample1(t *testing.T) { modules := ReadModules(filename) t.Log("got modules:\n", modules) - low, high := PropagateButtonPress(modules) + low, high := PropagateButtonPress(modules, 0) t.Logf("got low %d and high %d\n", low, high) t.Log("modules after single button press:\n", modules) @@ -26,7 +26,7 @@ func TestPropagateButtonPressExample2(t *testing.T) { t.Log("got modules:\n", modules) InitStuffs(modules) - low, high := PropagateButtonPress(modules) + low, high := PropagateButtonPress(modules, 0) t.Logf("got low %d and high %d\n", low, high) t.Log("modules after single button press:\n", modules) @@ -44,7 +44,7 @@ func TestPropagateButtonPressExample2FourSteps(t *testing.T) { initialModulesState := ModulesState(modules) - low, high := PropagateButtonPress(modules) + low, high := PropagateButtonPress(modules, 0) t.Logf("got low %d and high %d\n", low, high) t.Log("#1 button press:\n", modules) success := low == 4 && high == 4 @@ -52,7 +52,7 @@ func TestPropagateButtonPressExample2FourSteps(t *testing.T) { t.Errorf("expected low 4 got %d, high 4 got %d", low, high) } - low, high = PropagateButtonPress(modules) + low, high = PropagateButtonPress(modules, 0) t.Logf("got low %d and high %d\n", low, high) t.Log("#2 button press:\n", modules) success = low == 4 && high == 2 @@ -64,7 +64,7 @@ func TestPropagateButtonPressExample2FourSteps(t *testing.T) { t.Error("initial state should be different from second") } - low, high = PropagateButtonPress(modules) + low, high = PropagateButtonPress(modules, 0) t.Logf("got low %d and high %d\n", low, high) t.Log("#3 button press:\n", modules) success = low == 5 && high == 3 @@ -76,7 +76,7 @@ func TestPropagateButtonPressExample2FourSteps(t *testing.T) { t.Error("initial state should be different from third") } - low, high = PropagateButtonPress(modules) + low, high = PropagateButtonPress(modules, 0) t.Logf("got low %d and high %d\n", low, high) t.Log("#4 button press:\n", modules) success = low == 4 && high == 2 diff --git a/day20/pulsePropagation.go b/day20/pulsePropagation.go index 33bad91..652ab20 100644 --- a/day20/pulsePropagation.go +++ b/day20/pulsePropagation.go @@ -8,16 +8,19 @@ import ( ) func Run() int { - fmt.Println("hello from dya 20") + // fmt.Println("hello from dya 20") filename := "day20/input" modules := ReadModules(filename) InitStuffs(modules) log.Print("got modules:\n", modules) - low, high := Count10000ButtonPresses(modules) + var low, high int + // low, high = Count10000ButtonPresses(modules) log.Printf("got low %d and high %d\n", low, high) + fmt.Println(AllMermaidFlowChard(modules)) + return low * high } @@ -35,10 +38,13 @@ func Count10000ButtonPresses(modules map[string]Module) (lowSignalsCount, highSi // for now let's just print the info on loop for i := 0; i < count; i++ { - stepLow, stepHigh := PropagateButtonPress(modules) + if i % 10000 == 0 { + log.Println("done button presses: ", i) + } + stepLow, stepHigh := PropagateButtonPress(modules, i) lowSignalsCount += stepLow highSignalsCount += stepHigh - log.Printf("after step %d low is %d and high is %d", i, lowSignalsCount, highSignalsCount) + // log.Printf("after step %d low is %d and high is %d", i, lowSignalsCount, highSignalsCount) state := ModulesState(modules) prevCounts, found := countsAfterState[state] @@ -65,7 +71,7 @@ func Count10000ButtonPresses(modules map[string]Module) (lowSignalsCount, highSi return } -func PropagateButtonPress(modules map[string]Module) (lowSignalsCount, highSignalsCount int) { +func PropagateButtonPress(modules map[string]Module, i int) (lowSignalsCount, highSignalsCount int) { signals := []Signal{{From: "button", To: "broadcast", PulseType: LowPulse}} lowSignalsCount += 1 @@ -73,11 +79,14 @@ func PropagateButtonPress(modules map[string]Module) (lowSignalsCount, highSigna curSignal := signals[0] signals = signals[1:] - log.Printf("%s -%s-> %s", curSignal.From, curSignal.PulseType, curSignal.To) + // log.Printf("%s -%s-> %s", curSignal.From, curSignal.PulseType, curSignal.To) receivingModule, found := modules[curSignal.To] if !found { - log.Print(fmt.Sprintf("signal %+v can't find it's recepient\n", curSignal)) + // log.Print(fmt.Sprintf("signal %+v can't find it's recepient\n", curSignal)) + if curSignal.To == "rx" && curSignal.PulseType == LowPulse { + panic(fmt.Sprintf("getting low signal to rx, on step %d", i)) + } continue } @@ -153,3 +162,12 @@ func ModulesState(allModules map[string]Module) string { return fmt.Sprint(states) } + +func AllMermaidFlowChard(allModules map[string]Module) (result string) { + result = "flowchart LR\n" + for _, module := range allModules { + result += module.MermaidFlow() + } + + return +}