summaryrefslogtreecommitdiff
path: root/aoc/2024/09
diff options
context:
space:
mode:
authormhsn <mail@mhsn.net>2026-03-18 21:48:13 +0000
committermhsn <mail@mhsn.net>2026-03-18 21:48:13 +0000
commit86bac31392a76da84817eec020d2b84d099b3cc1 (patch)
treee2ee52db59b86b914d5b4bcceb19c9b5d899fff4 /aoc/2024/09
parent62fe361fc42dea75deaf7ac31c0ba6ba80e26a9c (diff)
downloadpuzzles-master.tar.gz
puzzles-master.zip
add other challenges supportHEADmaster
Diffstat (limited to 'aoc/2024/09')
-rwxr-xr-xaoc/2024/09/python.py62
-rw-r--r--aoc/2024/09/rust/Cargo.lock7
-rw-r--r--aoc/2024/09/rust/Cargo.toml6
-rw-r--r--aoc/2024/09/rust/src/main.rs100
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()
+}