generated from devries/aoc_template
-
Notifications
You must be signed in to change notification settings - Fork 0
/
solution.go
108 lines (89 loc) · 2.19 KB
/
solution.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package day20p2
import (
"fmt"
"io"
"os"
"strings"
"aoc/utils"
)
func Solve(r io.Reader) any {
lines := utils.ReadLines(r)
modules := make(map[string]*module)
for _, ln := range lines {
name, mod := parseLine(ln)
modules[name] = mod
}
// get all sources for modules
for name, mod := range modules {
for _, d := range mod.destinations {
if md, ok := modules[d]; ok {
md.sources = append(md.sources, name)
}
}
}
f, err := os.Create("day20p2/relations.gv")
utils.Check(err, "unable to open visualization file")
defer f.Close()
// write out a graphviz visualization
fmt.Fprintln(f, "digraph G {")
for name, m := range modules {
var shape string
switch m.kind {
case flipflop:
shape = "rect"
case conjunction:
shape = "trapezium"
default:
shape = "circle"
}
fmt.Fprintf(f, " %s [ shape = \"%s\"; ];\n", name, shape)
for _, d := range m.destinations {
fmt.Fprintf(f, " %s -> %s;\n", name, d)
}
}
fmt.Fprintln(f, "}")
// Can deduce that there are 12 bit counters that trigger an and LOW
// and resets the clock. When all ands are low at the same time you get
// your pulse. The counter trip point is when all flip-flops that feed
// into conjunction gate are HIGH, and the ones which receive a signal
// from that AND gate are LOW.
//
// The lSB is next to the button, and the bit order follows the links
// between flip-flops.
val := int64(0b111101011011) // kb
val = utils.Lcm(val, int64(0b111100010111)) // vm
val = utils.Lcm(val, int64(0b111011010101)) // dn
val = utils.Lcm(val, int64(0b111010111001)) // vk
return val
}
type modtype int
const (
flipflop modtype = iota
conjunction
broadcast
)
type module struct {
kind modtype
destinations []string
sources []string
bitnumber int
}
func parseLine(ln string) (string, *module) {
var ret module
var name string
components := strings.Split(ln, " -> ")
ret.destinations = strings.Split(components[1], ", ")
switch components[0][0] {
case '%':
// flip flop
ret.kind = flipflop
name = components[0][1:]
case '&':
ret.kind = conjunction
name = components[0][1:]
default:
ret.kind = broadcast
name = components[0]
}
return name, &ret
}