From 3e793911dc9ced530a923e4a9d54e0da145960d2 Mon Sep 17 00:00:00 2001 From: Russell Champoux Date: Tue, 20 Dec 2016 09:24:03 -0500 Subject: [PATCH] Solutions for day14, day18, day19 --- 2016/day14/Cargo.lock | 144 +++++++++++++++++++++++++++++++++++++++++ 2016/day14/Cargo.toml | 8 +++ 2016/day14/src/main.rs | 124 +++++++++++++++++++++++++++++++++++ 2016/day18/Cargo.lock | 4 ++ 2016/day18/Cargo.toml | 6 ++ 2016/day18/src/main.rs | 118 +++++++++++++++++++++++++++++++++ 2016/day19/Cargo.lock | 4 ++ 2016/day19/Cargo.toml | 6 ++ 2016/day19/src/main.rs | 75 +++++++++++++++++++++ 9 files changed, 489 insertions(+) create mode 100644 2016/day14/Cargo.lock create mode 100644 2016/day14/Cargo.toml create mode 100644 2016/day14/src/main.rs create mode 100644 2016/day18/Cargo.lock create mode 100644 2016/day18/Cargo.toml create mode 100644 2016/day18/src/main.rs create mode 100644 2016/day19/Cargo.lock create mode 100644 2016/day19/Cargo.toml create mode 100644 2016/day19/src/main.rs diff --git a/2016/day14/Cargo.lock b/2016/day14/Cargo.lock new file mode 100644 index 0000000..443d4c0 --- /dev/null +++ b/2016/day14/Cargo.lock @@ -0,0 +1,144 @@ +[root] +name = "day14" +version = "0.1.0" +dependencies = [ + "regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)", + "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "aho-corasick" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "gcc" +version = "0.3.40" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "kernel32-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libc" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "memchr" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex" +version = "0.1.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex-syntax" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rust-crypto" +version = "0.2.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "gcc 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rustc-serialize" +version = "0.3.22" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "thread-id" +version = "2.0.0" +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.18 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "thread_local" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "time" +version = "0.1.35" +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.18 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "utf8-ranges" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-build" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ca972c2ea5f742bfce5687b9aef75506a764f61d37f8f649047846a9686ddb66" +"checksum gcc 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)" = "872db9e59486ef2b14f8e8c10e9ef02de2bccef6363d7f34835dedb386b3d950" +"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +"checksum libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "a51822fc847e7a8101514d1d44e354ba2ffa7d4c194dcab48870740e327cac70" +"checksum memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d8b629fb514376c675b98c1421e80b151d3817ac42d7c667717d282761418d20" +"checksum rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "022e0636ec2519ddae48154b028864bdce4eaf7d35226ab8e65c611be97b189d" +"checksum regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)" = "4fd4ace6a8cf7860714a2c2280d6c1f7e6a413486c13298bbc86fd3da019402f" +"checksum regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f9ec002c35e86791825ed294b50008eea9ddfc8def4420124fbc6b08db834957" +"checksum rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a" +"checksum rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "237546c689f20bb44980270c73c3b9edd0891c1be49cc1274406134a66d3957b" +"checksum thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9539db560102d1cef46b8b78ce737ff0bb64e7e18d35b2a5688f7d097d0ff03" +"checksum thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8576dbbfcaef9641452d5cf0df9b0e7eeab7694956dd33bb61515fb8f18cfdd5" +"checksum time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "3c7ec6d62a20df54e07ab3b78b9a3932972f4b7981de295563686849eb3989af" +"checksum utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1ca13c08c41c9c3e04224ed9ff80461d97e121589ff27c753a16cb10830ae0f" +"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" +"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" diff --git a/2016/day14/Cargo.toml b/2016/day14/Cargo.toml new file mode 100644 index 0000000..c43b3d7 --- /dev/null +++ b/2016/day14/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "day14" +version = "0.1.0" +authors = ["~krowbar"] + +[dependencies] +rust-crypto = "^0.2" +regex = "0.1" \ No newline at end of file diff --git a/2016/day14/src/main.rs b/2016/day14/src/main.rs new file mode 100644 index 0000000..d6fdf1f --- /dev/null +++ b/2016/day14/src/main.rs @@ -0,0 +1,124 @@ +extern crate crypto; +//extern crate regex; + +use crypto::md5::Md5; +use crypto::digest::Digest; +//use regex::Regex; + +#[derive(Debug)] +struct Key { + idx: u64, + letters: Vec, + is_valid: bool, + hash: String, +} + +fn repeat_letters(line: &String, size: u64, only_first: bool) -> Vec { + let mut result: Vec = vec![]; + let mut count = 1; //we always have 1-in-a-row + let bytes = line.as_bytes(); + + 'outer: for idx in 0..line.len() - 2 { + if bytes[idx] == bytes[idx + 1] { + count = count + 1; + if count == size && result.iter().position(|&c| c == (bytes[idx] as char)) == None { + result.push(bytes[idx] as char); + if only_first { + break 'outer; + } + } + } else { + count = 1; + } + } + result +} + +fn purge_keys(keys: Vec, idx: u64, threshold: u64) -> Vec { + //remove all invalid keys with idx lower than threshold + //println!("Purging keys older than {} - {}", idx, threshold); + let old_len = keys.len(); + let new_keys: Vec = + keys.into_iter() + .filter(|key| key.is_valid || key.idx + threshold > idx) + .collect::>(); + if old_len > new_keys.len() { + //println!("Purged {} old keys with an idx < {}", old_len - new_keys.len(), idx - threshold); + } + new_keys +} + +fn validate_keys(keys: &mut Vec, key_char: char, idx: u64, threshold: u64) { + // will validate any unvalidated keys within the last *1000* that share the repeated char + let mut count = 0; + keys.into_iter() + .map(|key| { + if !key.is_valid && key.idx + threshold > idx && key.letters.iter().position(|&c| c == key_char) != None { + key.is_valid = true; + count = count + 1; + } + key + }) + .collect::>(); + if count > 0 { + //println!("On key {} at {} keys, validated {} keys using '{}'", idx, keys.len(), count, key_char); + } +} + +fn we_are_done(keys: &Vec, pad_size: usize) -> bool { + //we are done when we have 'pad_size' valid keys in a row + keys.iter().take_while(|key| key.is_valid ).collect::>().len() >= pad_size +} + +const PAD_SIZE: usize = 64; +const THRESHOLD: u64 = 1000; + +fn main() { + + println!("I did something wrong on this one and am not getting the correct answer. :("); + + let mut keys: Vec = vec![]; + let mut hasher = Md5::new(); + + let salt = "ahsbgdzn"; + + //let values: Vec = vec![18, 39, 816]; + for idx in 0..std::u64::MAX { + hasher.input(format!("{}{}", salt, idx).as_bytes()); + //print!("{}{} -> ", salt, idx); + + let mut output = [0; 16]; //represents MD5 string + hasher.result(&mut output); + let output_str: String = output.iter().map(|&c| format!("{:x}", c)).collect(); + //println!("{}", output_str); + + for r in repeat_letters(&output_str, 5, false) { + //println!("Found a super key for '{}'", r); + keys = purge_keys(keys, idx, THRESHOLD); + validate_keys(&mut keys, r, idx, THRESHOLD); + //println!(" from {}", output_str); + } + + //println!("{} - {} - {:?}", idx, output_str, repeat_letters(&output_str, 3)); + let threepeats = repeat_letters(&output_str, 3, true); + if threepeats.len() > 0 { + //ONLY CONSIDER FIRST TRIPPLET + let new_key = Key { idx: idx, letters: threepeats, is_valid: false, hash: String::from(output_str) }; + //println!("Added {:?}", new_key); + keys.push(new_key); + } + + if we_are_done(&keys, PAD_SIZE) { + if keys.len() >= PAD_SIZE { + println!("We're done! Finished on idx {}", idx); + println!("The {}th key is {:?}", PAD_SIZE, keys.iter().nth(PAD_SIZE).unwrap()); + //println!("The {}th key is {:?}", pad_size, keys[pad_size]); + } else { + println!("Uh oh! We didn't find enough keys. :("); + } + break; + } + + hasher.reset(); + } +} diff --git a/2016/day18/Cargo.lock b/2016/day18/Cargo.lock new file mode 100644 index 0000000..ed66149 --- /dev/null +++ b/2016/day18/Cargo.lock @@ -0,0 +1,4 @@ +[root] +name = "day18" +version = "0.1.0" + diff --git a/2016/day18/Cargo.toml b/2016/day18/Cargo.toml new file mode 100644 index 0000000..29d16da --- /dev/null +++ b/2016/day18/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "day18" +version = "0.1.0" +authors = ["~krowbar"] + +[dependencies] diff --git a/2016/day18/src/main.rs b/2016/day18/src/main.rs new file mode 100644 index 0000000..9497838 --- /dev/null +++ b/2016/day18/src/main.rs @@ -0,0 +1,118 @@ +// Trap rules +// * if 110 or 011, 100, 001 +// where nonexistent sides are considered 0 + +#[derive(Debug, PartialEq, Clone)] +enum Tile { + Trapped = 1, + Safe = 0 +} + +type Row = Vec; +type Grid = Vec; + +//Part 1 + +fn add_row(grid: &mut Grid) { + static TRAPS: [[Tile; 3]; 4] = + [ + [Tile::Trapped, Tile::Trapped, Tile::Safe], + [Tile::Safe, Tile::Trapped, Tile::Trapped], + [Tile::Trapped, Tile::Safe, Tile::Safe], + [Tile::Safe, Tile::Safe, Tile::Trapped], + ]; + + let last_row = grid.clone().into_iter().last().unwrap(); + //println!("Last row {:?}", last_row); + let mut new_row: Row = vec![]; + + for idx in 0..last_row.len() { + let mut pre: [Tile; 3] = [Tile::Safe, Tile::Safe, Tile::Safe]; + if idx > 0 { + pre[0] = last_row[idx - 1].clone(); + } + pre[1] = last_row[idx].clone(); + if idx + 1 < last_row.len() { + pre[2] = last_row[idx + 1].clone(); + } + if TRAPS.contains(&pre) { + new_row.push(Tile::Trapped); + } else { + new_row.push(Tile::Safe); + } + } + //println!("New row: {:?}", new_row); + + grid.push(new_row); +} + +fn create_grid(rows: usize) -> Grid { + let first_row: Row = + String::from(".^..^....^....^^.^^.^.^^.^.....^.^..^...^^^^^^.^^^^.^.^^^^^^^.^^^^^..^.^^^.^^..^.^^.^....^.^...^^.^.") + .chars().map(|c| { + match c { + '^' => Tile::Trapped, + _ => Tile::Safe, + } + }).collect::(); + let mut grid: Grid = vec![first_row]; + while grid.len() < rows { + add_row(&mut grid); + } + grid +} + + +// Part 2 +fn step_row(last_row: &mut Row) -> i64 { + static TRAPS: [[Tile; 3]; 4] = + [ + [Tile::Trapped, Tile::Trapped, Tile::Safe], + [Tile::Safe, Tile::Trapped, Tile::Trapped], + [Tile::Trapped, Tile::Safe, Tile::Safe], + [Tile::Safe, Tile::Safe, Tile::Trapped], + ]; + + let mut new_row: Row = vec![]; + let mut safe_tiles = 0; + for idx in 0..last_row.len() { + let mut pre: [Tile; 3] = [Tile::Safe, Tile::Safe, Tile::Safe]; + if idx > 0 { + pre[0] = last_row[idx - 1].clone(); + } + pre[1] = last_row[idx].clone(); + if idx + 1 < last_row.len() { + pre[2] = last_row[idx + 1].clone(); + } + if TRAPS.contains(&pre) { + new_row.push(Tile::Trapped); + } else { + new_row.push(Tile::Safe); + safe_tiles = safe_tiles + 1; + } + } + *last_row = new_row; + safe_tiles +} + +fn main() { + let grid = create_grid(40); + let total_safe = grid.iter().fold(0, |sum, r| sum + r.iter().filter(|t| **t == Tile::Safe).count()); + let total_trap = grid.iter().fold(0, |sum, r| sum + r.iter().filter(|t| **t == Tile::Trapped).count()); + println!("Part 1: There are {} safe tiles and {} traps", total_safe, total_trap); + + //Need to improve the algorithm so it finishes in a sane amount of time + let mut row: Row = + String::from(".^..^....^....^^.^^.^.^^.^.....^.^..^...^^^^^^.^^^^.^.^^^^^^^.^^^^^..^.^^^.^^..^.^^.^....^.^...^^.^.") + .chars().map(|c| { + match c { + '^' => Tile::Trapped, + _ => Tile::Safe, + } + }).collect::(); + let mut safe_tiles = 48; //from row 1 + for _ in 0..400000 - 1 { + safe_tiles = safe_tiles + step_row(&mut row); + } + println!("Part 2: There are {} safe tiles", safe_tiles); +} \ No newline at end of file diff --git a/2016/day19/Cargo.lock b/2016/day19/Cargo.lock new file mode 100644 index 0000000..ddd2c37 --- /dev/null +++ b/2016/day19/Cargo.lock @@ -0,0 +1,4 @@ +[root] +name = "day19" +version = "0.1.0" + diff --git a/2016/day19/Cargo.toml b/2016/day19/Cargo.toml new file mode 100644 index 0000000..0b577ca --- /dev/null +++ b/2016/day19/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "day19" +version = "0.1.0" +authors = ["~krowbar"] + +[dependencies] diff --git a/2016/day19/src/main.rs b/2016/day19/src/main.rs new file mode 100644 index 0000000..16b473b --- /dev/null +++ b/2016/day19/src/main.rs @@ -0,0 +1,75 @@ +// First game +// 1 1 -> 2 0 +// 1 1 1 1 -> 2 0 2 0 -> 4 0 0 0 //first +// 1 1 1 1 1 1 -> 2 0 2 0 2 0 -> 0 0 0 0 6 0 + +// 1 -> 1 +// 1 1 1 -> 0 0 3 //last player +// 1 1 1 1 1 -> 0 0 2 0 3 -> 0 0 5 0 0 //middle player +// 1 1 1 1 1 1 1 -> 0 0 2 0 2 0 3 -> 0 0 0 0 0 0 7 //last player +// 1 1 1 1 1 1 1 1 1 -> 0 0 2 0 2 0 2 0 3 -> 0 0 4 0 0 0 5 0 0 -> 0 0 9 0 0 0 0 0 0 //third player +// 1 1 1 1 1 1 1 1 1 1 1 -> 0 0 2 0 2 0 2 0 2 0 3 -> 0 0 0 0 0 0 4 0 0 0 7 -> 0 0 0 0 0 0 11 0 0 0 0 //7th player + +// generate list +// filter based on size +// filter_even: keep all with even idx +// filter_odd: keep all with even idx except 0 +// repeat until one remains + +fn pass_gifts(players: Vec) -> i64 { + //represents the group of players left after a pass + let is_odd = players.len() % 2 == 1; + let new_players = players.iter().enumerate().filter(|e| !(is_odd && e.0 == 0) && e.0 % 2 == 0).map(|e| *e.1).collect::>(); + //println!("{:?}", new_players); + if new_players.len() == 1 { + new_players[0] + } else { + pass_gifts(new_players) + } +} + +fn play_game(size: i64) -> i64 { + //take the size of the group and returns the winner + let players: Vec = (1..size+1).collect(); + //println!("{:?}", players); + pass_gifts(players) +} + + +// Second game +// 1 2 3 4 -> 1 2 - 4 -> 1 2 - - -> 1 +// 1 2 3 4 5 -> 1 2 - 4 5 -> 1 2 - 4 - -> - 2 - 4 - -> 2 +// 1 2 3 4 5 6 -> +//looping though all players, remove player at position floor(players.len()/2) + player_idx + +fn play_new_game(size: i64) -> i64 { + let mut players = (1..size+1).collect::>(); + println!("Set up vector of {} players", size); + let mut current_player_idx = 0; + let mut player_idx_to_eliminate; + let mut player_len = size as usize; + + while player_len > 1 { + player_idx_to_eliminate = (player_len/2 /*drops fraction*/ + current_player_idx) % player_len; + //println!("Removing idx {} from players (size {}) {:?}", player_idx_to_eliminate, players.len(), players); + //players.remove(player_idx_to_eliminate); + players = players.iter().enumerate().filter(|e| e.0 != player_idx_to_eliminate).map(|e| *e.1).collect::>(); + player_len = player_len - 1; + + current_player_idx = current_player_idx + match player_idx_to_eliminate > current_player_idx { + true => 1, + false => 0 + } % player_len; + } + //println!("Returning {:?}", players); + players[0] +} + +fn main() { + let winner = play_game(3014387); + println!("Part 1: Winner is {}", winner); + + //Need to improve the algorithm so it finishes in a sane amount of time + let new_winner = play_new_game(3014387); + println!("Part 2: Winner is {}", new_winner); +}