From 3b877bf4cc667eb8bcc787d145203600a4dba2d2 Mon Sep 17 00:00:00 2001 From: Prefetch Date: Sat, 25 Feb 2023 11:41:27 +0100 Subject: Initial commit --- d21/Cargo.toml | 7 ++++ d21/input.txt | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++ d21/src/main.rs | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 216 insertions(+) create mode 100644 d21/Cargo.toml create mode 100644 d21/input.txt create mode 100644 d21/src/main.rs (limited to 'd21') diff --git a/d21/Cargo.toml b/d21/Cargo.toml new file mode 100644 index 0000000..f06cd6a --- /dev/null +++ b/d21/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "d21" +version = "0.1.0" +edition = "2021" + +[dependencies] +itertools = "0.10.5" diff --git a/d21/input.txt b/d21/input.txt new file mode 100644 index 0000000..b39b884 --- /dev/null +++ b/d21/input.txt @@ -0,0 +1,100 @@ +reverse positions 1 through 6 +rotate based on position of letter a +swap position 4 with position 1 +reverse positions 1 through 5 +move position 5 to position 7 +swap position 4 with position 0 +swap position 4 with position 6 +rotate based on position of letter a +swap position 0 with position 2 +move position 5 to position 2 +move position 7 to position 1 +swap letter d with letter c +swap position 5 with position 3 +reverse positions 3 through 7 +rotate based on position of letter d +swap position 7 with position 5 +rotate based on position of letter f +swap position 4 with position 1 +swap position 3 with position 6 +reverse positions 4 through 7 +rotate based on position of letter c +move position 0 to position 5 +swap position 7 with position 4 +rotate based on position of letter f +reverse positions 1 through 3 +move position 5 to position 3 +rotate based on position of letter g +reverse positions 2 through 5 +rotate right 0 steps +rotate left 0 steps +swap letter f with letter b +rotate based on position of letter h +move position 1 to position 3 +reverse positions 3 through 6 +rotate based on position of letter h +swap position 4 with position 3 +swap letter b with letter h +swap letter a with letter h +reverse positions 1 through 6 +swap position 3 with position 6 +swap letter e with letter d +swap letter e with letter h +swap position 1 with position 5 +rotate based on position of letter a +reverse positions 4 through 5 +swap position 0 with position 4 +reverse positions 0 through 3 +move position 7 to position 2 +swap letter e with letter c +swap position 3 with position 4 +rotate left 3 steps +rotate left 7 steps +rotate based on position of letter e +reverse positions 5 through 6 +move position 1 to position 5 +move position 1 to position 2 +rotate left 1 step +move position 7 to position 6 +rotate left 0 steps +reverse positions 5 through 6 +reverse positions 3 through 7 +swap letter d with letter e +rotate right 3 steps +swap position 2 with position 1 +swap position 5 with position 7 +swap letter h with letter d +swap letter c with letter d +rotate based on position of letter d +swap letter d with letter g +reverse positions 0 through 1 +rotate right 0 steps +swap position 2 with position 3 +rotate left 4 steps +rotate left 5 steps +move position 7 to position 0 +rotate right 1 step +swap letter g with letter f +rotate based on position of letter a +rotate based on position of letter b +swap letter g with letter e +rotate right 4 steps +rotate based on position of letter h +reverse positions 3 through 5 +swap letter h with letter e +swap letter g with letter a +rotate based on position of letter c +reverse positions 0 through 4 +rotate based on position of letter e +reverse positions 4 through 7 +rotate left 4 steps +swap position 0 with position 6 +reverse positions 1 through 6 +rotate left 2 steps +swap position 5 with position 3 +swap letter b with letter d +swap letter b with letter d +rotate based on position of letter d +rotate based on position of letter c +rotate based on position of letter h +move position 4 to position 7 diff --git a/d21/src/main.rs b/d21/src/main.rs new file mode 100644 index 0000000..34d5599 --- /dev/null +++ b/d21/src/main.rs @@ -0,0 +1,109 @@ +use std::fs; + +use itertools::Itertools; + +fn solve_part1(insts: &Vec<&str>, init: &str) -> String { + let mut chars: Vec = init.chars().collect(); + + for inst in insts { + let mut next = chars.clone(); + + let words: Vec<&str> = inst.split_ascii_whitespace().collect(); + if words[0] == "swap" { + if words[1] == "position" { + // Swap the characters at indices `i' and `j' + let i: usize = words[2].parse().unwrap(); + let j: usize = words[5].parse().unwrap(); + next[i] = chars[j]; + next[j] = chars[i]; + } else if words[1] == "letter" { + // Swap all occurrences of characters `x' and `y' + let x = words[2].chars().nth(0).unwrap(); + let y = words[5].chars().nth(0).unwrap(); + for i in 0..next.len() { + if next[i] == x { + next[i] = y; + } else if next[i] == y { + next[i] = x; + } + } + } + } else if words[0] == "rotate" { + if words[1] == "left" { + let n: usize = words[2].parse().unwrap(); + next.rotate_left(n % chars.len()); + } else if words[1] == "right" { + let n: usize = words[2].parse().unwrap(); + next.rotate_right(n % chars.len()); + } else if words[1] == "based" { + // Get the index `i' of character `x' + let x = words[6].chars().nth(0).unwrap(); + let i = next.iter().position(|&c| c == x).unwrap(); + // Rotate right by an amount determined by `i' + let n = if i < 4 { i + 1 } else { i + 2 }; + next.rotate_right(n % chars.len()); + } + } else if words[0] == "reverse" { + let i: usize = words[2].parse().unwrap(); + let j: usize = words[4].parse().unwrap(); + next[i..j + 1].reverse(); + } else if words[0] == "move" { + let i: usize = words[2].parse().unwrap(); + let j: usize = words[5].parse().unwrap(); + let c = next.remove(i); + next.insert(j, c); + } + + chars = next; + } + + chars.into_iter().collect() +} + +fn solve_part2(insts: &Vec<&str>, target: &str) -> String { + let init = vec!['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']; + + // The "good" approach would be to reverse the operations in `insts'. + // I'm too lazy for that: I just go through all permutations of the + // input characters, run `insts' as in part 1, and see if it's the one. + for perm in init.into_iter().permutations(8) { + let string: String = perm.iter().collect(); + if solve_part1(insts, &string) == target { + return string; + } + } + + String::new() // shouldn't happen +} + +fn main() { + // Read instructions from input text file + let input = fs::read_to_string("input.txt").unwrap(); + let insts = input.lines().collect(); + + // Part 1 gives "gfdhebac" for me + println!("Part 1 solution: {}", solve_part1(&insts, "abcdefgh")); + + // Part 2 gives "dhaegfbc" for me + println!("Part 2 solution: {}", solve_part2(&insts, "fbgdceah")); +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn part1_example1() { + let insts = vec![ + "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", + ]; + assert_eq!(solve_part1(&insts, "abcde"), "decab"); + } +} -- cgit v1.2.3