diff --git a/day8/input b/day8/input new file mode 100644 index 0000000..db567c3 --- /dev/null +++ b/day8/input @@ -0,0 +1,50 @@ +..f........................8...................... +G............8..u................................. +........G...p..................................... +......d.....................n..................... +.................................................. +.....................................K............ +..................F...8.n...B.K................... +....b.........8..u................................ +...............F.p.......B.............4.....5.... +....f..d..U.........................c............. +...........U.....d.n.u.0................5......... +...Y.......f..........................5........... +..........................u.....d.....e.........4. +..F...p.............v........n.................... +....s.............0............................... +...US.s....g.....D..........................4..... +......wG...............S.......................... +.............................B.....e.............. +.........w.........................A.............. +.............9w.g..........................4...... +U....9..g.....v.....P....D.....f.K................ +.s.............0..9........pP..........5.......... +..9s...................P.......................... +.............b..................0.....A..2....e... +....................b.....V..v.................... +.......7........B......................A.......... +..................D6...V....q..................... +...v............D....PV........................... +.........Y...........g.......................e..y. +.......SW......V..7....................c.......... +.......bY7.....................N........A......... +.....................q.N..........y............... +........................N.........c............... +.................................................. +.........C..7..................q........2......... +............................N...q................. +...W......C3...Q................a1.........y...... +.......W.......................3......2........... +........3...........6.............1............... +....3............C.1....................k......... +E..................................a.....c........ +.............................................w.... +..S.......................Q..........2......k..... +......................C....6.......Q......ak...... +.................................................. +.................E.............a1............y.... +W..........E...................................... +......E...........6...........Q................... +...........................k...................... +.................................................. diff --git a/day8/main.go b/day8/main.go new file mode 100644 index 0000000..f2f923e --- /dev/null +++ b/day8/main.go @@ -0,0 +1,122 @@ +package main + +import ( + "fmt" + + "git.mstar.dev/mstar/aoc24/util" + "git.mstar.dev/mstar/goutils/sliceutils" +) + +type Vec struct { + X, Y int +} + +type Sender struct { + Pos Vec + Type rune +} + +// Vec from v to o +func (v Vec) Diff(o Vec) Vec { + return Vec{o.X - v.X, o.Y - v.Y} +} + +func (v Vec) Add(o Vec) Vec { + return Vec{v.X + o.X, v.Y + o.Y} +} + +func (v Vec) Invert() Vec { + return Vec{v.X * -1, v.Y * -1} +} + +func getSendersFromLines(lines []string) (senderMap map[rune][]Sender) { + senderMap = map[rune][]Sender{} + for iy, line := range lines { + for ix, char := range line { + if char != '.' { + senderMap[char] = append(senderMap[char], Sender{Vec{ix, iy}, char}) + } + } + } + return +} + +func visualise(allSenders map[rune][]Sender, signals []Vec, size Vec) string { + area := [][]rune{} + for range size.Y { + axis := []rune{} + for range size.X { + axis = append(axis, '.') + } + area = append(area, axis) + } + + for _, senders := range allSenders { + for _, sender := range senders { + area[sender.Pos.Y][sender.Pos.X] = sender.Type + } + } + for _, signal := range signals { + area[signal.Y][signal.X] = '#' + } + lines := sliceutils.Map(area, func(t []rune) string { return string(t) }) + return sliceutils.Compact(lines, func(acc, next string) string { return acc + "\n" + next }) +} + +func posInBounds(pos, bounds Vec) bool { + return pos.X < bounds.X && pos.X >= 0 && pos.Y < bounds.Y && pos.Y >= 0 +} + +func generateSignalPositions2(sender1, sender2 Sender, size Vec) (positions []Vec) { + diff := sender1.Pos.Diff(sender2.Pos) + invertedDiff := diff.Invert() + positions = append(positions, sender1.Pos, sender2.Pos) + for nextPost := sender1.Pos.Add(diff); posInBounds(nextPost, size); nextPost = nextPost.Add(diff) { + positions = append(positions, nextPost) + } + for nextPost := sender1.Pos.Add(invertedDiff); posInBounds(nextPost, size); nextPost = nextPost.Add(invertedDiff) { + positions = append(positions, nextPost) + } + return +} + +func main() { + inputLines := util.FileContentToNonEmptyLines(util.LoadFileFromArgs()) + allSenders := getSendersFromLines(inputLines) + size := Vec{len(inputLines[0]), len(inputLines)} + + signalPositions := []Vec{} + for _, senders := range allSenders { + passedSenders := []Sender{senders[0]} + for _, sender := range senders[1:] { + for _, checked := range passedSenders { + diff := sender.Pos.Diff(checked.Pos) + signalPositions = append(signalPositions, sender.Pos.Add(diff.Invert())) + signalPositions = append(signalPositions, checked.Pos.Add(diff)) + } + passedSenders = append(passedSenders, sender) + } + } + signalPositions = sliceutils.Filter(signalPositions, func(t Vec) bool { + return t.X < size.X && t.X >= 0 && t.Y < size.Y && t.Y >= 0 + }) + signalPositions = sliceutils.RemoveDuplicate(signalPositions) + // fmt.Printf("Size: %v\n", size) + + fmt.Printf("Task 1: %d\n", len(signalPositions)) + signals2 := []Vec{} + for _, senders := range allSenders { + passedSenders := []Sender{senders[0]} + for _, sender := range senders[1:] { + for _, checked := range passedSenders { + signals2 = append(signals2, generateSignalPositions2(sender, checked, size)...) + } + passedSenders = append(passedSenders, sender) + } + } + signals2 = sliceutils.Filter(signals2, func(t Vec) bool { + return t.X < size.X && t.X >= 0 && t.Y < size.Y && t.Y >= 0 + }) + signals2 = sliceutils.RemoveDuplicate(signals2) + fmt.Printf("Task 2: %d\n", len(signals2)) +} diff --git a/day8/sample b/day8/sample new file mode 100644 index 0000000..78a1e91 --- /dev/null +++ b/day8/sample @@ -0,0 +1,12 @@ +............ +........0... +.....0...... +.......0.... +....0....... +......A..... +............ +............ +........A... +.........A.. +............ +............