day20, receive functions
This commit is contained in:
parent
4974127cef
commit
1d7a0ef7b8
106
day20/modules.go
106
day20/modules.go
|
@ -4,6 +4,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -21,21 +22,49 @@ type Signal struct {
|
||||||
|
|
||||||
type Module interface {
|
type Module interface {
|
||||||
Receive(s Signal) []Signal
|
Receive(s Signal) []Signal
|
||||||
|
Outputs() []string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Modules
|
// Modules
|
||||||
type FlipFlop struct {
|
type FlipFlop struct {
|
||||||
Name string
|
Name string
|
||||||
OutputNames []string
|
OutputNames []string
|
||||||
InOn bool
|
IsOn bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ignores HighPulse
|
||||||
|
// on LowPulse - toggle state and send signal
|
||||||
func (ff *FlipFlop)Receive(s Signal) []Signal {
|
func (ff *FlipFlop)Receive(s Signal) []Signal {
|
||||||
|
if s.PulseType == HighPulse {
|
||||||
return []Signal{}
|
return []Signal{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ff.IsOn = !ff.IsOn
|
||||||
|
outTemplate := Signal{
|
||||||
|
From: ff.Name,
|
||||||
|
}
|
||||||
|
if ff.IsOn {
|
||||||
|
outTemplate.PulseType = HighPulse
|
||||||
|
} else {
|
||||||
|
outTemplate.PulseType = LowPulse
|
||||||
|
}
|
||||||
|
|
||||||
|
result := make([]Signal, len(ff.OutputNames))
|
||||||
|
for i, outName := range ff.OutputNames {
|
||||||
|
out := outTemplate
|
||||||
|
out.To = outName
|
||||||
|
result[i] = out
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ff *FlipFlop)Outputs() []string {
|
||||||
|
return ff.OutputNames
|
||||||
|
}
|
||||||
|
|
||||||
func (ff *FlipFlop)String() string {
|
func (ff *FlipFlop)String() string {
|
||||||
return fmt.Sprintf("[flip-flop '%s' (on: %t) -> %s]", ff.Name, ff.InOn, ff.OutputNames)
|
return fmt.Sprintf("[flip-flop '%s' (on: %t) -> %s]", ff.Name, ff.IsOn, ff.OutputNames)
|
||||||
}
|
}
|
||||||
|
|
||||||
func IsLineFlipFlop(line string) bool {
|
func IsLineFlipFlop(line string) bool {
|
||||||
|
@ -57,8 +86,19 @@ type Broadcast struct {
|
||||||
OutputNames []string
|
OutputNames []string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Broadcast)Receive(s Signal) []Signal {
|
// send same pulse to all outputs
|
||||||
return []Signal{}
|
func (b *Broadcast)Receive(s Signal) (result []Signal) {
|
||||||
|
signalTemplate := Signal{From: "broadcast", PulseType: s.PulseType}
|
||||||
|
for _, out := range b.OutputNames {
|
||||||
|
outSignal := signalTemplate
|
||||||
|
outSignal.To = out
|
||||||
|
result = append(result, outSignal)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Broadcast)Outputs() []string {
|
||||||
|
return b.OutputNames
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Broadcast)String() string {
|
func (b *Broadcast)String() string {
|
||||||
|
@ -83,8 +123,47 @@ type Conjunction struct {
|
||||||
MostRecentPulseFromInputIsHigh map[string]bool
|
MostRecentPulseFromInputIsHigh map[string]bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Conjunction)Receive(s Signal) []Signal {
|
// remembers last signal type from all inputs (initial default is Low)
|
||||||
return []Signal{}
|
// when receiving pulse, first update memory for that input
|
||||||
|
// then if for all inputs remembered is high - send LowPulse
|
||||||
|
// otherwise if some remembers are low - send HighPulse
|
||||||
|
func (c *Conjunction)Receive(s Signal) (result []Signal) {
|
||||||
|
c.MostRecentPulseFromInputIsHigh[s.From] = s.PulseType == HighPulse
|
||||||
|
|
||||||
|
allHigh := true
|
||||||
|
for _, latestImpulseHight := range c.MostRecentPulseFromInputIsHigh {
|
||||||
|
if !latestImpulseHight {
|
||||||
|
allHigh = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
outTemplate := Signal{From: c.Name}
|
||||||
|
if allHigh {
|
||||||
|
outTemplate.PulseType = LowPulse
|
||||||
|
} else {
|
||||||
|
outTemplate.PulseType = HighPulse
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, outName := range c.OutputNames {
|
||||||
|
outSignal := outTemplate
|
||||||
|
outSignal.To = outName
|
||||||
|
result = append(result, outSignal)
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Conjunction)Outputs() []string {
|
||||||
|
return c.OutputNames
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Conjunction)RegisterInputs(allModules map[string]Module) {
|
||||||
|
for name, module := range allModules {
|
||||||
|
if slices.Contains( module.Outputs(), c.Name) {
|
||||||
|
c.MostRecentPulseFromInputIsHigh[name] = false
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Conjunction)String() string {
|
func (c *Conjunction)String() string {
|
||||||
|
@ -103,13 +182,21 @@ func ParseConjunction(line string) (result Conjunction) {
|
||||||
result.Name = matches[1]
|
result.Name = matches[1]
|
||||||
result.OutputNames = strings.Split(matches[2], ", ")
|
result.OutputNames = strings.Split(matches[2], ", ")
|
||||||
|
|
||||||
|
result.MostRecentPulseFromInputIsHigh = map[string]bool{}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
type Button struct {}
|
type Button struct {}
|
||||||
|
|
||||||
func (b *Button)Receive(s Signal) []Signal {
|
func (b *Button)Receive(s Signal) []Signal {
|
||||||
return []Signal{}
|
return []Signal{
|
||||||
|
{ To: "broadcast", From: "button", PulseType: LowPulse },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Button)Outputs() []string {
|
||||||
|
return []string{"broadcast"}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Button)String() string {
|
func (b *Button)String() string {
|
||||||
|
@ -119,9 +206,14 @@ func (b *Button)String() string {
|
||||||
type Output struct {}
|
type Output struct {}
|
||||||
|
|
||||||
func (o *Output)Receive(s Signal) []Signal {
|
func (o *Output)Receive(s Signal) []Signal {
|
||||||
|
log.Print("Outut received signal: ", s)
|
||||||
return []Signal{}
|
return []Signal{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (o *Output)Outputs() []string {
|
||||||
|
return []string{}
|
||||||
|
}
|
||||||
|
|
||||||
func (o *Output)String() string {
|
func (o *Output)String() string {
|
||||||
return "[output]"
|
return "[output]"
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,5 +48,14 @@ func TestReadManyModules(t *testing.T) {
|
||||||
filename2 := "example2"
|
filename2 := "example2"
|
||||||
modules2 := ReadModules(filename2)
|
modules2 := ReadModules(filename2)
|
||||||
t.Logf("> read example2:\n%+v", modules2)
|
t.Logf("> read example2:\n%+v", modules2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestConjunctionRegisterInputs(t *testing.T) {
|
||||||
|
filename := "example2"
|
||||||
|
modules := ReadModules(filename)
|
||||||
|
|
||||||
|
conjunctionInv := modules["inv"].(*Conjunction)
|
||||||
|
conjunctionInv.RegisterInputs(modules)
|
||||||
|
|
||||||
|
t.Logf("after registering inputs on $inv : %+v", conjunctionInv.MostRecentPulseFromInputIsHigh)
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,3 +33,5 @@ have file with `_test.go` and `func Test...(t *testing.T) {}` name
|
||||||
#+begin_src bash
|
#+begin_src bash
|
||||||
go test sunshine.industries/aoc2023/day20 -v -run TestParseFlipFlop
|
go test sunshine.industries/aoc2023/day20 -v -run TestParseFlipFlop
|
||||||
#+end_src
|
#+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.
|
||||||
|
|
Loading…
Reference in New Issue