Advertisement
Guest User

Untitled

a guest
Dec 21st, 2016
366
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 2.85 KB | None | 0 0
  1. fn swap_position(s: &[u8], x: usize, y: usize) -> Vec<u8> {
  2.     let mut r = s.to_vec();
  3.     r.swap(x, y);
  4.     r
  5. }
  6.  
  7. fn swap_letter(s: &[u8], x: u8, y: u8) -> Vec<u8> {
  8.     s.iter()
  9.         .map(|c| match c {
  10.             _ if *c == x => y,
  11.             _ if *c == y => x,
  12.             _ => *c,
  13.         })
  14.         .collect()
  15. }
  16.  
  17. fn rotate_left(s: &[u8], steps: usize) -> Vec<u8> {
  18.     s[steps..].iter().chain(s[..steps].iter()).cloned().collect()
  19. }
  20.  
  21. fn rotate_right(s: &[u8], steps: usize) -> Vec<u8> {
  22.     rotate_left(s, s.len() - (steps % s.len()))
  23. }
  24.  
  25. fn rotate_based(s: &[u8], l: u8) -> Vec<u8> {
  26.     let index = s.iter().enumerate().find(|&(_, e)| *e == l).unwrap().0;
  27.     rotate_right(s, 1 + index + (index >= 4) as usize)
  28. }
  29.  
  30. fn rotate_based_inverse(s: &[u8], l: u8) -> Vec<u8> {
  31.     let mut r = s.to_vec();
  32.     while &rotate_based(&r, l) != &s {
  33.         r = rotate_left(&r, 1);
  34.     }
  35.     r
  36. }
  37.  
  38. fn reverse_positions(s: &[u8], x: usize, y: usize) -> Vec<u8> {
  39.     s[..x].iter().chain(s[x..y + 1].iter().rev()).chain(s[y + 1..].iter()).cloned().collect()
  40. }
  41.  
  42. fn move_position(s: &[u8], x: usize, y: usize) -> Vec<u8> {
  43.     let mut r = s.to_vec();
  44.     let letter = r.remove(x);
  45.     r.insert(y, letter);
  46.     r
  47. }
  48.  
  49. fn execute(command: &str, s: &[u8], inverse: bool) -> Vec<u8> {
  50.     let words = command.split(' ').collect::<Vec<_>>();
  51.     let ints = words.iter().map(|w| w.parse::<usize>().unwrap_or(0)).collect::<Vec<_>>();
  52.     let mut s = s.to_vec();
  53.     match (words[0], words[1]) {
  54.         ("swap", "position") => s = swap_position(&s, ints[2], ints[5]),
  55.         ("swap", "letter") => s = swap_letter(&s, words[2].as_bytes()[0], words[5].as_bytes()[0]),
  56.         ("rotate", "left") if !inverse => s = rotate_left(&s, ints[2]),
  57.         ("rotate", "left") => s = rotate_right(&s, ints[2]),
  58.         ("rotate", "right") if !inverse => s = rotate_right(&s, ints[2]),
  59.         ("rotate", "right") => s = rotate_left(&s, ints[2]),
  60.         ("rotate", "based") if !inverse => s = rotate_based(&s, words[6].as_bytes()[0]),
  61.         ("rotate", "based") => s = rotate_based_inverse(&s, words[6].as_bytes()[0]),
  62.         ("reverse", "positions") => s = reverse_positions(&s, ints[2], ints[4]),
  63.         ("move", "position") if !inverse => s = move_position(&s, ints[2], ints[5]),
  64.         ("move", "position") => s = move_position(&s, ints[5], ints[2]),
  65.         _ => panic!("cannot parse command"),
  66.     }
  67.     s
  68. }
  69.  
  70. fn p(input: &str, commands: &[&str], inverse: bool) -> String {
  71.     let mut s = input.bytes().collect::<Vec<_>>();
  72.     for command in commands {
  73.         s = execute(command, &s, inverse);
  74.     }
  75.     String::from_utf8(s).unwrap()
  76. }
  77.  
  78. fn main() {
  79.     let commands = include_str!("../../21.input").lines().collect::<Vec<&str>>();
  80.     println!("P1 = {}", p("abcdefgh", &commands, false));
  81.     println!("P2 = {}", p("fbgdceah", &commands, true));
  82. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement