day20: whelp.

This commit is contained in:
efim 2023-12-20 11:14:45 +00:00
parent 1e32ec0988
commit 57fdfb01cb
6 changed files with 272 additions and 17 deletions

View File

@ -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 ""
}

170
day20/my-mermaid.mmd Normal file
View File

@ -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

1
day20/my-mermaid.mmd.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 134 KiB

View File

@ -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.

View File

@ -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

View File

@ -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
}