Skip to content

Commit

Permalink
add day 14 solutions and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
scottmckendry committed Dec 15, 2024
1 parent 47f0853 commit 745a5bf
Show file tree
Hide file tree
Showing 5 changed files with 739 additions and 0 deletions.
108 changes: 108 additions & 0 deletions 2024/14p1.odin
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package main

import "core:fmt"
import "core:log"
import "core:math"
import "core:strconv"
import "core:strings"

robot :: struct {
pos, vel: vec2,
}

D14P1 :: proc() {
input_string := #load("inputs/14.txt", string)
lines := strings.split(input_string, "\n", context.temp_allocator)

safety_factor := calculate_safety_factor(lines, vec2{100, 102})
fmt.printf("Safety factor: %d\n", safety_factor)
}

calculate_safety_factor :: proc(lines: []string, bounds: vec2) -> int {
robots := parse_robots(lines)
defer delete(robots)
seconds := 100

for &robot in robots {
apply_robot_velocity(&robot, seconds, bounds)
}

middle_x := bounds.x / 2
middle_y := bounds.y / 2
quadrants: [4]int

for robot in robots {
// Skip robots on the middle lines
if robot.pos.x == middle_x || robot.pos.y == middle_y {
continue
}

if robot.pos.x < middle_x {
if robot.pos.y < middle_y {
quadrants[0] += 1 // top left
} else {
quadrants[1] += 1 // bottom left
}
} else {
if robot.pos.y < middle_y {
quadrants[2] += 1 // top right
} else {
quadrants[3] += 1 // bottom right
}
}
}

log.info(quadrants)
return quadrants[0] * quadrants[1] * quadrants[2] * quadrants[3]
}

parse_robots :: proc(input: []string) -> (robots: [dynamic]robot) {
for line in input {
if line == "" {
continue
}

r := robot{}

pos_and_vel_strs := strings.split(line, " ", context.temp_allocator)
pos_str := strings.split(pos_and_vel_strs[0], "p=", context.temp_allocator)[1]
vel_str := strings.split(pos_and_vel_strs[1], "v=", context.temp_allocator)[1]

pos_parts := strings.split(pos_str, ",", context.temp_allocator)
vel_parts := strings.split(vel_str, ",", context.temp_allocator)

r.pos.x = strconv.atoi(pos_parts[0])
r.pos.y = strconv.atoi(pos_parts[1])
r.vel.x = strconv.atoi(vel_parts[0])
r.vel.y = strconv.atoi(vel_parts[1])

append(&robots, r)
}

return
}

apply_robot_velocity :: proc(r: ^robot, seconds: int, bounds: vec2) {
for _ in 0 ..< seconds {
r.pos.x += r.vel.x
r.pos.y += r.vel.y

// if a wall is hit, teleport to the other side
if r.pos.y < 0 {
diff := math.abs(r.pos.y)
r.pos.y = bounds.y - diff + 1
}
if r.pos.y > bounds.y {
diff := r.pos.y - bounds.y
r.pos.y = diff - 1
}
if r.pos.x < 0 {
diff := math.abs(r.pos.x)
r.pos.x = bounds.x - diff + 1
}
if r.pos.x > bounds.x {
diff := r.pos.x - bounds.x
r.pos.x = diff - 1
}
}
}
45 changes: 45 additions & 0 deletions 2024/14p2.odin
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package main

import "core:fmt"
import "core:strings"

D14P2 :: proc() {
input_string := #load("inputs/14.txt", string)
lines := strings.split(input_string, "\n", context.temp_allocator)

bounds := vec2{100, 102}

robots := parse_robots(lines)
defer delete(robots)
seconds := 200000

seconds = 1
found := false
for !found {
for &robot in robots {
apply_robot_velocity(&robot, 1, bounds)
}

found = check_robots(&robots, bounds)
if found {
break
}
seconds += 1
}

fmt.printf("Seconds: %d\n", seconds)
}

check_robots :: proc(robots: ^[dynamic]robot, bounds: vec2) -> bool {
visited := make(map[vec2]bool)
defer delete(visited)

for &robot in robots {
if visited[robot.pos] {
return false
}

visited[robot.pos] = true
}
return true
}
Loading

0 comments on commit 745a5bf

Please sign in to comment.