diff options
| author | mhsn <mail@mhsn.net> | 2026-03-18 21:48:13 +0000 |
|---|---|---|
| committer | mhsn <mail@mhsn.net> | 2026-03-18 21:48:13 +0000 |
| commit | 86bac31392a76da84817eec020d2b84d099b3cc1 (patch) | |
| tree | e2ee52db59b86b914d5b4bcceb19c9b5d899fff4 /aoc/2024/06 | |
| parent | 62fe361fc42dea75deaf7ac31c0ba6ba80e26a9c (diff) | |
| download | puzzles-86bac31392a76da84817eec020d2b84d099b3cc1.tar.gz puzzles-86bac31392a76da84817eec020d2b84d099b3cc1.zip | |
Diffstat (limited to 'aoc/2024/06')
| -rwxr-xr-x | aoc/2024/06/python.py | 57 | ||||
| -rw-r--r-- | aoc/2024/06/rust/Cargo.lock | 7 | ||||
| -rw-r--r-- | aoc/2024/06/rust/Cargo.toml | 4 | ||||
| -rw-r--r-- | aoc/2024/06/rust/src/main.rs | 105 |
4 files changed, 173 insertions, 0 deletions
diff --git a/aoc/2024/06/python.py b/aoc/2024/06/python.py new file mode 100755 index 0000000..52b61d0 --- /dev/null +++ b/aoc/2024/06/python.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python3 + +from fileinput import input + +obstacles = set() +seen = set() + +xmax, ymax = 0, 0 +for idy, line in enumerate(input()): + ymax = max(ymax, idy) + for idx, c in enumerate(line.strip()): + xmax = max(xmax, idx) + match c: + case "^": + pos = complex(idx, idy) + dir = 0 - 1j + case "#": + obstacles.add(complex(idx, idy)) + + +def is_loop(pos, obst): + seen_ = set() + dir = 0 - 1j + while 0 <= pos.real <= xmax and 0 <= pos.imag <= ymax: + if (pos, dir) in seen_: + return True + seen_.add((pos, dir)) + if pos + dir in obstacles or pos + dir == obst: + # Rotate cw + dir *= 1j + continue + pos += dir + return False + + +gold = 0 +for idx in range(xmax + 1): + for idy in range(ymax + 1): + if complex(idx, idy) == pos: + continue + else: + gold += is_loop(pos, complex(idx, idy)) + + +while 0 <= pos.real <= xmax and 0 <= pos.imag <= ymax: + seen.add(pos) + if pos + dir in obstacles: + # Rotate cw + dir *= 1j + continue + pos += dir + + +silver = len(seen) + +print("silver:", silver) +print("gold:", gold) diff --git a/aoc/2024/06/rust/Cargo.lock b/aoc/2024/06/rust/Cargo.lock new file mode 100644 index 0000000..ac79b17 --- /dev/null +++ b/aoc/2024/06/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/06/rust/Cargo.toml b/aoc/2024/06/rust/Cargo.toml new file mode 100644 index 0000000..5a7c59b --- /dev/null +++ b/aoc/2024/06/rust/Cargo.toml @@ -0,0 +1,4 @@ +[package] +name = "puzzle" +version = "0.1.0" +edition = "2021" diff --git a/aoc/2024/06/rust/src/main.rs b/aoc/2024/06/rust/src/main.rs new file mode 100644 index 0000000..ca78bcd --- /dev/null +++ b/aoc/2024/06/rust/src/main.rs @@ -0,0 +1,105 @@ +use std::collections::HashSet; +use std::{collections::HashMap, io}; + +#[derive(Clone)] +enum Cell { + Empty, + Obstacle, +} + +#[derive(Clone)] +enum Direction { + L = 0b1, + R = 0b10, + U = 0b100, + D = 0b1000, +} + +impl Direction { + fn shift(&self, point: (isize, isize)) -> (isize, isize) { + let (x, y) = point; + match self { + Direction::L => (x - 1, y), + Direction::R => (x + 1, y), + Direction::U => (x, y - 1), + Direction::D => (x, y + 1), + } + } + + fn rotate(&self) -> Self { + use Direction::*; + match self { + L => U, + R => D, + U => R, + D => L, + } + } +} + +fn main() -> io::Result<()> { + let mut map = HashMap::new(); + let mut start = None; + io::stdin() + .lines() + .flatten() + .enumerate() + .flat_map(|(y, line)| { + line.chars() + .enumerate() + .map(|(x, ch)| ([x as isize, y as isize], ch)) + .collect::<Vec<_>>() + }) + .for_each(|([x, y], ch)| match ch { + '.' => { + map.insert((x, y), Cell::Empty); + } + '^' => { + map.insert((x, y), Cell::Empty); + start = Some((x, y)) + } + '#' => { + map.insert((x, y), Cell::Obstacle); + } + _ => panic!(), + }); + let start = start.unwrap(); + + let visited = path_len(&map, start.clone()).unwrap(); + let silver: usize = visited.len(); + let gold: usize = visited + .iter() + .filter(|&p| { + let mut map = map.clone(); + map.insert(*p, Cell::Obstacle); + path_len(&map, start.clone()).is_none() + }) + .count(); + println!("silver: {silver}"); + println!("gold: {gold}"); + + return Ok(()); +} + +fn path_len( + map: &HashMap<(isize, isize), Cell>, + mut pos: (isize, isize), +) -> Option<HashSet<(isize, isize)>> { + let mut visited = HashMap::new(); + let mut dir = Direction::U; + + loop { + let before = visited.entry(pos).or_insert(0 as u8); + if *before & dir.clone() as u8 > 0 { + return None; + } + *before |= dir.clone() as u8; + + let ahead = dir.shift(pos); + match map.get(&ahead) { + Some(Cell::Empty) => pos = ahead, + Some(Cell::Obstacle) => dir = dir.rotate(), + None => return Some(visited.into_keys().collect()), + }; + } +} |
