add day 21

This commit is contained in:
timeshifter
2026-07-03 16:07:25 +02:00
parent 2ce82421c2
commit 672c7de41a
5 changed files with 304 additions and 0 deletions
+183
View File
@@ -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<usize> {
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<char> = 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<char> = 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:?}"),
}
}
}