This commit is contained in:
Hugo Mårdbrink 2025-10-06 23:35:38 +02:00
parent 34bd604d16
commit 8acee0934c

151
d12/main.odin Normal file
View file

@ -0,0 +1,151 @@
package main
import "core:unicode/utf8"
import "core:math"
import "core:slice"
import "core:strconv"
import "core:strings"
import "core:bytes"
import "core:fmt"
import "core:os"
import "../util"
Type :: enum {
East,
North,
West,
South,
Left,
Right,
Forward
}
Instruction :: struct {
type: Type,
units: int,
}
part_1 :: proc(lines: []string) {
result := 0
instructions := slice.mapper(lines, proc(line: string) -> (instruction: Instruction) {
switch line[0] {
case 'N': instruction.type = .North
case 'S': instruction.type = .South
case 'E': instruction.type = .East
case 'W': instruction.type = .West
case 'L': instruction.type = .Left
case 'R': instruction.type = .Right
case 'F': instruction.type = .Forward
}
ok: bool
instruction.units, ok = strconv.parse_int(line[1:]); assert(ok)
return instruction
})
direction := Type.East
location := [2]int{}
for instruction in instructions {
switch instruction.type {
case .North: location.y += instruction.units
case .South: location.y -= instruction.units
case .East: location.x += instruction.units
case .West: location.x -= instruction.units
case .Left:
turn_units := instruction.units / 90
direction_int := (int(direction) + turn_units) % 4
direction = Type(direction_int)
case .Right:
turn_units := instruction.units / 90
direction_int := (int(direction) - turn_units + 4) % 4
direction = Type(direction_int)
case .Forward:
#partial switch direction {
case .North: location.y += instruction.units
case .South: location.y -= instruction.units
case .East: location.x += instruction.units
case .West: location.x -= instruction.units
}
}
}
result = abs(location.x) + abs(location.y)
fmt.printfln("Part 1: %d", result)
}
part_2 :: proc(lines: []string) {
result := 0
instructions := slice.mapper(lines, proc(line: string) -> (instruction: Instruction) {
switch line[0] {
case 'N': instruction.type = .North
case 'S': instruction.type = .South
case 'E': instruction.type = .East
case 'W': instruction.type = .West
case 'L': instruction.type = .Left
case 'R': instruction.type = .Right
case 'F': instruction.type = .Forward
}
ok: bool
instruction.units, ok = strconv.parse_int(line[1:]); assert(ok)
return instruction
})
ship_location := [2]int{ 0, 0 }
waypoint_location := [2]int{ 10, 1 }
for instruction in instructions {
switch instruction.type {
case .North: waypoint_location.y += instruction.units
case .South: waypoint_location.y -= instruction.units
case .East: waypoint_location.x += instruction.units
case .West: waypoint_location.x -= instruction.units
case .Left:
turns := instruction.units / 90
for _ in 0..<turns {
x := waypoint_location.x
y := waypoint_location.y
waypoint_location.y = x
waypoint_location.x = -y
}
case .Right:
turns := instruction.units / 90
for _ in 0..<turns {
x := waypoint_location.x
y := waypoint_location.y
waypoint_location.y = -x
waypoint_location.x = y
}
case .Forward:
ship_location.x += instruction.units * waypoint_location.x
ship_location.y += instruction.units * waypoint_location.y
}
}
result = abs(ship_location.x) + abs(ship_location.y)
fmt.printfln("Part 2: %d", result)
}
main :: proc() {
context.allocator = context.temp_allocator
defer free_all(context.temp_allocator)
INPUT :: #load("input.txt", string)
lines := strings.split(INPUT, "\n")
lines = lines[:len(lines)-1]
part_1(lines)
part_2(lines)
}