From 71575ca08a56f8230044edfe3e6897e5077acbf2 Mon Sep 17 00:00:00 2001 From: Alpha Chen Date: Sat, 16 Dec 2017 20:19:27 -0800 Subject: [PATCH] [2017][rust][16.0] --- 2017/rust/Cargo.lock | 19 +++++++++ 2017/rust/Cargo.toml | 1 + 2017/rust/src/day_06.rs | 2 +- 2017/rust/src/day_16.rs | 90 +++++++++++++++++++++++++++++++++++++++++ 2017/rust/src/main.rs | 7 +++- 5 files changed, 116 insertions(+), 3 deletions(-) create mode 100644 2017/rust/src/day_16.rs diff --git a/2017/rust/Cargo.lock b/2017/rust/Cargo.lock index d6adbc5..648f6ec 100644 --- a/2017/rust/Cargo.lock +++ b/2017/rust/Cargo.lock @@ -5,6 +5,7 @@ dependencies = [ "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -108,6 +109,11 @@ name = "quote" version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "redox_syscall" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "regex" version = "0.2.3" @@ -166,6 +172,17 @@ dependencies = [ "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "time" +version = "0.1.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "unicode-xid" version = "0.0.4" @@ -213,6 +230,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)" = "36fbc8a8929c632868295d0178dd8f63fc423fd7537ad0738372bd010b3ac9b0" "checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" +"checksum redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ab105df655884ede59d45b7070c8a65002d921461ee813a024558ca16030eea0" "checksum regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ac6ab4e9218ade5b423358bbd2567d1617418403c7a512603630181813316322" "checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db" "checksum rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "aee45432acc62f7b9a108cc054142dac51f979e69e71ddce7d6fc7adf29e817e" @@ -220,6 +238,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" "checksum synstructure 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a761d12e6d8dcb4dcf952a7a89b475e3a9d69e4a69307e01a470977642914bd" "checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963" +"checksum time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)" = "d5d788d3aa77bc0ef3e9621256885555368b47bd495c13dd2e7413c89f845520" "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" diff --git a/2017/rust/Cargo.toml b/2017/rust/Cargo.toml index 7fdc2ec..ade2bbd 100644 --- a/2017/rust/Cargo.toml +++ b/2017/rust/Cargo.toml @@ -7,3 +7,4 @@ authors = ["Alpha Chen "] failure = "0.1" lazy_static = "1.0" regex = "0.2" +time = "" diff --git a/2017/rust/src/day_06.rs b/2017/rust/src/day_06.rs index 1464cc6..f4f1cd4 100644 --- a/2017/rust/src/day_06.rs +++ b/2017/rust/src/day_06.rs @@ -53,7 +53,7 @@ impl Iterator for Reallocation { let (start, max) = banks .iter() .max_by_key(|&&(_, x)| x) - .map(|&(i, x)| (i, x.clone()))?; + .map(|&(i, x)| (i, *x))?; let len = self.banks.len(); self.banks[start] = 0; diff --git a/2017/rust/src/day_16.rs b/2017/rust/src/day_16.rs new file mode 100644 index 0000000..5bd0feb --- /dev/null +++ b/2017/rust/src/day_16.rs @@ -0,0 +1,90 @@ +use std::convert::TryFrom; +use failure::*; +use regex::Regex; + +pub fn solve(input: &str) -> Result { + // let input = "s1,x3/4,pe/b"; + let moves: Vec<_> = input + .split(',') + .map(Move::try_from) + .collect::>()?; + let mut programs = (b'a'..=b'p').map(|c| c as char).collect::>(); + dance(&moves, &mut programs); + Ok(programs.iter().collect()) +} + +fn dance(moves: &[Move], programs: &mut [char]) { + for m in moves { + match m { + Move::Spin(size) => { + let len = programs.len(); + programs.rotate(len - size); + } + Move::Exchange(a, b) => { + programs.swap(*a, *b); + } + Move::Partner(a, b) => { + let a = programs.iter().position(|x| x == a).unwrap(); + let b = programs.iter().position(|x| x == b).unwrap(); + programs.swap(a, b); + } + } + } +} + +#[test] +fn test_dance() { + let moves = vec![Move::Spin(1), Move::Exchange(3, 4), Move::Partner('e', 'b')]; + let mut programs: Vec<_> = (b'a'..=b'e').map(|c| c as char).collect(); + + dance(&moves, &mut programs); + + assert_eq!(programs, vec!['b', 'a', 'e', 'd', 'c']); +} + +#[derive(Debug, Eq, PartialEq)] +enum Move { + Spin(usize), + Exchange(usize, usize), + Partner(char, char), +} + +lazy_static! { + static ref RE_S: Regex = { Regex::new(r"s(\d+)").unwrap() }; + static ref RE_X: Regex = { Regex::new(r"x(\d+)/(\d+)").unwrap() }; + static ref RE_P: Regex = { Regex::new(r"p(\w)/(\w)").unwrap() }; +} + +impl<'a> TryFrom<&'a str> for Move { + type Error = Error; + + fn try_from(value: &str) -> Result { + RE_S.captures(value) + .and_then(|c| { + let size = c.get(1).unwrap().as_str().parse().ok()?; + Some(Move::Spin(size)) + }) + .or_else(|| { + RE_X.captures(value).and_then(|c| { + let a = c.get(1).unwrap().as_str().parse().ok()?; + let b = c.get(2).unwrap().as_str().parse().ok()?; + Some(Move::Exchange(a, b)) + }) + }) + .or_else(|| { + RE_P.captures(value).and_then(|c| { + let a = c.get(1).unwrap().as_str().chars().next()?; + let b = c.get(2).unwrap().as_str().chars().next()?; + Some(Move::Partner(a, b)) + }) + }) + .ok_or_else(|| format_err!("invalid move: {}", value)) + } +} + +#[test] +fn test_move_try_from() { + assert_eq!(Move::try_from("s1").unwrap(), Move::Spin(1)); + assert_eq!(Move::try_from("x3/4").unwrap(), Move::Exchange(3, 4)); + assert_eq!(Move::try_from("pe/b").unwrap(), Move::Partner('e', 'b')); +} diff --git a/2017/rust/src/main.rs b/2017/rust/src/main.rs index 6eb8141..f2f01bf 100644 --- a/2017/rust/src/main.rs +++ b/2017/rust/src/main.rs @@ -1,9 +1,11 @@ -#![feature(conservative_impl_trait, inclusive_range_syntax)] +#![feature(conservative_impl_trait, inclusive_range_syntax, match_default_bindings, slice_rotate, + try_from)] extern crate failure; #[macro_use] extern crate lazy_static; extern crate regex; +extern crate time; use std::io::{self, Read}; @@ -16,6 +18,7 @@ mod day_04; mod day_05; mod day_06; mod day_15; +mod day_16; fn main() { if let Err(e) = run() { @@ -27,7 +30,7 @@ fn run() -> Result<(), Error> { let mut input = String::new(); io::stdin().read_to_string(&mut input)?; - let solution = day_06::solve(&input)?; + let solution = day_16::solve(&input)?; println!("{}", solution); Ok(())