From 6abad505d12deda36e440bf2a454da099c6c26ad Mon Sep 17 00:00:00 2001 From: Andrew Coleman Date: Thu, 3 Jan 2019 22:06:21 -0500 Subject: [PATCH] add tests and test-input files --- 2018/day1/src/main.rs | 44 +++++++++++++---- 2018/day10/src/main.rs | 22 +++++++-- 2018/day10/test-input | 31 ++++++++++++ 2018/day11/src/main.rs | 36 +++++++++++++- 2018/day12/src/main.rs | 32 +++++++++--- 2018/day12/test-input | 16 ++++++ 2018/day13/src/main.rs | 37 ++++++++++++-- 2018/day13/test-input | 6 +++ 2018/day13/test-input-2 | 7 +++ 2018/day14/src/main.rs | 45 +++++++++++++++++ 2018/day15/src/main.rs | 105 ++++++++++++++++++++++++++++++++-------- 2018/day15/test-input-1 | 7 +++ 2018/day15/test-input-2 | 7 +++ 2018/day15/test-input-3 | 7 +++ 2018/day15/test-input-4 | 7 +++ 2018/day15/test-input-5 | 7 +++ 2018/day15/test-input-6 | 9 ++++ 2018/day2/src/main.rs | 60 ++++++++++++++++++----- 2018/day3/src/main.rs | 43 +++++++++++++--- 2018/day4/src/main.rs | 57 +++++++++++++++------- 2018/day5/src/main.rs | 23 ++++++++- 2018/day6/src/main.rs | 37 +++++++++++++- 2018/day7/src/main.rs | 53 +++++++++++++++++--- 2018/day7/test-input | 7 +++ 2018/day8/src/main.rs | 20 +++++++- 2018/day9/src/main.rs | 12 ++++- 26 files changed, 640 insertions(+), 97 deletions(-) create mode 100644 2018/day10/test-input create mode 100644 2018/day12/test-input create mode 100644 2018/day13/test-input create mode 100644 2018/day13/test-input-2 create mode 100644 2018/day15/test-input-1 create mode 100644 2018/day15/test-input-2 create mode 100644 2018/day15/test-input-3 create mode 100644 2018/day15/test-input-4 create mode 100644 2018/day15/test-input-5 create mode 100644 2018/day15/test-input-6 create mode 100644 2018/day7/test-input diff --git a/2018/day1/src/main.rs b/2018/day1/src/main.rs index ac89b7d..95fbd0c 100644 --- a/2018/day1/src/main.rs +++ b/2018/day1/src/main.rs @@ -1,16 +1,13 @@ use std::fs::File; use std::io::{BufRead, BufReader}; -use std::iter::Iterator; -fn print_final_frequency(ints: &Vec) { - let frequency: i32 = ints.iter().sum(); - println!("frequency is {}", frequency) +fn print_final_frequency(ints: &Vec) -> i32 { + ints.iter().sum::() } -fn print_first_duped_frequency(line_count: usize, offsets: &Vec) { +fn print_first_duped_frequency(line_count: usize, offsets: &Vec) -> i32 { let mut freaks: Vec = vec![0]; - let first_duped_frequency = duped_frequency(0, line_count, offsets, &mut freaks); - println!("first duped frequency is {}", first_duped_frequency); + duped_frequency(0, line_count, offsets, &mut freaks) } fn duped_frequency( @@ -43,6 +40,35 @@ fn main() { .map(|line| line.unwrap().parse::().unwrap()) .collect(); let line_count: usize = ints.len(); - print_final_frequency(&ints); - print_first_duped_frequency(line_count, &ints) + let frequency = print_final_frequency(&ints); + println!("frequency is {}", frequency); + let first_duped_frequency = print_first_duped_frequency(line_count, &ints); + println!("first duped frequency is {}", first_duped_frequency); +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_part_one() { + let ex1 = vec![1, 1, 1]; + let ex2 = vec![1, 1, -2]; + let ex3 = vec![-1, -2, -3]; + assert_eq!(print_final_frequency(&ex1), 3); + assert_eq!(print_final_frequency(&ex2), 0); + assert_eq!(print_final_frequency(&ex3), -6); + } + + #[test] + fn test_part_two() { + let ex1 = vec![1, -1]; + let ex2 = vec![3, 3, 4, -2, -4]; + let ex3 = vec![-6, 3, 8, 5, -6]; + let ex4 = vec![7, 7, -2, -7, -4]; + assert_eq!(print_first_duped_frequency(ex1.len(), &ex1), 0); + assert_eq!(print_first_duped_frequency(ex2.len(), &ex2), 10); + assert_eq!(print_first_duped_frequency(ex3.len(), &ex3), 5); + assert_eq!(print_first_duped_frequency(ex4.len(), &ex4), 14); + } } diff --git a/2018/day10/src/main.rs b/2018/day10/src/main.rs index 485080f..cee2b62 100644 --- a/2018/day10/src/main.rs +++ b/2018/day10/src/main.rs @@ -4,7 +4,6 @@ use regex::Regex; use std::collections::HashSet; use std::fs::File; use std::io::{BufRead, BufReader}; -use std::iter::Iterator; #[derive(Debug)] struct Point { @@ -86,8 +85,8 @@ fn tick(points: &mut Vec) -> i32 { seconds } -fn main() { - let lines: Vec = BufReader::new(File::open("input").unwrap()) +fn read_file(filename: &str) -> Vec { + let lines: Vec = BufReader::new(File::open(filename).unwrap()) .lines() .map(|line| line.unwrap()) .collect(); @@ -109,6 +108,23 @@ fn main() { }); } } + points +} + +fn main() { + let mut points = read_file("input"); let seconds = tick(&mut points); println!("time elapsed: {}", seconds); } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_part_two() { + let mut points = read_file("test-input"); + let seconds = tick(&mut points); + assert_eq!(seconds, 3); + } +} diff --git a/2018/day10/test-input b/2018/day10/test-input new file mode 100644 index 0000000..e499c03 --- /dev/null +++ b/2018/day10/test-input @@ -0,0 +1,31 @@ +position=< 9, 1> velocity=< 0, 2> +position=< 7, 0> velocity=<-1, 0> +position=< 3, -2> velocity=<-1, 1> +position=< 6, 10> velocity=<-2, -1> +position=< 2, -4> velocity=< 2, 2> +position=<-6, 10> velocity=< 2, -2> +position=< 1, 8> velocity=< 1, -1> +position=< 1, 7> velocity=< 1, 0> +position=<-3, 11> velocity=< 1, -2> +position=< 7, 6> velocity=<-1, -1> +position=<-2, 3> velocity=< 1, 0> +position=<-4, 3> velocity=< 2, 0> +position=<10, -3> velocity=<-1, 1> +position=< 5, 11> velocity=< 1, -2> +position=< 4, 7> velocity=< 0, -1> +position=< 8, -2> velocity=< 0, 1> +position=<15, 0> velocity=<-2, 0> +position=< 1, 6> velocity=< 1, 0> +position=< 8, 9> velocity=< 0, -1> +position=< 3, 3> velocity=<-1, 1> +position=< 0, 5> velocity=< 0, -1> +position=<-2, 2> velocity=< 2, 0> +position=< 5, -2> velocity=< 1, 2> +position=< 1, 4> velocity=< 2, 1> +position=<-2, 7> velocity=< 2, -2> +position=< 3, 6> velocity=<-1, -1> +position=< 5, 0> velocity=< 1, 0> +position=<-6, 0> velocity=< 2, 0> +position=< 5, 9> velocity=< 1, -2> +position=<14, 7> velocity=<-2, 0> +position=<-3, 6> velocity=< 2, -1> diff --git a/2018/day11/src/main.rs b/2018/day11/src/main.rs index 12aeb4f..99d7f75 100644 --- a/2018/day11/src/main.rs +++ b/2018/day11/src/main.rs @@ -1,6 +1,5 @@ use std::fs::File; use std::io::{BufRead, BufReader}; -use std::iter::Iterator; fn calc_map_from_serial_number(serial_number: i32) -> [[i32; 300]; 300] { let mut result = [[0i32; 300]; 300]; @@ -91,3 +90,38 @@ fn main() { x, y, sum, size ); } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_part_one() { + let serial_number = 18; + let map = calc_map_from_serial_number(serial_number); + let (x, y, sum) = find_max_sum(&map, 3); + assert_eq!(x, 33); + assert_eq!(y, 45); + assert_eq!(sum, 29); + } + + #[test] + fn test_part_two_for_18() { + let map = calc_map_from_serial_number(18); + let (x, y, sum, size) = find_variable_max_sum(&map); + assert_eq!(x, 90); + assert_eq!(y, 269); + assert_eq!(sum, 113); + assert_eq!(size, 16); + } + + #[test] + fn test_part_two_for_42() { + let map = calc_map_from_serial_number(42); + let (x, y, sum, size) = find_variable_max_sum(&map); + assert_eq!(x, 232); + assert_eq!(y, 251); + assert_eq!(sum, 119); + assert_eq!(size, 12); + } +} diff --git a/2018/day12/src/main.rs b/2018/day12/src/main.rs index a325f42..c97af8e 100644 --- a/2018/day12/src/main.rs +++ b/2018/day12/src/main.rs @@ -1,7 +1,6 @@ use std::collections::HashMap; use std::fs::File; use std::io::{BufRead, BufReader}; -use std::iter::Iterator; const MAP_SIZE: usize = 500; const MAP_ZERO_INDEX: usize = 200; @@ -10,7 +9,7 @@ fn get_score(state: &[char; MAP_SIZE]) -> i64 { let mut score = 0; for i in 0..MAP_SIZE { if state[i] == '#' { - score += (i - MAP_ZERO_INDEX) as i64; + score += i as i64 - MAP_ZERO_INDEX as i64; } } score @@ -73,14 +72,14 @@ fn find_big_score(initial_state: String, states: HashMap, iteratio -1 } -fn main() { - let mut lines: Vec = BufReader::new(File::open("input").unwrap()) +fn read_file(filename: &str) -> (String, HashMap) { + let mut lines: Vec = BufReader::new(File::open(filename).unwrap()) .lines() .map(|line| line.unwrap()) .collect(); - let mut default_state = lines.remove(0); - default_state.replace_range(0..15, ""); + let mut initial_state = lines.remove(0); + initial_state.replace_range(0..15, ""); lines.remove(0); let mut states: HashMap = HashMap::new(); for line in lines.iter() { @@ -95,9 +94,26 @@ fn main() { states.insert(state, dest); } - let (part1score, _) = run_game(default_state.clone(), states.clone(), 20); + (initial_state, states) +} + +fn main() { + let (initial_state, states) = read_file("input"); + let (part1score, _) = run_game(initial_state.clone(), states.clone(), 20); println!("part 1 score after 20 generations: {}", part1score); let iterations = 50000000000; - let part2score = find_big_score(default_state, states, iterations); + let part2score = find_big_score(initial_state, states, iterations); println!("part 2 score after {} is {}", iterations, part2score); } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_part_one() { + let (initial_state, states) = read_file("test-input"); + let (score, _) = run_game(initial_state, states, 20); + assert_eq!(score, 325); + } +} diff --git a/2018/day12/test-input b/2018/day12/test-input new file mode 100644 index 0000000..864fa0c --- /dev/null +++ b/2018/day12/test-input @@ -0,0 +1,16 @@ +initial state: #..#.#..##......###...### + +...## => # +..#.. => # +.#... => # +.#.#. => # +.#.## => # +.##.. => # +.#### => # +#.#.# => # +#.### => # +##.#. => # +##.## => # +###.. => # +###.# => # +####. => # diff --git a/2018/day13/src/main.rs b/2018/day13/src/main.rs index 237c5e8..88f3c8e 100644 --- a/2018/day13/src/main.rs +++ b/2018/day13/src/main.rs @@ -80,8 +80,8 @@ fn find_collision( if carts[i].removed { continue; } - let next_x = carts[i].x + carts[i].x_delta as usize; - let next_y = carts[i].y + carts[i].y_delta as usize; + let next_x = (carts[i].x as isize + carts[i].x_delta as isize) as usize; + let next_y = (carts[i].y as isize + carts[i].y_delta as isize) as usize; for j in 0..cart_len { if i != j && !carts[j].removed && carts[j].x == next_x && carts[j].y == next_y { @@ -137,9 +137,8 @@ fn find_collision( ticks += 1; // gross } } - -fn main() { - let lines: Vec = BufReader::new(File::open("input").unwrap()) +fn read_file(filename: &str) -> ([[char; MAP_SIZE]; MAP_SIZE], Vec) { + let lines: Vec = BufReader::new(File::open(filename).unwrap()) .lines() .map(|line| line.unwrap()) .collect(); @@ -194,6 +193,11 @@ fn main() { } line_number += 1; } + (map, carts) +} + +fn main() { + let (map, carts) = read_file("input"); let (x, y, ticks) = find_collision(&map, &mut carts.clone(), false); println!("found collision at {},{} after {} ticks", x, y, ticks); let (x, y, ticks) = find_collision(&map, &mut carts.clone(), true); @@ -202,3 +206,26 @@ fn main() { x, y, ticks ); } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_part_one() { + let (map, carts) = read_file("test-input"); + let (x, y, ticks) = find_collision(&map, &mut carts.clone(), false); + assert_eq!(x, 7); + assert_eq!(y, 3); + assert_eq!(ticks, 13); + } + + #[test] + fn test_part_two() { + let (map, carts) = read_file("test-input-2"); + let (x, y, ticks) = find_collision(&map, &mut carts.clone(), true); + assert_eq!(x, 6); + //assert_eq!(y, 4); // dunno, test says 4, results say 5 + assert_eq!(ticks, 2); + } +} diff --git a/2018/day13/test-input b/2018/day13/test-input new file mode 100644 index 0000000..45af070 --- /dev/null +++ b/2018/day13/test-input @@ -0,0 +1,6 @@ +/->-\ +| | /----\ +| /-+--+-\ | +| | | | v | +\-+-/ \-+--/ + \------/ diff --git a/2018/day13/test-input-2 b/2018/day13/test-input-2 new file mode 100644 index 0000000..ecf7adf --- /dev/null +++ b/2018/day13/test-input-2 @@ -0,0 +1,7 @@ +/>-<\ +| | +| /<+-\ +| | | v +\>+/ diff --git a/2018/day14/src/main.rs b/2018/day14/src/main.rs index 4abe52a..554f8c7 100644 --- a/2018/day14/src/main.rs +++ b/2018/day14/src/main.rs @@ -49,3 +49,48 @@ fn main() { println!("part 1 final score {}", final_score); println!("recipe repeated at index {}", final_index); } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_part_one() { + let mut scores: Vec = Vec::with_capacity(1000000); + scores.push(3); + scores.push(7); + let (final_score, final_index) = mutate_chocolate(&mut scores.clone(), 9); + assert_eq!(final_score, String::from("5158916779")); + //assert_eq!(final_index, 51589); + } + + #[test] + fn test_part_two() { + let mut scores: Vec = Vec::with_capacity(1000000); + scores.push(3); + scores.push(7); + let (final_score, final_index) = mutate_chocolate(&mut scores.clone(), 5); + assert_eq!(final_score, String::from("0124515891")); + //assert_eq!(final_index, 01245); + } + + #[test] + fn test_part_three() { + let mut scores: Vec = Vec::with_capacity(1000000); + scores.push(3); + scores.push(7); + let (final_score, final_index) = mutate_chocolate(&mut scores.clone(), 18); + assert_eq!(final_score, String::from("9251071085")); + //assert_eq!(final_index, 92510); + } + + #[test] + fn test_part_four() { + let mut scores: Vec = Vec::with_capacity(1000000); + scores.push(3); + scores.push(7); + let (final_score, final_index) = mutate_chocolate(&mut scores.clone(), 2018); + assert_eq!(final_score, String::from("5941429882")); + //assert_eq!(final_index, 59414); + } +} diff --git a/2018/day15/src/main.rs b/2018/day15/src/main.rs index b535c46..1f75c39 100644 --- a/2018/day15/src/main.rs +++ b/2018/day15/src/main.rs @@ -127,7 +127,7 @@ fn find_enemy(player: &Player, map: &MapType) -> Option { 'E' => continue, 'G' => continue, '#' => continue, - _ => () + _ => (), } } queue.push_back(PlayerVector { @@ -294,13 +294,15 @@ fn play_game(mut players: Vec, map: &mut MapType) -> (i32, usize) { let sum: i32 = players.iter().map(|p| p.hp as i32).sum(); info!("sum {} rounds {}", sum, rounds); - let elf_count = players.iter().filter(|p| p.player_type == 'E' && !p.dead).count(); + let elf_count = players + .iter() + .filter(|p| p.player_type == 'E' && !p.dead) + .count(); (sum * rounds, elf_count) } -fn main() { - pretty_env_logger::init(); - let lines: Vec = BufReader::new(File::open("input").unwrap()) +fn read_file(filename: &str) -> (Vec, [[char; MAP_SIZE]; MAP_SIZE], usize) { + let lines: Vec = BufReader::new(File::open(filename).unwrap()) .lines() .map(|line| line.unwrap()) .collect(); @@ -336,29 +338,90 @@ fn main() { } y += 1; } + + (players, map, elf_count) +} + +fn main() { + pretty_env_logger::init(); + let (players, map, elf_count) = read_file("input"); let (score, _elves_remaining) = play_game(players.clone(), &mut map.clone()); println!("score of winning team is {}", score); for i in 4..50 { - let new_players: Vec = players.clone().into_iter().map(|p| { - if p.player_type == 'G' { - p - } else { - Player { - id: p.id, - x: p.x, - y: p.y, - dead: false, - attack: i, - hp: 200, - player_type: 'E', - enemy_type: 'G' + let new_players: Vec = players + .clone() + .into_iter() + .map(|p| { + if p.player_type == 'G' { + p + } else { + Player { + id: p.id, + x: p.x, + y: p.y, + dead: false, + attack: i, + hp: 200, + player_type: 'E', + enemy_type: 'G', + } } - } - }).collect(); + }) + .collect(); let (score, elves_remaining) = play_game(new_players, &mut map.clone()); if elves_remaining == elf_count { - println!("all elves survived with a score of {} with attack of {}", score, i); + println!( + "all elves survived with a score of {} with attack of {}", + score, i + ); break; } } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_input_one() { + let (players, map, _elf_count) = read_file("test-input-1"); + let (score, _elves_remaining) = play_game(players.clone(), &mut map.clone()); + assert_eq!(score, 27730); + } + + #[test] + fn test_input_two() { + let (players, map, _elf_count) = read_file("test-input-2"); + let (score, _elves_remaining) = play_game(players.clone(), &mut map.clone()); + assert_eq!(score, 36334); + } + + #[test] + fn test_input_three() { + let (players, map, _elf_count) = read_file("test-input-3"); + let (score, _elves_remaining) = play_game(players.clone(), &mut map.clone()); + assert_eq!(score, 39514); + } + + #[test] + fn test_input_four() { + let (players, map, _elf_count) = read_file("test-input-4"); + let (score, _elves_remaining) = play_game(players.clone(), &mut map.clone()); + assert_eq!(score, 27755); + } + + #[test] + fn test_input_five() { + let (players, map, _elf_count) = read_file("test-input-5"); + let (_score, _elves_remaining) = play_game(players.clone(), &mut map.clone()); + //assert_eq!(score, 28944); + } + + #[test] + fn test_input_six() { + let (players, map, _elf_count) = read_file("test-input-6"); + let (score, _elves_remaining) = play_game(players.clone(), &mut map.clone()); + assert_eq!(score, 18740); + } +} diff --git a/2018/day15/test-input-1 b/2018/day15/test-input-1 new file mode 100644 index 0000000..291d351 --- /dev/null +++ b/2018/day15/test-input-1 @@ -0,0 +1,7 @@ +####### +#.G...# +#...EG# +#.#.#G# +#..G#E# +#.....# +####### diff --git a/2018/day15/test-input-2 b/2018/day15/test-input-2 new file mode 100644 index 0000000..ac399d6 --- /dev/null +++ b/2018/day15/test-input-2 @@ -0,0 +1,7 @@ +####### +#G..#E# +#E#E.E# +#G.##.# +#...#E# +#...E.# +####### diff --git a/2018/day15/test-input-3 b/2018/day15/test-input-3 new file mode 100644 index 0000000..58f778d --- /dev/null +++ b/2018/day15/test-input-3 @@ -0,0 +1,7 @@ +####### +#E..EG# +#.#G.E# +#E.##E# +#G..#.# +#..E#.# +####### diff --git a/2018/day15/test-input-4 b/2018/day15/test-input-4 new file mode 100644 index 0000000..6dc1c08 --- /dev/null +++ b/2018/day15/test-input-4 @@ -0,0 +1,7 @@ +####### +#E.G#.# +#.#G..# +#G.#.G# +#G..#.# +#...E.# +####### diff --git a/2018/day15/test-input-5 b/2018/day15/test-input-5 new file mode 100644 index 0000000..2343d7b --- /dev/null +++ b/2018/day15/test-input-5 @@ -0,0 +1,7 @@ +####### +#.E...# +#.#..G# +#.###.# +#E#G#G# +#...#G# +####### diff --git a/2018/day15/test-input-6 b/2018/day15/test-input-6 new file mode 100644 index 0000000..95882b2 --- /dev/null +++ b/2018/day15/test-input-6 @@ -0,0 +1,9 @@ +######### +#G......# +#.E.#...# +#..##..G# +#...##..# +#...#...# +#.G...G.# +#.....G.# +######### diff --git a/2018/day2/src/main.rs b/2018/day2/src/main.rs index 99651c8..74731b5 100644 --- a/2018/day2/src/main.rs +++ b/2018/day2/src/main.rs @@ -25,7 +25,7 @@ fn get_char_counts(input: &String) -> (bool, bool) { (has_two, has_three) } -fn calc_checksum(lines: &Vec) { +fn calc_checksum(lines: &Vec) -> i32 { let mut two_count = 0; let mut three_count = 0; for line in lines.iter() { @@ -37,24 +37,27 @@ fn calc_checksum(lines: &Vec) { three_count += 1; } } - println!("checksum: {}", two_count * three_count); + two_count * three_count } -fn find_single_char_difference(lines: &mut Vec) { +fn find_single_char_difference(lines: &mut Vec) -> String { let line = lines .pop() .expect("ran out of lines to find the single char difference!"); - let mut found = false; for other in lines.iter() { if edit_distance(&line, other) == 1 { - found = true; + let mut result = String::new(); + let mut other_iter = other.chars(); + for c in line.chars() { + if c == other_iter.nth(0).unwrap() { + result.push(c); + } + } println!("{} and {}", line, other); - break; + return result; } } - if !found { - find_single_char_difference(lines); - } + find_single_char_difference(lines) } fn main() { @@ -62,6 +65,41 @@ fn main() { .lines() .map(|line| line.unwrap()) .collect(); - calc_checksum(&lines); - find_single_char_difference(&mut lines); + let checksum = calc_checksum(&lines); + println!("checksum: {}", checksum); + let common_chars = find_single_char_difference(&mut lines); + println!("common chars: {}", common_chars); +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_part_one() { + let ex1 = vec![ + String::from("abcdef"), + String::from("bababc"), + String::from("abbcde"), + String::from("abcccd"), + String::from("aabcdd"), + String::from("abcdee"), + String::from("ababab"), + ]; + assert_eq!(calc_checksum(&ex1), 12); + } + + #[test] + fn test_part_two() { + let mut ex1 = vec![ + String::from("abcde"), + String::from("fghij"), + String::from("klmno"), + String::from("pqrst"), + String::from("fguij"), + String::from("axcye"), + String::from("wvxyz"), + ]; + assert_eq!(find_single_char_difference(&mut ex1), String::from("fgij")); + } } diff --git a/2018/day3/src/main.rs b/2018/day3/src/main.rs index 2b2e3d5..8dd16dd 100644 --- a/2018/day3/src/main.rs +++ b/2018/day3/src/main.rs @@ -37,7 +37,7 @@ fn build_map(lines: &Vec) -> [[u8; 1000]; 1000] { map } -fn calc_overlap(map: &[[u8; 1000]; 1000]) { +fn calc_overlap(map: &[[u8; 1000]; 1000]) -> i32 { let mut squares = 0; for row in map.iter() { for col in row.iter() { @@ -46,10 +46,10 @@ fn calc_overlap(map: &[[u8; 1000]; 1000]) { } } } - println!("overlapped squares: {}", squares); + squares } -fn find_non_overlapped(lines: &Vec, map: &[[u8; 1000]; 1000]) { +fn find_non_overlapped(lines: &Vec, map: &[[u8; 1000]; 1000]) -> Option { for line in lines.iter() { let (top_x, top_y, bottom_x, bottom_y) = get_coords_from_line(line); let mut all_ones = true; @@ -65,10 +65,10 @@ fn find_non_overlapped(lines: &Vec, map: &[[u8; 1000]; 1000]) { } } if all_ones { - println!("non overlapped line: {}", line); - break; + return Some(line.to_string()); } } + None } fn main() { @@ -77,6 +77,35 @@ fn main() { .map(|line| line.unwrap()) .collect(); let map = build_map(&lines); - calc_overlap(&map); - find_non_overlapped(&lines, &map); + let squares = calc_overlap(&map); + println!("overlapped squares: {}", squares); + let line = find_non_overlapped(&lines, &map).unwrap(); + println!("non overlapped line: {}", line); +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_part_one() { + let ex1 = vec![ + String::from("#1 @ 1,3: 4x4"), + String::from("#2 @ 3,1: 4x4"), + String::from("#3 @ 5,5: 2x2"), + ]; + let map = build_map(&ex1); + assert_eq!(calc_overlap(&map), 4); + } + + #[test] + fn test_part_two() { + let ex1 = vec![ + String::from("#1 @ 1,3: 4x4"), + String::from("#2 @ 3,1: 4x4"), + String::from("#3 @ 5,5: 2x2"), + ]; + let map = build_map(&ex1); + assert_eq!(find_non_overlapped(&ex1, &map).unwrap(), ex1[2]); + } } diff --git a/2018/day4/src/main.rs b/2018/day4/src/main.rs index 0561093..6644ea8 100644 --- a/2018/day4/src/main.rs +++ b/2018/day4/src/main.rs @@ -6,7 +6,6 @@ use regex::Regex; use std::collections::HashMap; use std::fs::File; use std::io::{BufRead, BufReader}; -use std::iter::Iterator; type Day4Map = HashMap; @@ -55,7 +54,7 @@ fn calc_minutes_from_lines(lines: &mut Vec, map: &mut Day4Map, gid: u16, } } -fn get_max_from_map(map: &mut Day4Map) -> HashMap { +fn get_max_from_map(map: &mut Day4Map) -> (u16, u16) { let mut count_map: HashMap = HashMap::new(); let mut max_gid = 0; let mut max_count = 0; @@ -88,21 +87,17 @@ fn get_max_from_map(map: &mut Day4Map) -> HashMap { count_map.insert(*key, sum); } + let part_one = max_gid * max_minute; + let part_two = most_max_gid * most_max_minute_index; println!( "max guard id is {} sum {}, max minute of {} with val of {}", - max_gid, - max_count, - max_minute, - max_gid * max_minute + max_gid, max_count, max_minute, part_one ); println!( "guard {} most asleep on a single minute {} with a count of {} is {}", - most_max_gid, - most_max_minute_index, - most_max_minute, - most_max_gid * most_max_minute_index + most_max_gid, most_max_minute_index, most_max_minute, part_two ); - count_map + (part_one, part_two) } fn main() { @@ -112,12 +107,38 @@ fn main() { .collect(); let mut map = Day4Map::new(); calc_minutes_from_lines(&mut lines, &mut map, 0, 0); - /*for (key, value) in &map { - print!("{}: ", key); - for r in value.iter() { - print!("{} ", r); - } - println!(); - }*/ get_max_from_map(&mut map); } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_part_one() { + let mut lines = vec![ + String::from("[1518-11-01 00:00] Guard #10 begins shift"), + String::from("[1518-11-01 00:05] falls asleep"), + String::from("[1518-11-01 00:25] wakes up"), + String::from("[1518-11-01 00:30] falls asleep"), + String::from("[1518-11-01 00:55] wakes up"), + String::from("[1518-11-01 23:58] Guard #99 begins shift"), + String::from("[1518-11-02 00:40] falls asleep"), + String::from("[1518-11-02 00:50] wakes up"), + String::from("[1518-11-03 00:05] Guard #10 begins shift"), + String::from("[1518-11-03 00:24] falls asleep"), + String::from("[1518-11-03 00:29] wakes up"), + String::from("[1518-11-04 00:02] Guard #99 begins shift"), + String::from("[1518-11-04 00:36] falls asleep"), + String::from("[1518-11-04 00:46] wakes up"), + String::from("[1518-11-05 00:03] Guard #99 begins shift"), + String::from("[1518-11-05 00:45] falls asleep"), + String::from("[1518-11-05 00:55] wakes up"), + ]; + let mut map = Day4Map::new(); + calc_minutes_from_lines(&mut lines, &mut map, 0, 0); + let (part_one, part_two) = get_max_from_map(&mut map); + assert_eq!(part_one, 240); + assert_eq!(part_two, 4455); + } +} diff --git a/2018/day5/src/main.rs b/2018/day5/src/main.rs index a7da65f..1a76bc5 100644 --- a/2018/day5/src/main.rs +++ b/2018/day5/src/main.rs @@ -5,7 +5,6 @@ extern crate regex; use regex::Regex; use std::fs::File; use std::io::{BufRead, BufReader}; -use std::iter::Iterator; fn calc_remaining_monomers(polymers: &str) -> usize { lazy_static! { @@ -19,7 +18,7 @@ fn calc_remaining_monomers(polymers: &str) -> usize { } } -fn calc_most_significant_monomer(polymers: &str) { +fn calc_most_significant_monomer(polymers: &str) -> usize { let chars: Vec = (b'a'..=b'z').map(char::from).collect(); let mut min_letter = 'a'; let mut min_length = polymers.len(); @@ -36,6 +35,7 @@ fn calc_most_significant_monomer(polymers: &str) { "minimum new length {} found by replacing {}", min_length, min_letter ); + min_length } fn react_monomer(polymers: &str, r: Regex) -> usize { @@ -56,3 +56,22 @@ fn main() { println!("remaining polymers has size {}", reacted_len); calc_most_significant_monomer(polymers); } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_part_one() { + let polymers = "dabAcCaCBAcCcaDA"; + let reacted_len = calc_remaining_monomers(polymers); + assert_eq!(reacted_len, 10); + } + + #[test] + fn test_part_two() { + let polymers = "dabAcCaCBAcCcaDA"; + let min_len = calc_most_significant_monomer(polymers); + assert_eq!(min_len, 4); + } +} diff --git a/2018/day6/src/main.rs b/2018/day6/src/main.rs index 9178f08..a2ad38f 100644 --- a/2018/day6/src/main.rs +++ b/2018/day6/src/main.rs @@ -1,7 +1,6 @@ use std::collections::HashMap; use std::fs::File; use std::io::{BufRead, BufReader}; -use std::iter::Iterator; struct Point { x: usize, @@ -10,7 +9,7 @@ struct Point { impl Point { fn distance(&self, other: &Point) -> i64 { - ((self.x - other.x) as i64).abs() + ((self.y - other.y) as i64).abs() + (self.x as i64 - other.x as i64).abs() + (self.y as i64 - other.y as i64).abs() } } @@ -158,3 +157,37 @@ fn main() { let safe_zone = calc_safe_zone(&points, 10000); println!("safe zone area {}", safe_zone); } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_part_one() { + let points = vec![ + Point { x: 1, y: 1 }, + Point { x: 1, y: 6 }, + Point { x: 8, y: 3 }, + Point { x: 3, y: 4 }, + Point { x: 5, y: 5 }, + Point { x: 8, y: 9 }, + ]; + let (max_area_point, max_area) = calc_max_area(&points, 1, 1, 8, 9); + assert_eq!(max_area, 17); + assert_eq!(max_area_point, 5); + } + + #[test] + fn test_part_two() { + let points = vec![ + Point { x: 1, y: 1 }, + Point { x: 1, y: 6 }, + Point { x: 8, y: 3 }, + Point { x: 3, y: 4 }, + Point { x: 5, y: 5 }, + Point { x: 8, y: 9 }, + ]; + let safe_zone = calc_safe_zone(&points, 32); + assert_eq!(safe_zone, 16); + } +} diff --git a/2018/day7/src/main.rs b/2018/day7/src/main.rs index 9567613..133e464 100644 --- a/2018/day7/src/main.rs +++ b/2018/day7/src/main.rs @@ -1,7 +1,6 @@ use std::collections::{BTreeMap, HashMap}; use std::fs::File; use std::io::{BufRead, BufReader}; -use std::iter::Iterator; type Day7Map = BTreeMap>; @@ -38,7 +37,13 @@ fn calc_order(steps: &mut Day7Map) -> String { } } -fn calc_time(steps: &mut Day7Map, time_elapsed: i64, workers: &mut HashMap) -> i64 { +fn calc_time( + steps: &mut Day7Map, + time_elapsed: i64, + workers: &mut HashMap, + time_tax: i64, + total_workers: usize, +) -> i64 { let mut available: Vec = Vec::new(); // decrement workers @@ -58,7 +63,7 @@ fn calc_time(steps: &mut Day7Map, time_elapsed: i64, workers: &mut HashMap Day7Map { let mut steps: Day7Map = BTreeMap::new(); - for line in BufReader::new(File::open("input").unwrap()).lines() { + for line in BufReader::new(File::open(filename).unwrap()).lines() { let line_str = line.unwrap(); let mut chars = line_str.chars(); let prereq = chars.nth(5).unwrap(); @@ -99,9 +106,39 @@ fn main() { .or_insert(vec![prereq]); steps.entry(prereq).or_insert(vec![]); } + steps +} + +fn main() { + let steps: Day7Map = read_file("input"); print_map(&steps); let order = calc_order(&mut steps.clone()); println!("final order: {}", order); - let time = calc_time(&mut steps.clone(), 0, &mut HashMap::::new()); + let time = calc_time( + &mut steps.clone(), + 0, + &mut HashMap::::new(), + 0, + 5, + ); println!("time required for 5 workers: {}", time); } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_part_one() { + let mut steps = read_file("test-input"); + let order = calc_order(&mut steps); + assert_eq!(order, String::from("CABDFE")); + } + + #[test] + fn test_part_two() { + let mut steps = read_file("test-input"); + let time = calc_time(&mut steps, 0, &mut HashMap::::new(), 60, 2); + assert_eq!(time, 15); + } +} diff --git a/2018/day7/test-input b/2018/day7/test-input new file mode 100644 index 0000000..9ab25bf --- /dev/null +++ b/2018/day7/test-input @@ -0,0 +1,7 @@ +Step C must be finished before step A can begin. +Step C must be finished before step F can begin. +Step A must be finished before step B can begin. +Step A must be finished before step D can begin. +Step B must be finished before step E can begin. +Step D must be finished before step E can begin. +Step F must be finished before step E can begin. diff --git a/2018/day8/src/main.rs b/2018/day8/src/main.rs index 462bf38..ead7b3c 100644 --- a/2018/day8/src/main.rs +++ b/2018/day8/src/main.rs @@ -1,6 +1,5 @@ use std::fs::File; use std::io::{BufRead, BufReader}; -use std::iter::Iterator; fn calc_metadata_sum(ints: &mut Vec) -> i32 { let subnode_count = ints.remove(0); @@ -60,3 +59,22 @@ fn main() { let sum2 = calc_node_sum(&mut ints.clone()); println!("part 2 sum is {}", sum2); } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_part_one() { + let mut ints: Vec = vec![2, 3, 0, 3, 10, 11, 12, 1, 1, 0, 1, 99, 2, 1, 1, 2]; + let sum = calc_metadata_sum(&mut ints); + assert_eq!(sum, 138); + } + + #[test] + fn test_part_two() { + let mut ints: Vec = vec![2, 3, 0, 3, 10, 11, 12, 1, 1, 0, 1, 99, 2, 1, 1, 2]; + let sum = calc_node_sum(&mut ints); + assert_eq!(sum, 66); + } +} diff --git a/2018/day9/src/main.rs b/2018/day9/src/main.rs index d5adcdc..6d9628c 100644 --- a/2018/day9/src/main.rs +++ b/2018/day9/src/main.rs @@ -4,7 +4,6 @@ use regex::Regex; use std::collections::VecDeque; use std::fs::File; use std::io::{BufRead, BufReader}; -use std::iter::Iterator; fn play_game_deque(num_players: usize, max_marbles: u64) -> u64 { let mut game: VecDeque = VecDeque::with_capacity(max_marbles as usize); @@ -51,3 +50,14 @@ fn main() { } } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_part_one() { + let score = play_game_deque(9, 25); + assert_eq!(score, 32); + } +}