Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- fn swap_position(s: &[u8], x: usize, y: usize) -> Vec<u8> {
- let mut r = s.to_vec();
- r.swap(x, y);
- r
- }
- fn swap_letter(s: &[u8], x: u8, y: u8) -> Vec<u8> {
- s.iter()
- .map(|c| match c {
- _ if *c == x => y,
- _ if *c == y => x,
- _ => *c,
- })
- .collect()
- }
- fn rotate_left(s: &[u8], steps: usize) -> Vec<u8> {
- s[steps..].iter().chain(s[..steps].iter()).cloned().collect()
- }
- fn rotate_right(s: &[u8], steps: usize) -> Vec<u8> {
- rotate_left(s, s.len() - (steps % s.len()))
- }
- fn rotate_based(s: &[u8], l: u8) -> Vec<u8> {
- let index = s.iter().enumerate().find(|&(_, e)| *e == l).unwrap().0;
- rotate_right(s, 1 + index + (index >= 4) as usize)
- }
- fn rotate_based_inverse(s: &[u8], l: u8) -> Vec<u8> {
- let mut r = s.to_vec();
- while &rotate_based(&r, l) != &s {
- r = rotate_left(&r, 1);
- }
- r
- }
- fn reverse_positions(s: &[u8], x: usize, y: usize) -> Vec<u8> {
- s[..x].iter().chain(s[x..y + 1].iter().rev()).chain(s[y + 1..].iter()).cloned().collect()
- }
- fn move_position(s: &[u8], x: usize, y: usize) -> Vec<u8> {
- let mut r = s.to_vec();
- let letter = r.remove(x);
- r.insert(y, letter);
- r
- }
- fn execute(command: &str, s: &[u8], inverse: bool) -> Vec<u8> {
- let words = command.split(' ').collect::<Vec<_>>();
- let ints = words.iter().map(|w| w.parse::<usize>().unwrap_or(0)).collect::<Vec<_>>();
- let mut s = s.to_vec();
- match (words[0], words[1]) {
- ("swap", "position") => s = swap_position(&s, ints[2], ints[5]),
- ("swap", "letter") => s = swap_letter(&s, words[2].as_bytes()[0], words[5].as_bytes()[0]),
- ("rotate", "left") if !inverse => s = rotate_left(&s, ints[2]),
- ("rotate", "left") => s = rotate_right(&s, ints[2]),
- ("rotate", "right") if !inverse => s = rotate_right(&s, ints[2]),
- ("rotate", "right") => s = rotate_left(&s, ints[2]),
- ("rotate", "based") if !inverse => s = rotate_based(&s, words[6].as_bytes()[0]),
- ("rotate", "based") => s = rotate_based_inverse(&s, words[6].as_bytes()[0]),
- ("reverse", "positions") => s = reverse_positions(&s, ints[2], ints[4]),
- ("move", "position") if !inverse => s = move_position(&s, ints[2], ints[5]),
- ("move", "position") => s = move_position(&s, ints[5], ints[2]),
- _ => panic!("cannot parse command"),
- }
- s
- }
- fn p(input: &str, commands: &[&str], inverse: bool) -> String {
- let mut s = input.bytes().collect::<Vec<_>>();
- for command in commands {
- s = execute(command, &s, inverse);
- }
- String::from_utf8(s).unwrap()
- }
- fn main() {
- let commands = include_str!("../../21.input").lines().collect::<Vec<&str>>();
- println!("P1 = {}", p("abcdefgh", &commands, false));
- println!("P2 = {}", p("fbgdceah", &commands, true));
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement