mirror of
https://github.com/fredrikr79/advent_of_code.git
synced 2026-01-11 20:03:06 +01:00
2024/9/odin: solve part 1
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
input.txt
|
||||
input
|
||||
1
2024/9/odin/example.txt
Normal file
1
2024/9/odin/example.txt
Normal file
@@ -0,0 +1 @@
|
||||
2333133121414131402
|
||||
BIN
2024/9/odin/main
Executable file
BIN
2024/9/odin/main
Executable file
Binary file not shown.
173
2024/9/odin/main.odin
Normal file
173
2024/9/odin/main.odin
Normal file
@@ -0,0 +1,173 @@
|
||||
package aoc2024day9
|
||||
|
||||
import "core:container/queue"
|
||||
import "core:fmt"
|
||||
import "core:os"
|
||||
import "core:slice"
|
||||
import "core:strconv"
|
||||
import "core:unicode"
|
||||
|
||||
PUZZLE_INPUT_PATH :: "input.txt"
|
||||
EXAMPLE_INPUT_PATH :: "example.txt"
|
||||
|
||||
main :: proc() {
|
||||
path := len(os.args) == 2 ? os.args[1] : PUZZLE_INPUT_PATH
|
||||
input := string(os.read_entire_file_from_filename(path) or_else panic("damn"))
|
||||
|
||||
fmt.println("part 1:", part1(input))
|
||||
fmt.println("part 2:", part2(input))
|
||||
}
|
||||
|
||||
part2 :: proc(input: string) -> int {
|
||||
mem: [dynamic]int
|
||||
defer delete(mem)
|
||||
free: map[int]int // start_index -> free_space_interval_delta
|
||||
defer delete(free)
|
||||
filesizes: map[int]int // fileid -> block_count
|
||||
defer delete(filesizes)
|
||||
|
||||
next_fileid := 0
|
||||
memptr := 0
|
||||
|
||||
for r, i in input {
|
||||
if !unicode.is_digit(r) {continue}
|
||||
d := strconv._digit_value(r)
|
||||
if i % 2 == 0 { // files
|
||||
for j := 0; j < d; j += 1 {
|
||||
append(&mem, next_fileid)
|
||||
memptr += 1
|
||||
filesizes[next_fileid] = j + 1
|
||||
}
|
||||
next_fileid += 1
|
||||
} else { // free
|
||||
for j := 0; j < d; j += 1 {
|
||||
append(&mem, -1)
|
||||
free[memptr - j] = j + 1
|
||||
memptr += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fmt.println(free)
|
||||
// fmt.println(filesizes)
|
||||
|
||||
used: [dynamic]int
|
||||
defer delete(used)
|
||||
|
||||
#reverse for fid, i in mem {
|
||||
if fid < 0 || slice.contains(used[:], fid) {continue}
|
||||
append(&used, fid)
|
||||
move := false
|
||||
size := filesizes[fid]
|
||||
for f, j in mem {
|
||||
if f >= 0 || !(j in free) {continue} // TODO: scary slow
|
||||
t := free[j]
|
||||
if t >= size {
|
||||
move = true
|
||||
for k in 0 ..< size {
|
||||
mem[j + k] = fid
|
||||
}
|
||||
free[j + size] = t - size
|
||||
break
|
||||
}
|
||||
}
|
||||
if move {
|
||||
for k in 0 ..< size {
|
||||
mem[i - k] = -2
|
||||
}
|
||||
}
|
||||
for m in mem {
|
||||
if m < 0 {
|
||||
fmt.print("x")
|
||||
} else {
|
||||
fmt.print(m)
|
||||
}
|
||||
}
|
||||
fmt.println()
|
||||
}
|
||||
|
||||
// for fid := next_fileid - 1; fid > 0; fid -= 1 {
|
||||
// size := filesizes[fid]
|
||||
// memptr -= size
|
||||
// }
|
||||
|
||||
// keys := slice.map_keys(free) or_else panic("damn2")
|
||||
// slice.sort(keys)
|
||||
// ptr := 0
|
||||
// #reverse for fileid, i in mem {
|
||||
// if fileid < 0 {continue}
|
||||
// cur := mem[memptr - 1]
|
||||
// target := filesizes[cur]
|
||||
// for start, j in keys[ptr:] {
|
||||
// delta := free[start]
|
||||
// if delta < target {continue}
|
||||
// end := delta + start
|
||||
// }
|
||||
// }
|
||||
|
||||
// #reverse for fileid, i in mem {
|
||||
// f := queue.peek_front(&free)^
|
||||
// if queue.len(free) <= 0 || f >= len(mem) {break}
|
||||
// if fileid >= 0 {
|
||||
// mem[f] = fileid
|
||||
// queue.pop_front(&free)
|
||||
// }
|
||||
// pop(&mem)
|
||||
// }
|
||||
|
||||
sum := 0
|
||||
for fileid, i in mem {
|
||||
if fileid < 0 {continue}
|
||||
sum += fileid * i
|
||||
}
|
||||
|
||||
return sum
|
||||
}
|
||||
|
||||
part1 :: proc(input: string) -> int {
|
||||
mem: [dynamic]int
|
||||
defer delete(mem)
|
||||
free: queue.Queue(int)
|
||||
queue.init(&free)
|
||||
defer queue.destroy(&free)
|
||||
|
||||
next_fileid := 0
|
||||
memptr := 0
|
||||
|
||||
for r, i in input {
|
||||
if !unicode.is_digit(r) {continue}
|
||||
d := strconv._digit_value(r)
|
||||
if i % 2 == 0 { // files
|
||||
for j := 0; j < d; j += 1 {
|
||||
append(&mem, next_fileid)
|
||||
memptr += 1
|
||||
}
|
||||
next_fileid += 1
|
||||
} else { // free
|
||||
for j := 0; j < d; j += 1 {
|
||||
append(&mem, -1)
|
||||
queue.push_back(&free, memptr)
|
||||
memptr += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#reverse for fileid, i in mem {
|
||||
f := queue.peek_front(&free)^
|
||||
if queue.len(free) <= 0 || f >= len(mem) {break}
|
||||
if fileid >= 0 {
|
||||
mem[f] = fileid
|
||||
queue.pop_front(&free)
|
||||
}
|
||||
pop(&mem)
|
||||
}
|
||||
|
||||
sum := 0
|
||||
for fileid, i in mem {
|
||||
if fileid < 0 {continue}
|
||||
sum += fileid * i
|
||||
// fmt.println(fileid, i)
|
||||
}
|
||||
|
||||
return sum
|
||||
}
|
||||
Reference in New Issue
Block a user