1
0
Fork 0

Merge branch 'master' of ssh://git.penguincoder.org:2222/penguincoder/advent-of-code

main
Andrew Coleman 2019-01-07 21:58:46 -05:00
commit 921e892ca8
26 changed files with 640 additions and 97 deletions

View File

@ -1,16 +1,13 @@
use std::fs::File;
use std::io::{BufRead, BufReader};
use std::iter::Iterator;
fn print_final_frequency(ints: &Vec<i32>) {
let frequency: i32 = ints.iter().sum();
println!("frequency is {}", frequency)
fn print_final_frequency(ints: &Vec<i32>) -> i32 {
ints.iter().sum::<i32>()
}
fn print_first_duped_frequency(line_count: usize, offsets: &Vec<i32>) {
fn print_first_duped_frequency(line_count: usize, offsets: &Vec<i32>) -> i32 {
let mut freaks: Vec<i32> = 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::<i32>().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);
}
}

View File

@ -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<Point>) -> i32 {
seconds
}
fn main() {
let lines: Vec<String> = BufReader::new(File::open("input").unwrap())
fn read_file(filename: &str) -> Vec<Point> {
let lines: Vec<String> = 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);
}
}

31
2018/day10/test-input Normal file
View File

@ -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>

View File

@ -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);
}
}

View File

@ -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<String, char>, iteratio
-1
}
fn main() {
let mut lines: Vec<String> = BufReader::new(File::open("input").unwrap())
fn read_file(filename: &str) -> (String, HashMap<String, char>) {
let mut lines: Vec<String> = 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<String, char> = 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);
}
}

16
2018/day12/test-input Normal file
View File

@ -0,0 +1,16 @@
initial state: #..#.#..##......###...###
...## => #
..#.. => #
.#... => #
.#.#. => #
.#.## => #
.##.. => #
.#### => #
#.#.# => #
#.### => #
##.#. => #
##.## => #
###.. => #
###.# => #
####. => #

View File

@ -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<String> = BufReader::new(File::open("input").unwrap())
fn read_file(filename: &str) -> ([[char; MAP_SIZE]; MAP_SIZE], Vec<Cart>) {
let lines: Vec<String> = 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);
}
}

6
2018/day13/test-input Normal file
View File

@ -0,0 +1,6 @@
/->-\
| | /----\
| /-+--+-\ |
| | | | v |
\-+-/ \-+--/
\------/

7
2018/day13/test-input-2 Normal file
View File

@ -0,0 +1,7 @@
/>-<\
| |
| /<+-\
| | | v
\>+</ |
| ^
\<->/

View File

@ -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<u8> = 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<u8> = 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<u8> = 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<u8> = 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);
}
}

View File

@ -127,7 +127,7 @@ fn find_enemy(player: &Player, map: &MapType) -> Option<PlayerVector> {
'E' => continue,
'G' => continue,
'#' => continue,
_ => ()
_ => (),
}
}
queue.push_back(PlayerVector {
@ -294,13 +294,15 @@ fn play_game(mut players: Vec<Player>, 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<String> = BufReader::new(File::open("input").unwrap())
fn read_file(filename: &str) -> (Vec<Player>, [[char; MAP_SIZE]; MAP_SIZE], usize) {
let lines: Vec<String> = BufReader::new(File::open(filename).unwrap())
.lines()
.map(|line| line.unwrap())
.collect();
@ -336,10 +338,20 @@ 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<Player> = players.clone().into_iter().map(|p| {
let new_players: Vec<Player> = players
.clone()
.into_iter()
.map(|p| {
if p.player_type == 'G' {
p
} else {
@ -351,14 +363,65 @@ fn main() {
attack: i,
hp: 200,
player_type: 'E',
enemy_type: 'G'
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);
}
}

7
2018/day15/test-input-1 Normal file
View File

@ -0,0 +1,7 @@
#######
#.G...#
#...EG#
#.#.#G#
#..G#E#
#.....#
#######

7
2018/day15/test-input-2 Normal file
View File

@ -0,0 +1,7 @@
#######
#G..#E#
#E#E.E#
#G.##.#
#...#E#
#...E.#
#######

7
2018/day15/test-input-3 Normal file
View File

@ -0,0 +1,7 @@
#######
#E..EG#
#.#G.E#
#E.##E#
#G..#.#
#..E#.#
#######

7
2018/day15/test-input-4 Normal file
View File

@ -0,0 +1,7 @@
#######
#E.G#.#
#.#G..#
#G.#.G#
#G..#.#
#...E.#
#######

7
2018/day15/test-input-5 Normal file
View File

@ -0,0 +1,7 @@
#######
#.E...#
#.#..G#
#.###.#
#E#G#G#
#...#G#
#######

9
2018/day15/test-input-6 Normal file
View File

@ -0,0 +1,9 @@
#########
#G......#
#.E.#...#
#..##..G#
#...##..#
#...#...#
#.G...G.#
#.....G.#
#########

View File

@ -25,7 +25,7 @@ fn get_char_counts(input: &String) -> (bool, bool) {
(has_two, has_three)
}
fn calc_checksum(lines: &Vec<String>) {
fn calc_checksum(lines: &Vec<String>) -> 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<String>) {
three_count += 1;
}
}
println!("checksum: {}", two_count * three_count);
two_count * three_count
}
fn find_single_char_difference(lines: &mut Vec<String>) {
fn find_single_char_difference(lines: &mut Vec<String>) -> 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"));
}
}

View File

@ -37,7 +37,7 @@ fn build_map(lines: &Vec<String>) -> [[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<String>, map: &[[u8; 1000]; 1000]) {
fn find_non_overlapped(lines: &Vec<String>, map: &[[u8; 1000]; 1000]) -> Option<String> {
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<String>, 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]);
}
}

View File

@ -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<u16, [u16; 60]>;
@ -55,7 +54,7 @@ fn calc_minutes_from_lines(lines: &mut Vec<String>, map: &mut Day4Map, gid: u16,
}
}
fn get_max_from_map(map: &mut Day4Map) -> HashMap<u16, u16> {
fn get_max_from_map(map: &mut Day4Map) -> (u16, u16) {
let mut count_map: HashMap<u16, u16> = 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<u16, u16> {
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);
}
}

View File

@ -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<char> = (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);
}
}

View File

@ -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);
}
}

View File

@ -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<char, Vec<char>>;
@ -38,7 +37,13 @@ fn calc_order(steps: &mut Day7Map) -> String {
}
}
fn calc_time(steps: &mut Day7Map, time_elapsed: i64, workers: &mut HashMap<char, i64>) -> i64 {
fn calc_time(
steps: &mut Day7Map,
time_elapsed: i64,
workers: &mut HashMap<char, i64>,
time_tax: i64,
total_workers: usize,
) -> i64 {
let mut available: Vec<char> = Vec::new();
// decrement workers
@ -58,7 +63,7 @@ fn calc_time(steps: &mut Day7Map, time_elapsed: i64, workers: &mut HashMap<char,
}
});
let mut needed_workers = 5 - workers.len();
let mut needed_workers = total_workers - workers.len();
let mut needs_work = false;
for (key, values) in steps.iter_mut() {
if values.is_empty() {
@ -81,14 +86,16 @@ fn calc_time(steps: &mut Day7Map, time_elapsed: i64, workers: &mut HashMap<char,
for new_step in available.iter() {
// add new work
workers.entry(*new_step).or_insert(*new_step as i64 - 4);
workers
.entry(*new_step)
.or_insert(*new_step as i64 - 4 - time_tax);
}
calc_time(steps, time_elapsed + 1, workers)
calc_time(steps, time_elapsed + 1, workers, time_tax, total_workers)
}
fn main() {
fn read_file(filename: &str) -> 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::<char, i64>::new());
let time = calc_time(
&mut steps.clone(),
0,
&mut HashMap::<char, i64>::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::<char, i64>::new(), 60, 2);
assert_eq!(time, 15);
}
}

7
2018/day7/test-input Normal file
View File

@ -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.

View File

@ -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>) -> 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<i32> = 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<i32> = 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);
}
}

View File

@ -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<u64> = 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);
}
}