Skip to content

Commit

Permalink
day 15
Browse files Browse the repository at this point in the history
  • Loading branch information
gamersi committed Dec 15, 2024
1 parent 794fbf9 commit a5dd84f
Show file tree
Hide file tree
Showing 4 changed files with 298 additions and 0 deletions.
79 changes: 79 additions & 0 deletions day15p1/solution.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package day15p1

import (
"io"

"aoc/utils"
)

var directions = map[rune]utils.Point{
'v': {X: 0, Y: 1},
'^': {X: 0, Y: -1},
'>': {X: 1, Y: 0},
'<': {X: -1, Y: 0},
}

func Solve(r io.Reader) any {
lines := utils.ReadLines(r)
linesUntilNewline := 0
for i, line := range lines {
if line == "" {
linesUntilNewline = i
break
}
}
board := make([][]rune, linesUntilNewline)
boardMode := true
moveString := ""

room := make(map[utils.Point]rune)
robotPos := utils.Point{X: -1, Y: -1}

for i, line := range lines {
if line == "" {
boardMode = false
continue
}
if boardMode {
board[i] = []rune(line)
for j, r := range board[i] {
room[utils.Point{X: j, Y: i}] = r
if r == '@' {
robotPos.X = j
robotPos.Y = i
}
}
} else {
moveString += line
}
}

for _, instruction := range moveString {
dir := directions[instruction]
robotPos, _ = move(robotPos, dir, room)
}

sum := 0
for p, r := range room {
if r == 'O' {
sum += p.X + p.Y*100
}
}

return sum
}

func move(pos utils.Point, dir utils.Point, room map[utils.Point]rune) (utils.Point, bool) {
newPos := pos.Add(dir)
switch room[newPos] {
case '#':
return pos, false
case 'O':
_, possible := move(newPos, dir, room)
if !possible {
return pos, false
}
}
room[pos], room[newPos] = '.', room[pos]
return newPos, true
}
53 changes: 53 additions & 0 deletions day15p1/solution_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package day15p1

import (
"strings"
"testing"

"aoc/utils"
)

var testInput = `##########
#..O..O.O#
#......O.#
#.OO..O.O#
#[email protected].#
#O#..O...#
#O..O..O.#
#.OO.O.OO#
#....O...#
##########
<vv>^<v^>v>^vv^v>v<>v^v<v<^vv<<<^><<><>>v<vvv<>^v^>^<<<><<v<<<v^vv^v>^
vvv<<^>^v^^><<>>><>^<<><^vv^^<>vvv<>><^^v>^>vv<>v<<<<v<^v>^<^^>>>^<v<v
><>vv>v^v^<>><>>>><^^>vv>v<^^^>>v^v^<^^>v^^>v^<^v>v<>>v^v^<v>v^^<^^vv<
<<v<^>>^^^^>>>v^<>vvv^><v<<<>^^^vv^<vvv>^>v<^^^^v<>^>vvvv><>>v^<<^^^^^
^><^><>>><>^^<<^^v>>><^<v>^<vv>>v>>>^v><>^v><<<<v>>v<v<v>vvv>^<><<>^><
^>><>^v<><^vvv<^^<><v<<<<<><^v<<<><<<^^<v<^^^><^>>^<v^><<<^>>^v<v^v<v^
>^>>^v>vv>^<<^v<>><<><<v<<v><>v<^vv<<<>^^v^>^^>>><<^v>>v^v><^^>>^<>vv^
<><^^>^^^<><vvvvv^v<v<<>^v<v>v<<^><<><<><<<^^<<<^<<>><<><^^^>^^<>^>v<>
^^>vv<^v^v<vv>^<><v<^v>^^^>>>^^vvv^>vvv<>>>^<^>>>>>^<<^v>^vvv<>^<><<v>
v^^>>><<^^<>>^v^<v^vv<>v^<<>^<^v^v><^<<<><<^<v><v<>vv>>v><v^<vv<>v^<<^`

func TestSolve(t *testing.T) {
tests := []struct {
input string
answer int
}{
{testInput, 10092},
}

if testing.Verbose() {
utils.Verbose = true
}

for _, test := range tests {
r := strings.NewReader(test.input)

result := Solve(r).(int)

if result != test.answer {
t.Errorf("Expected %d, got %d", test.answer, result)
}
}
}
113 changes: 113 additions & 0 deletions day15p2/solution.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package day15p2

import (
"io"

"aoc/utils"
)

var directions = map[rune]utils.Point{
'v': {X: 0, Y: 1},
'^': {X: 0, Y: -1},
'>': {X: 1, Y: 0},
'<': {X: -1, Y: 0},
}

func Solve(r io.Reader) any {
lines := utils.ReadLines(r)
linesUntilNewline := 0
for i, line := range lines {
if line == "" {
linesUntilNewline = i
break
}
}
board := make([][]rune, linesUntilNewline)
boardMode := true
moveString := ""

room := make(map[utils.Point]rune)
robotPos := utils.Point{X: -1, Y: -1}

for i, line := range lines {
if line == "" {
boardMode = false
continue
}
if boardMode {
board[i] = []rune(line)
for j, r := range board[i] {
switch r {
case '@':
room[utils.Point{X: j * 2, Y: i}] = r
room[utils.Point{X: j*2 + 1, Y: i}] = '.'
robotPos.X = j * 2
robotPos.Y = i
case 'O':
room[utils.Point{X: j * 2, Y: i}] = '['
room[utils.Point{X: j*2 + 1, Y: i}] = ']'
default:
room[utils.Point{X: j * 2, Y: i}] = r
room[utils.Point{X: j*2 + 1, Y: i}] = r
}
}
} else {
moveString += line
}
}

for _, instruction := range moveString {
dir := directions[instruction]
if movePossible(robotPos, dir, room) {
robotPos, _ = move(robotPos, dir, room)
}
}

sum := 0
for p, r := range room {
if r == '[' {
sum += p.X + p.Y*100
}
}

return sum
}

func movePossible(pos utils.Point, dir utils.Point, room map[utils.Point]rune) bool {
newPos := pos.Add(dir)
switch room[newPos] {
case '#':
return false
case '[':
if dir.X == 0 {
return movePossible(newPos, dir, room) && movePossible(newPos.Add(utils.Point{X: 1, Y: 0}), dir, room)
}
return movePossible(newPos, dir, room)
case ']':
if dir.X == 0 {
return movePossible(newPos, dir, room) && movePossible(newPos.Add(utils.Point{X: -1, Y: 0}), dir, room)
}
return movePossible(newPos, dir, room)
}
return true
}

func move(pos utils.Point, dir utils.Point, room map[utils.Point]rune) (utils.Point, bool) {
newPos := pos.Add(dir)
switch room[newPos] {
case '#':
return pos, false
case '[':
if dir.X == 0 {
move(newPos.Add(utils.Point{X: 1, Y: 0}), dir, room)
}
move(newPos, dir, room)
case ']':
if dir.X == 0 {
move(newPos.Add(utils.Point{X: -1, Y: 0}), dir, room)
}
move(newPos, dir, room)
}
room[pos], room[newPos] = '.', room[pos]
return newPos, true
}
53 changes: 53 additions & 0 deletions day15p2/solution_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package day15p2

import (
"strings"
"testing"

"aoc/utils"
)

var testInput = `##########
#..O..O.O#
#......O.#
#.OO..O.O#
#[email protected].#
#O#..O...#
#O..O..O.#
#.OO.O.OO#
#....O...#
##########
<vv>^<v^>v>^vv^v>v<>v^v<v<^vv<<<^><<><>>v<vvv<>^v^>^<<<><<v<<<v^vv^v>^
vvv<<^>^v^^><<>>><>^<<><^vv^^<>vvv<>><^^v>^>vv<>v<<<<v<^v>^<^^>>>^<v<v
><>vv>v^v^<>><>>>><^^>vv>v<^^^>>v^v^<^^>v^^>v^<^v>v<>>v^v^<v>v^^<^^vv<
<<v<^>>^^^^>>>v^<>vvv^><v<<<>^^^vv^<vvv>^>v<^^^^v<>^>vvvv><>>v^<<^^^^^
^><^><>>><>^^<<^^v>>><^<v>^<vv>>v>>>^v><>^v><<<<v>>v<v<v>vvv>^<><<>^><
^>><>^v<><^vvv<^^<><v<<<<<><^v<<<><<<^^<v<^^^><^>>^<v^><<<^>>^v<v^v<v^
>^>>^v>vv>^<<^v<>><<><<v<<v><>v<^vv<<<>^^v^>^^>>><<^v>>v^v><^^>>^<>vv^
<><^^>^^^<><vvvvv^v<v<<>^v<v>v<<^><<><<><<<^^<<<^<<>><<><^^^>^^<>^>v<>
^^>vv<^v^v<vv>^<><v<^v>^^^>>>^^vvv^>vvv<>>>^<^>>>>>^<<^v>^vvv<>^<><<v>
v^^>>><<^^<>>^v^<v^vv<>v^<<>^<^v^v><^<<<><<^<v><v<>vv>>v><v^<vv<>v^<<^`

func TestSolve(t *testing.T) {
tests := []struct {
input string
answer int
}{
{testInput, 9021},
}

if testing.Verbose() {
utils.Verbose = true
}

for _, test := range tests {
r := strings.NewReader(test.input)

result := Solve(r).(int)

if result != test.answer {
t.Errorf("Expected %d, got %d", test.answer, result)
}
}
}

0 comments on commit a5dd84f

Please sign in to comment.