Skip to content
This repository was archived by the owner on Dec 28, 2024. It is now read-only.

Commit babe72e

Browse files
committed
Add solution day 14 part 1
1 parent 34bef05 commit babe72e

File tree

4 files changed

+135
-2
lines changed

4 files changed

+135
-2
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ automatically rebuilt and redeployed ever time the `common` module or their own
4545

4646
| Day | Solution | Day | Solution |
4747
|-----|----------|-----|----------|
48-
| 01 | ⭐ ⭐ | 14 | |
48+
| 01 | ⭐ ⭐ | 14 | |
4949
| 02 | ⭐ ⭐ | 15 | |
5050
| 03 | ⭐ ⭐ | 16 | |
5151
| 04 | ⭐ ⭐ | 17 | |

common/util/coordinate.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,34 @@ func In2DArray[T any](
1919
return !invalid
2020
}
2121

22+
func (c Coordinate) Add(x int, y int) Coordinate {
23+
return Coordinate{X: c.X + x, Y: c.Y + y}
24+
}
25+
26+
func (c Coordinate) Multiply(x int, y int) Coordinate {
27+
return Coordinate{X: c.X * x, Y: c.Y * y}
28+
}
29+
30+
func (c Coordinate) Modulo(x int, y int) Coordinate {
31+
return Coordinate{X: c.X % x, Y: c.Y % y}
32+
}
33+
34+
func (c Coordinate) PositiveModulo(x int, y int) Coordinate {
35+
// This is similar to how modulo works in Python
36+
// See: https://stackoverflow.com/questions/13794171/how-to-make-the-mod-of-a-negative-number-to-be-positive/13794192
37+
38+
if x < 0 {
39+
x = -x
40+
}
41+
if y < 0 {
42+
y = -y
43+
}
44+
return Coordinate{
45+
X: ((c.X % x) + x) % x,
46+
Y: ((c.Y % y) + y) % y,
47+
}
48+
}
49+
2250
func (c Coordinate) North() Coordinate {
2351
return Coordinate{c.X, c.Y - 1}
2452
}

solutions/day14/main.go

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,55 @@
11
package main
22

33
import (
4+
"fmt"
45
"github.com/terminalnode/adventofcode2024/common"
56
)
67

78
func main() {
8-
common.Setup(14, nil, nil)
9+
common.Setup(14, part1, nil)
10+
}
11+
12+
func part1(
13+
input string,
14+
) string {
15+
return solve(input, 100, 100, 102)
16+
}
17+
18+
func solve(
19+
input string,
20+
seconds int,
21+
maxX int,
22+
maxY int,
23+
) string {
24+
// Lines assume that the board is an uneven number of tiles
25+
horizontalLine := maxY / 2
26+
verticalLine := maxX / 2
27+
28+
robots, err := parseRobots(input)
29+
if err != nil {
30+
return fmt.Sprintf("Failed to parse robots: %v", err)
31+
}
32+
33+
q1, q2, q3, q4 := 0, 0, 0, 0
34+
for _, r := range robots {
35+
move := r.move.Multiply(seconds, seconds)
36+
newPos := r.init.Add(move.X, move.Y).PositiveModulo(maxX+1, maxY+1)
37+
38+
if newPos.X < verticalLine {
39+
if newPos.Y < horizontalLine {
40+
q1++
41+
} else if newPos.Y > horizontalLine {
42+
q2++
43+
}
44+
} else if newPos.X > verticalLine {
45+
if newPos.Y < horizontalLine {
46+
q3++
47+
} else if newPos.Y > horizontalLine {
48+
q4++
49+
}
50+
}
51+
}
52+
53+
safetyFactor := q1 * q2 * q3 * q4
54+
return fmt.Sprintf("After 100 seconds, area has a safety factor of %d", safetyFactor)
955
}

solutions/day14/parse.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package main
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
"github.com/terminalnode/adventofcode2024/common/util"
7+
"regexp"
8+
"strconv"
9+
)
10+
11+
type robot struct {
12+
init util.Coordinate
13+
move util.Coordinate
14+
}
15+
16+
func (r robot) String() string {
17+
return fmt.Sprintf(
18+
"p=%d,%d v=%d,%d",
19+
r.init.X,
20+
r.init.Y,
21+
r.move.X,
22+
r.move.Y,
23+
)
24+
}
25+
26+
var rx = regexp.MustCompile(`p=(-?\d+),(-?\d+) v=(-?\d+),(-?\d+)`)
27+
28+
func parseRobots(
29+
input string,
30+
) ([]robot, error) {
31+
matches := rx.FindAllSubmatch([]byte(input), -1)
32+
robots := make([]robot, len(matches))
33+
34+
if len(robots) == 0 {
35+
return robots, errors.New("input set contains no robots")
36+
}
37+
38+
for i, match := range matches {
39+
if len(match) != 5 {
40+
return robots, fmt.Errorf("expected match to be 5 long, but was %d", len(match))
41+
}
42+
43+
numbers := make([]int, 4)
44+
for j := 0; j < 4; j++ {
45+
n, err := strconv.ParseInt(string(match[j+1]), 10, 0)
46+
if err != nil {
47+
return robots, err
48+
}
49+
numbers[j] = int(n)
50+
}
51+
52+
robots[i] = robot{
53+
init: util.Coordinate{X: numbers[0], Y: numbers[1]},
54+
move: util.Coordinate{X: numbers[2], Y: numbers[3]},
55+
}
56+
}
57+
58+
return robots, nil
59+
}

0 commit comments

Comments
 (0)