diff options
Diffstat (limited to 'aoc/2024/09')
| -rwxr-xr-x | aoc/2024/09/python.py | 62 | ||||
| -rw-r--r-- | aoc/2024/09/rust/Cargo.lock | 7 | ||||
| -rw-r--r-- | aoc/2024/09/rust/Cargo.toml | 6 | ||||
| -rw-r--r-- | aoc/2024/09/rust/src/main.rs | 100 |
4 files changed, 175 insertions, 0 deletions
diff --git a/aoc/2024/09/python.py b/aoc/2024/09/python.py new file mode 100755 index 0000000..1cf450e --- /dev/null +++ b/aoc/2024/09/python.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 + +from fileinput import input + +disk = list(input())[0].strip() + +id_ = -1 +blocks = [] +tail = 0 +file = True +for c in disk: + blocks.append([tail, tail + int(c), (id_ := id_ + 1) if file else -1]) + tail += int(c) + file = not file + + +def expand(bs): + return [x for a, b, x in sorted(bs) for _ in range(b - a)] + + +def debug(bs): + print("".join(str(b) if b != -1 else "." for b in expand(bs))) + + +# Silver +expanded = expand(blocks) +tail = len(expanded) - 1 +fill = expanded.index(-1) +while fill < tail: + expanded[fill] = expanded[tail] + expanded[tail] = -1 + while expanded[tail] == -1: + tail -= 1 + while expanded[fill] != -1: + fill += 1 +silver = sum(idx * n for idx, n in enumerate(expanded) if n != -1) + + +# Gold +for move in blocks[::-1]: + print(move) + ma, mb, mx = move + if mx == -1: + continue + mlen = mb - ma + for tidx, to in enumerate(blocks): + ta, tb, tx = to + if ta >= ma: + break + if tx != -1: + continue + if (tlen := tb - ta) < mlen: + continue + move[2] = -1 + to[2] = mx + to[1] = ta + mlen + blocks.insert(tidx + 1, [ta + mlen, tb, -1]) + break +gold = sum(idx * n for idx, n in enumerate(expand(blocks)) if n != -1) + +print("silver:", silver) +print("gold:", gold) diff --git a/aoc/2024/09/rust/Cargo.lock b/aoc/2024/09/rust/Cargo.lock new file mode 100644 index 0000000..ac79b17 --- /dev/null +++ b/aoc/2024/09/rust/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "puzzle" +version = "0.1.0" diff --git a/aoc/2024/09/rust/Cargo.toml b/aoc/2024/09/rust/Cargo.toml new file mode 100644 index 0000000..88e7b42 --- /dev/null +++ b/aoc/2024/09/rust/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "puzzle" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/aoc/2024/09/rust/src/main.rs b/aoc/2024/09/rust/src/main.rs new file mode 100644 index 0000000..fa7c021 --- /dev/null +++ b/aoc/2024/09/rust/src/main.rs @@ -0,0 +1,100 @@ +#![feature(iter_array_chunks)] + +use std::io; + +fn main() -> io::Result<()> { + let disk_map = io::stdin() + .lines() + .flatten() + .next() + .unwrap() + .chars() + .map(|c| c as u8 - b'0') + .collect(); + + let silver: usize = silver(&disk_map); + let gold: usize = gold(&disk_map); + println!("silver: {silver}"); + println!("gold: {gold}"); + + return Ok(()); +} + +fn silver(input: &Vec<u8>) -> usize { + let mut blocks = input + .iter() + .chain([0, 0].iter()) // lol + .array_chunks() + .enumerate() + .map(|(n, [&f, &s])| [[Some(n)].repeat(f as usize), [None].repeat(s as usize)]) + .flatten() + .flatten() + .collect::<Vec<_>>(); + + let mut l = 0; + let mut r = blocks.len() - 1; + loop { + while blocks[r].is_none() { + r -= 1; + } + while blocks[l].is_some() { + l += 1; + } + if l >= r { + break; + } + let [left, right] = blocks.get_disjoint_mut([l, r]).unwrap(); + left.replace(right.take().unwrap()); + } + + blocks + .iter() + .enumerate() + .map(|(n, id)| n * id.unwrap_or_default()) + .sum() +} + +fn gold(input: &Vec<u8>) -> usize { + let mut blocks = input + .iter() + .chain([0, 0].iter()) // lol + .array_chunks() + .enumerate() + .map(|(n, [&f, &s])| [(Some(n), f as usize), (None, s as usize)]) + .flatten() + .collect::<Vec<_>>(); + + let mut r = blocks.len(); + while r > 0 { + r -= 1; + let (Some(_), f) = blocks[r] else { + continue; + }; + + // find some empty space and maybe split + let Some(l) = blocks.iter().position(|b| b.0.is_none() && b.1 >= f) else { + continue; + }; + if l > r { + continue; + }; + + let (_, s) = &mut blocks[l]; + + let diff = *s - f; + if diff > 0 { + *s = f; + blocks.insert(l + 1, (None, diff)); + r += 1; + } + blocks.swap(l, r); + } + + blocks + .iter() + .map(|&(id, n)| [id].repeat(n)) + .flatten() + .enumerate() + .map(|(n, id)| n * id.unwrap_or_default()) + .sum() +} |
