diff --git a/2016/day-21/Cargo.toml b/2016/day-21/Cargo.toml new file mode 100644 index 0000000..16c171d --- /dev/null +++ b/2016/day-21/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "day-21" +version = "0.1.0" +authors = ["Bert Peters "] + +[dependencies] diff --git a/2016/day-21/input.txt b/2016/day-21/input.txt new file mode 100644 index 0000000..f43fd37 --- /dev/null +++ b/2016/day-21/input.txt @@ -0,0 +1,100 @@ +swap position 2 with position 7 +swap letter f with letter a +swap letter c with letter a +rotate based on position of letter g +rotate based on position of letter f +rotate based on position of letter b +swap position 3 with position 6 +swap letter e with letter c +swap letter f with letter h +rotate based on position of letter e +swap letter c with letter b +rotate right 6 steps +reverse positions 4 through 7 +rotate based on position of letter f +swap position 1 with position 5 +rotate left 1 step +swap letter d with letter e +rotate right 7 steps +move position 0 to position 6 +swap position 2 with position 6 +swap position 2 with position 0 +swap position 0 with position 1 +rotate based on position of letter d +rotate right 2 steps +rotate left 4 steps +reverse positions 0 through 2 +rotate right 2 steps +move position 6 to position 1 +move position 1 to position 2 +reverse positions 2 through 5 +move position 2 to position 7 +rotate left 3 steps +swap position 0 with position 1 +rotate based on position of letter g +swap position 5 with position 0 +rotate left 1 step +swap position 7 with position 1 +swap letter g with letter h +rotate left 1 step +rotate based on position of letter g +reverse positions 1 through 7 +reverse positions 1 through 4 +reverse positions 4 through 5 +rotate left 2 steps +swap letter f with letter d +swap position 6 with position 3 +swap letter c with letter e +swap letter c with letter d +swap position 1 with position 6 +rotate based on position of letter g +move position 4 to position 5 +swap letter g with letter h +rotate based on position of letter h +swap letter h with letter f +swap position 3 with position 6 +rotate based on position of letter c +rotate left 3 steps +rotate based on position of letter d +swap position 0 with position 7 +swap letter e with letter d +move position 6 to position 7 +rotate right 5 steps +move position 7 to position 0 +rotate left 1 step +move position 6 to position 2 +rotate based on position of letter d +rotate right 7 steps +swap position 3 with position 5 +move position 1 to position 5 +rotate right 0 steps +move position 4 to position 5 +rotate based on position of letter b +reverse positions 2 through 4 +rotate right 3 steps +swap letter b with letter g +rotate based on position of letter a +rotate right 0 steps +move position 0 to position 6 +reverse positions 5 through 6 +rotate left 2 steps +move position 3 to position 0 +swap letter g with letter b +move position 6 to position 1 +rotate based on position of letter f +move position 3 to position 2 +reverse positions 2 through 7 +swap position 0 with position 4 +swap letter e with letter b +rotate left 4 steps +reverse positions 0 through 4 +rotate based on position of letter a +rotate based on position of letter b +rotate left 6 steps +rotate based on position of letter d +rotate left 7 steps +swap letter c with letter d +rotate left 3 steps +move position 4 to position 6 +move position 3 to position 2 +reverse positions 0 through 6 diff --git a/2016/day-21/sample.txt b/2016/day-21/sample.txt new file mode 100644 index 0000000..865c052 --- /dev/null +++ b/2016/day-21/sample.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/2016/day-21/src/main.rs b/2016/day-21/src/main.rs new file mode 100644 index 0000000..5559584 --- /dev/null +++ b/2016/day-21/src/main.rs @@ -0,0 +1,166 @@ +use std::env; +use std::io::prelude::*; +use std::io::BufReader; +use std::fs::File; + +fn vec_str(vec: &[char]) -> String +{ + return vec.iter().cloned().collect(); +} + +fn find(password: &[char], search: &str) -> usize +{ + let c = search.chars().next().unwrap(); + for (index, b) in password.iter().enumerate() { + if c == *b { + return index; + } + } + panic!("{} not found in {}", c, vec_str(password)); +} + +fn rotate_left(password: &[char], amount: usize) -> Vec +{ + let mut new_passwd = Vec::with_capacity(password.len()); + + new_passwd.extend_from_slice(&password[amount..]); + new_passwd.extend_from_slice(&password[..amount]); + + return new_passwd; +} + +fn reverse_range(password: &mut[char], pos_1: usize, pos_2: usize) +{ + password[pos_1..pos_2 + 1].reverse(); +} + +fn swap(password: &mut[char], by: &str, id_1: &str, id_2: &str) +{ + let pos_1: usize; + let pos_2: usize; + match by { + "position" => { + pos_1 = id_1.parse().unwrap(); + pos_2 = id_2.parse().unwrap(); + }, + "letter" => { + pos_1 = find(password, id_1); + pos_2 = find(password, id_2); + }, + _ => panic!("Can't swap {}", by), + } + + password.swap(pos_1, pos_2); +} + +fn main() { + let args: Vec = env::args().collect(); + let f = File::open(&args[1]).expect("Could not open file"); + let reader = BufReader::new(f); + + let mut password: Vec = "abcdefgh".chars().collect(); + let mut rules = Vec::new(); + + for line in reader.lines() { + let contents = line.unwrap(); + let parts: Vec<&str> = contents.split(" ").collect(); + rules.push(contents.clone()); + + match parts[0] { + "swap" => { + swap(&mut password, &parts[1], &parts[2], &parts[5]); + }, + "rotate" => { + let amount = match parts[1] { + "left" => parts[2].parse().unwrap(), + "right" => password.len() - parts[2].parse::().unwrap(), + "based" => { + let pos = find(&password, parts[6]); + + 2 * password.len() - if pos >= 4 { pos + 2 } else { pos + 1 } + }, + + _ => panic!("Cannot rotate by {}", parts[2]), + } % password.len(); + password = rotate_left(&password, amount); + }, + + "reverse" => { + let pos_1: usize = parts[2].parse().unwrap(); + let pos_2: usize = parts[4].parse().unwrap(); + reverse_range(&mut password, pos_1, pos_2); + }, + "move" => { + let pos_1: usize = parts[2].parse().unwrap(); + let pos_2: usize = parts[5].parse().unwrap(); + + let c = password.remove(pos_1); + password.insert(pos_2, c); + }, + _ => panic!("Don't understand {}", parts[0]), + } + } + + println!("Final password is {}", vec_str(&password)); + let mut password: Vec = "fbgdceah".chars().collect(); + + for line in rules.iter().rev() { + let parts: Vec<&str> = line.split(" ").collect(); + + match parts[0] { + "swap" => { + swap(&mut password, &parts[1], &parts[2], &parts[5]); + }, + "rotate" => { + // invert regular rotations, and + let amount = match parts[1] { + "right" => parts[2].parse().unwrap(), + "left" => password.len() - parts[2].parse::().unwrap(), + "based" => { + let pos = find(&password, parts[6]); + + let mut original = usize::max_value(); + if pos % 2 == 1 { + // original pos < 4 + for x in 0..4 { + if (2 * x + 1) % password.len() == pos { + original = x + 1; + break; + } + } + } else { + // original pos >= 4 + for x in 4..password.len() { + if (2 * x + 2) % password.len() == pos { + original = x + 2; + } + } + } + + original + }, + + _ => panic!("Cannot rotate by {}", parts[2]), + } % password.len(); + password = rotate_left(&password, amount); + }, + + "reverse" => { + let pos_1: usize = parts[2].parse().unwrap(); + let pos_2: usize = parts[4].parse().unwrap(); + reverse_range(&mut password, pos_1, pos_2); + }, + "move" => { + let pos_1: usize = parts[2].parse().unwrap(); + let pos_2: usize = parts[5].parse().unwrap(); + + let c = password.remove(pos_2); + password.insert(pos_1, c); + }, + _ => panic!("Don't understand {}", parts[0]), + } + } + + println!("Reversed password is {}", vec_str(&password)); + +}