From 672c7de41a36dbc77b1da189d6a2edb5ba849eda Mon Sep 17 00:00:00 2001 From: timeshifter Date: Fri, 3 Jul 2026 16:07:25 +0200 Subject: [PATCH] add day 21 --- day21/Cargo.lock | 7 ++ day21/Cargo.toml | 6 ++ day21/example.txt | 8 ++ day21/input.txt | 100 +++++++++++++++++++++++++ day21/src/main.rs | 183 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 304 insertions(+) create mode 100644 day21/Cargo.lock create mode 100644 day21/Cargo.toml create mode 100644 day21/example.txt create mode 100644 day21/input.txt create mode 100644 day21/src/main.rs diff --git a/day21/Cargo.lock b/day21/Cargo.lock new file mode 100644 index 0000000..6dc24b7 --- /dev/null +++ b/day21/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "day21" +version = "0.1.0" diff --git a/day21/Cargo.toml b/day21/Cargo.toml new file mode 100644 index 0000000..b05c438 --- /dev/null +++ b/day21/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "day21" +version = "0.1.0" +edition = "2024" + +[dependencies] diff --git a/day21/example.txt b/day21/example.txt new file mode 100644 index 0000000..865c052 --- /dev/null +++ b/day21/example.txt @@ -0,0 +1,8 @@ +swap position 4 with position 0 +swap letter d with letter b +reverse positions 0 through 4 +rotate left 1 step +move position 1 to position 4 +move position 3 to position 0 +rotate based on position of letter b +rotate based on position of letter d diff --git a/day21/input.txt b/day21/input.txt new file mode 100644 index 0000000..b445817 --- /dev/null +++ b/day21/input.txt @@ -0,0 +1,100 @@ +rotate based on position of letter a +swap letter g with letter d +move position 1 to position 5 +reverse positions 6 through 7 +move position 5 to position 4 +rotate based on position of letter b +reverse positions 6 through 7 +swap letter h with letter f +swap letter e with letter c +reverse positions 0 through 7 +swap position 6 with position 4 +rotate based on position of letter e +move position 2 to position 7 +swap position 6 with position 4 +rotate based on position of letter e +reverse positions 2 through 3 +rotate right 2 steps +swap position 7 with position 1 +move position 1 to position 2 +move position 4 to position 7 +move position 5 to position 0 +swap letter e with letter f +move position 4 to position 7 +reverse positions 1 through 7 +rotate based on position of letter g +move position 7 to position 4 +rotate right 6 steps +rotate based on position of letter g +reverse positions 0 through 5 +reverse positions 0 through 7 +swap letter c with letter f +swap letter h with letter f +rotate right 7 steps +rotate based on position of letter g +rotate based on position of letter c +swap position 1 with position 4 +move position 7 to position 3 +reverse positions 2 through 6 +move position 7 to position 0 +move position 7 to position 1 +move position 6 to position 7 +rotate right 5 steps +reverse positions 0 through 6 +move position 1 to position 4 +rotate left 3 steps +swap letter d with letter c +move position 4 to position 5 +rotate based on position of letter f +rotate right 1 step +move position 7 to position 6 +swap position 6 with position 0 +move position 6 to position 2 +rotate right 1 step +swap position 1 with position 6 +move position 2 to position 6 +swap position 2 with position 1 +reverse positions 1 through 7 +move position 4 to position 1 +move position 7 to position 0 +swap position 6 with position 7 +rotate left 1 step +reverse positions 0 through 4 +rotate based on position of letter c +rotate based on position of letter b +move position 2 to position 1 +rotate right 0 steps +swap letter b with letter d +swap letter f with letter c +swap letter d with letter a +swap position 7 with position 6 +rotate right 0 steps +swap position 0 with position 3 +swap position 2 with position 5 +swap letter h with letter f +reverse positions 2 through 3 +rotate based on position of letter c +rotate left 2 steps +move position 0 to position 5 +swap position 2 with position 3 +rotate right 1 step +rotate left 2 steps +move position 0 to position 4 +rotate based on position of letter c +rotate based on position of letter g +swap position 3 with position 0 +rotate right 3 steps +reverse positions 0 through 2 +move position 1 to position 2 +swap letter e with letter c +rotate right 7 steps +move position 0 to position 7 +rotate left 2 steps +reverse positions 0 through 4 +swap letter e with letter b +reverse positions 2 through 7 +rotate right 5 steps +swap position 2 with position 4 +swap letter d with letter g +reverse positions 3 through 4 +reverse positions 4 through 5 diff --git a/day21/src/main.rs b/day21/src/main.rs new file mode 100644 index 0000000..6bad021 --- /dev/null +++ b/day21/src/main.rs @@ -0,0 +1,183 @@ +const INPUT: &str = "abcdefgh"; +const INPUT2: &str = "fbgdceah"; + +fn main() { + let instructions: Vec<_> = std::fs::read_to_string("input.txt") + .unwrap() + .lines() + .map(Instruction::parse) + .collect(); + + let mut result: String = INPUT.chars().collect(); + + for i in &instructions { + let mut chars: Vec<_> = result.chars().collect(); + result = i.apply(&mut chars) + } + + println!("{result}"); + + let mut result: String = INPUT2.chars().collect(); + + for i in instructions.iter().rev() { + let mut chars: Vec<_> = result.chars().collect(); + result = i.reverse_apply(&mut chars) + } + + println!("{result}"); +} + +#[derive(Debug)] +enum Instruction { + SwapPosition(usize, usize), + SwapLetter(char, char), + RotateLeft(usize), + RotateRight(usize), + RotateByLetter(char), + ReversePositions(usize, usize), + Move(usize, usize), +} + +fn find_idx_of_letter(s: &[char], a: char) -> Option { + s.iter() + .enumerate() + .find_map(|(i, c)| (a == *c).then_some(i)) +} + +impl Instruction { + fn reverse_apply(&self, s: &mut [char]) -> String { + match self { + Instruction::SwapPosition(a, b) => { + s.swap(*a, *b); + s[..].iter().collect() + } + Instruction::SwapLetter(a, b) => { + let a = find_idx_of_letter(s, *a).unwrap(); + let b = find_idx_of_letter(s, *b).unwrap(); + s.swap(a, b); + s[..].iter().collect() + } + Instruction::RotateLeft(a) => { + s.rotate_right(*a); + s[..].iter().collect() + } + Instruction::RotateRight(a) => { + s.rotate_left(*a); + s[..].iter().collect() + } + Instruction::RotateByLetter(a) => { + let len = s.len(); + for rot in 0..len { + let mut candidate = s.to_vec(); + candidate.rotate_left(rot); + let idx = find_idx_of_letter(&candidate, *a).unwrap(); + let expected_rot = if idx >= 4 { + (1 + idx + 1) % len + } else { + (1 + idx) % len + }; + if expected_rot == rot { + return candidate.iter().collect(); + } + } + unreachable!("no valid rotation found") + } + Instruction::ReversePositions(a, b) => { + s[*a..=*b].reverse(); + s[..].iter().collect() + } + Instruction::Move(a, b) => { + let mut string: Vec = s.to_vec(); + let c = string.remove(*b); + string.insert(*a, c); + string.iter().collect() + } + } + } + + fn apply(&self, s: &mut [char]) -> String { + match self { + Instruction::SwapPosition(a, b) => { + s.swap(*a, *b); + s[..].iter().collect() + } + Instruction::SwapLetter(a, b) => { + let a = find_idx_of_letter(s, *a).unwrap(); + let b = find_idx_of_letter(s, *b).unwrap(); + s.swap(a, b); + s[..].iter().collect() + } + Instruction::RotateLeft(a) => { + s.rotate_left(*a); + s[..].iter().collect() + } + Instruction::RotateRight(a) => { + s.rotate_right(*a); + s[..].iter().collect() + } + Instruction::RotateByLetter(a) => { + let a = find_idx_of_letter(s, *a).unwrap(); + let rotate = if a >= 4 { + (1 + a + 1) % s.len() + } else { + (1 + a) % s.len() + }; + s.rotate_right(rotate); + s[..].iter().collect() + } + Instruction::ReversePositions(a, b) => { + s[*a..=*b].reverse(); + s[..].iter().collect() + } + Instruction::Move(a, b) => { + let mut string: Vec = s.to_vec(); + let c = string.remove(*a); + string.insert(*b, c); + string.iter().collect() + } + } + } + + fn parse(s: &str) -> Self { + let words = s.split_whitespace(); + let two_words: Vec<&str> = words.clone().take(2).collect(); + + let mut words = words.skip(2); + + match two_words[..] { + ["swap", "position"] => { + let a = words.next().unwrap().parse().unwrap(); + let b = words.last().unwrap().parse().unwrap(); + Self::SwapPosition(a, b) + } + ["swap", "letter"] => { + let a = words.next().unwrap().parse().unwrap(); + let b = words.last().unwrap().parse().unwrap(); + Self::SwapLetter(a, b) + } + ["rotate", "left"] => { + let a = words.next().unwrap().parse().unwrap(); + Self::RotateLeft(a) + } + ["rotate", "right"] => { + let a = words.next().unwrap().parse().unwrap(); + Self::RotateRight(a) + } + ["rotate", "based"] => { + let a = words.last().unwrap().parse().unwrap(); + Self::RotateByLetter(a) + } + ["reverse", "positions"] => { + let a = words.next().unwrap().parse().unwrap(); + let b = words.last().unwrap().parse().unwrap(); + Self::ReversePositions(a, b) + } + ["move", "position"] => { + let a = words.next().unwrap().parse().unwrap(); + let b = words.last().unwrap().parse().unwrap(); + Self::Move(a, b) + } + _ => panic!("unknown pattern: {two_words:?}"), + } + } +}