add tests and test-input files
parent
d707a1412c
commit
6abad505d1
|
@ -1,16 +1,13 @@
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{BufRead, BufReader};
|
use std::io::{BufRead, BufReader};
|
||||||
use std::iter::Iterator;
|
|
||||||
|
|
||||||
fn print_final_frequency(ints: &Vec<i32>) {
|
fn print_final_frequency(ints: &Vec<i32>) -> i32 {
|
||||||
let frequency: i32 = ints.iter().sum();
|
ints.iter().sum::<i32>()
|
||||||
println!("frequency is {}", frequency)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 mut freaks: Vec<i32> = vec![0];
|
||||||
let first_duped_frequency = duped_frequency(0, line_count, offsets, &mut freaks);
|
duped_frequency(0, line_count, offsets, &mut freaks)
|
||||||
println!("first duped frequency is {}", first_duped_frequency);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn duped_frequency(
|
fn duped_frequency(
|
||||||
|
@ -43,6 +40,35 @@ fn main() {
|
||||||
.map(|line| line.unwrap().parse::<i32>().unwrap())
|
.map(|line| line.unwrap().parse::<i32>().unwrap())
|
||||||
.collect();
|
.collect();
|
||||||
let line_count: usize = ints.len();
|
let line_count: usize = ints.len();
|
||||||
print_final_frequency(&ints);
|
let frequency = print_final_frequency(&ints);
|
||||||
print_first_duped_frequency(line_count, &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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ use regex::Regex;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{BufRead, BufReader};
|
use std::io::{BufRead, BufReader};
|
||||||
use std::iter::Iterator;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Point {
|
struct Point {
|
||||||
|
@ -86,8 +85,8 @@ fn tick(points: &mut Vec<Point>) -> i32 {
|
||||||
seconds
|
seconds
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn read_file(filename: &str) -> Vec<Point> {
|
||||||
let lines: Vec<String> = BufReader::new(File::open("input").unwrap())
|
let lines: Vec<String> = BufReader::new(File::open(filename).unwrap())
|
||||||
.lines()
|
.lines()
|
||||||
.map(|line| line.unwrap())
|
.map(|line| line.unwrap())
|
||||||
.collect();
|
.collect();
|
||||||
|
@ -109,6 +108,23 @@ fn main() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
points
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut points = read_file("input");
|
||||||
let seconds = tick(&mut points);
|
let seconds = tick(&mut points);
|
||||||
println!("time elapsed: {}", seconds);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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>
|
|
@ -1,6 +1,5 @@
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{BufRead, BufReader};
|
use std::io::{BufRead, BufReader};
|
||||||
use std::iter::Iterator;
|
|
||||||
|
|
||||||
fn calc_map_from_serial_number(serial_number: i32) -> [[i32; 300]; 300] {
|
fn calc_map_from_serial_number(serial_number: i32) -> [[i32; 300]; 300] {
|
||||||
let mut result = [[0i32; 300]; 300];
|
let mut result = [[0i32; 300]; 300];
|
||||||
|
@ -91,3 +90,38 @@ fn main() {
|
||||||
x, y, sum, size
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{BufRead, BufReader};
|
use std::io::{BufRead, BufReader};
|
||||||
use std::iter::Iterator;
|
|
||||||
|
|
||||||
const MAP_SIZE: usize = 500;
|
const MAP_SIZE: usize = 500;
|
||||||
const MAP_ZERO_INDEX: usize = 200;
|
const MAP_ZERO_INDEX: usize = 200;
|
||||||
|
@ -10,7 +9,7 @@ fn get_score(state: &[char; MAP_SIZE]) -> i64 {
|
||||||
let mut score = 0;
|
let mut score = 0;
|
||||||
for i in 0..MAP_SIZE {
|
for i in 0..MAP_SIZE {
|
||||||
if state[i] == '#' {
|
if state[i] == '#' {
|
||||||
score += (i - MAP_ZERO_INDEX) as i64;
|
score += i as i64 - MAP_ZERO_INDEX as i64;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
score
|
score
|
||||||
|
@ -73,14 +72,14 @@ fn find_big_score(initial_state: String, states: HashMap<String, char>, iteratio
|
||||||
-1
|
-1
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn read_file(filename: &str) -> (String, HashMap<String, char>) {
|
||||||
let mut lines: Vec<String> = BufReader::new(File::open("input").unwrap())
|
let mut lines: Vec<String> = BufReader::new(File::open(filename).unwrap())
|
||||||
.lines()
|
.lines()
|
||||||
.map(|line| line.unwrap())
|
.map(|line| line.unwrap())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let mut default_state = lines.remove(0);
|
let mut initial_state = lines.remove(0);
|
||||||
default_state.replace_range(0..15, "");
|
initial_state.replace_range(0..15, "");
|
||||||
lines.remove(0);
|
lines.remove(0);
|
||||||
let mut states: HashMap<String, char> = HashMap::new();
|
let mut states: HashMap<String, char> = HashMap::new();
|
||||||
for line in lines.iter() {
|
for line in lines.iter() {
|
||||||
|
@ -95,9 +94,26 @@ fn main() {
|
||||||
states.insert(state, dest);
|
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);
|
println!("part 1 score after 20 generations: {}", part1score);
|
||||||
let iterations = 50000000000;
|
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);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
initial state: #..#.#..##......###...###
|
||||||
|
|
||||||
|
...## => #
|
||||||
|
..#.. => #
|
||||||
|
.#... => #
|
||||||
|
.#.#. => #
|
||||||
|
.#.## => #
|
||||||
|
.##.. => #
|
||||||
|
.#### => #
|
||||||
|
#.#.# => #
|
||||||
|
#.### => #
|
||||||
|
##.#. => #
|
||||||
|
##.## => #
|
||||||
|
###.. => #
|
||||||
|
###.# => #
|
||||||
|
####. => #
|
|
@ -80,8 +80,8 @@ fn find_collision(
|
||||||
if carts[i].removed {
|
if carts[i].removed {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let next_x = carts[i].x + carts[i].x_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 + carts[i].y_delta as usize;
|
let next_y = (carts[i].y as isize + carts[i].y_delta as isize) as usize;
|
||||||
|
|
||||||
for j in 0..cart_len {
|
for j in 0..cart_len {
|
||||||
if i != j && !carts[j].removed && carts[j].x == next_x && carts[j].y == next_y {
|
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
|
ticks += 1; // gross
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn read_file(filename: &str) -> ([[char; MAP_SIZE]; MAP_SIZE], Vec<Cart>) {
|
||||||
fn main() {
|
let lines: Vec<String> = BufReader::new(File::open(filename).unwrap())
|
||||||
let lines: Vec<String> = BufReader::new(File::open("input").unwrap())
|
|
||||||
.lines()
|
.lines()
|
||||||
.map(|line| line.unwrap())
|
.map(|line| line.unwrap())
|
||||||
.collect();
|
.collect();
|
||||||
|
@ -194,6 +193,11 @@ fn main() {
|
||||||
}
|
}
|
||||||
line_number += 1;
|
line_number += 1;
|
||||||
}
|
}
|
||||||
|
(map, carts)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let (map, carts) = read_file("input");
|
||||||
let (x, y, ticks) = find_collision(&map, &mut carts.clone(), false);
|
let (x, y, ticks) = find_collision(&map, &mut carts.clone(), false);
|
||||||
println!("found collision at {},{} after {} ticks", x, y, ticks);
|
println!("found collision at {},{} after {} ticks", x, y, ticks);
|
||||||
let (x, y, ticks) = find_collision(&map, &mut carts.clone(), true);
|
let (x, y, ticks) = find_collision(&map, &mut carts.clone(), true);
|
||||||
|
@ -202,3 +206,26 @@ fn main() {
|
||||||
x, y, ticks
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
/->-\
|
||||||
|
| | /----\
|
||||||
|
| /-+--+-\ |
|
||||||
|
| | | | v |
|
||||||
|
\-+-/ \-+--/
|
||||||
|
\------/
|
|
@ -0,0 +1,7 @@
|
||||||
|
/>-<\
|
||||||
|
| |
|
||||||
|
| /<+-\
|
||||||
|
| | | v
|
||||||
|
\>+</ |
|
||||||
|
| ^
|
||||||
|
\<->/
|
|
@ -49,3 +49,48 @@ fn main() {
|
||||||
println!("part 1 final score {}", final_score);
|
println!("part 1 final score {}", final_score);
|
||||||
println!("recipe repeated at index {}", final_index);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -127,7 +127,7 @@ fn find_enemy(player: &Player, map: &MapType) -> Option<PlayerVector> {
|
||||||
'E' => continue,
|
'E' => continue,
|
||||||
'G' => continue,
|
'G' => continue,
|
||||||
'#' => continue,
|
'#' => continue,
|
||||||
_ => ()
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
queue.push_back(PlayerVector {
|
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();
|
let sum: i32 = players.iter().map(|p| p.hp as i32).sum();
|
||||||
info!("sum {} rounds {}", sum, rounds);
|
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)
|
(sum * rounds, elf_count)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn read_file(filename: &str) -> (Vec<Player>, [[char; MAP_SIZE]; MAP_SIZE], usize) {
|
||||||
pretty_env_logger::init();
|
let lines: Vec<String> = BufReader::new(File::open(filename).unwrap())
|
||||||
let lines: Vec<String> = BufReader::new(File::open("input").unwrap())
|
|
||||||
.lines()
|
.lines()
|
||||||
.map(|line| line.unwrap())
|
.map(|line| line.unwrap())
|
||||||
.collect();
|
.collect();
|
||||||
|
@ -336,29 +338,90 @@ fn main() {
|
||||||
}
|
}
|
||||||
y += 1;
|
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());
|
let (score, _elves_remaining) = play_game(players.clone(), &mut map.clone());
|
||||||
println!("score of winning team is {}", score);
|
println!("score of winning team is {}", score);
|
||||||
for i in 4..50 {
|
for i in 4..50 {
|
||||||
let new_players: Vec<Player> = players.clone().into_iter().map(|p| {
|
let new_players: Vec<Player> = players
|
||||||
if p.player_type == 'G' {
|
.clone()
|
||||||
p
|
.into_iter()
|
||||||
} else {
|
.map(|p| {
|
||||||
Player {
|
if p.player_type == 'G' {
|
||||||
id: p.id,
|
p
|
||||||
x: p.x,
|
} else {
|
||||||
y: p.y,
|
Player {
|
||||||
dead: false,
|
id: p.id,
|
||||||
attack: i,
|
x: p.x,
|
||||||
hp: 200,
|
y: p.y,
|
||||||
player_type: 'E',
|
dead: false,
|
||||||
enemy_type: 'G'
|
attack: i,
|
||||||
|
hp: 200,
|
||||||
|
player_type: 'E',
|
||||||
|
enemy_type: 'G',
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
}).collect();
|
.collect();
|
||||||
let (score, elves_remaining) = play_game(new_players, &mut map.clone());
|
let (score, elves_remaining) = play_game(new_players, &mut map.clone());
|
||||||
if elves_remaining == elf_count {
|
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;
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
#######
|
||||||
|
#.G...#
|
||||||
|
#...EG#
|
||||||
|
#.#.#G#
|
||||||
|
#..G#E#
|
||||||
|
#.....#
|
||||||
|
#######
|
|
@ -0,0 +1,7 @@
|
||||||
|
#######
|
||||||
|
#G..#E#
|
||||||
|
#E#E.E#
|
||||||
|
#G.##.#
|
||||||
|
#...#E#
|
||||||
|
#...E.#
|
||||||
|
#######
|
|
@ -0,0 +1,7 @@
|
||||||
|
#######
|
||||||
|
#E..EG#
|
||||||
|
#.#G.E#
|
||||||
|
#E.##E#
|
||||||
|
#G..#.#
|
||||||
|
#..E#.#
|
||||||
|
#######
|
|
@ -0,0 +1,7 @@
|
||||||
|
#######
|
||||||
|
#E.G#.#
|
||||||
|
#.#G..#
|
||||||
|
#G.#.G#
|
||||||
|
#G..#.#
|
||||||
|
#...E.#
|
||||||
|
#######
|
|
@ -0,0 +1,7 @@
|
||||||
|
#######
|
||||||
|
#.E...#
|
||||||
|
#.#..G#
|
||||||
|
#.###.#
|
||||||
|
#E#G#G#
|
||||||
|
#...#G#
|
||||||
|
#######
|
|
@ -0,0 +1,9 @@
|
||||||
|
#########
|
||||||
|
#G......#
|
||||||
|
#.E.#...#
|
||||||
|
#..##..G#
|
||||||
|
#...##..#
|
||||||
|
#...#...#
|
||||||
|
#.G...G.#
|
||||||
|
#.....G.#
|
||||||
|
#########
|
|
@ -25,7 +25,7 @@ fn get_char_counts(input: &String) -> (bool, bool) {
|
||||||
(has_two, has_three)
|
(has_two, has_three)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn calc_checksum(lines: &Vec<String>) {
|
fn calc_checksum(lines: &Vec<String>) -> i32 {
|
||||||
let mut two_count = 0;
|
let mut two_count = 0;
|
||||||
let mut three_count = 0;
|
let mut three_count = 0;
|
||||||
for line in lines.iter() {
|
for line in lines.iter() {
|
||||||
|
@ -37,24 +37,27 @@ fn calc_checksum(lines: &Vec<String>) {
|
||||||
three_count += 1;
|
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
|
let line = lines
|
||||||
.pop()
|
.pop()
|
||||||
.expect("ran out of lines to find the single char difference!");
|
.expect("ran out of lines to find the single char difference!");
|
||||||
let mut found = false;
|
|
||||||
for other in lines.iter() {
|
for other in lines.iter() {
|
||||||
if edit_distance(&line, other) == 1 {
|
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);
|
println!("{} and {}", line, other);
|
||||||
break;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !found {
|
find_single_char_difference(lines)
|
||||||
find_single_char_difference(lines);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -62,6 +65,41 @@ fn main() {
|
||||||
.lines()
|
.lines()
|
||||||
.map(|line| line.unwrap())
|
.map(|line| line.unwrap())
|
||||||
.collect();
|
.collect();
|
||||||
calc_checksum(&lines);
|
let checksum = calc_checksum(&lines);
|
||||||
find_single_char_difference(&mut 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"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ fn build_map(lines: &Vec<String>) -> [[u8; 1000]; 1000] {
|
||||||
map
|
map
|
||||||
}
|
}
|
||||||
|
|
||||||
fn calc_overlap(map: &[[u8; 1000]; 1000]) {
|
fn calc_overlap(map: &[[u8; 1000]; 1000]) -> i32 {
|
||||||
let mut squares = 0;
|
let mut squares = 0;
|
||||||
for row in map.iter() {
|
for row in map.iter() {
|
||||||
for col in row.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() {
|
for line in lines.iter() {
|
||||||
let (top_x, top_y, bottom_x, bottom_y) = get_coords_from_line(line);
|
let (top_x, top_y, bottom_x, bottom_y) = get_coords_from_line(line);
|
||||||
let mut all_ones = true;
|
let mut all_ones = true;
|
||||||
|
@ -65,10 +65,10 @@ fn find_non_overlapped(lines: &Vec<String>, map: &[[u8; 1000]; 1000]) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if all_ones {
|
if all_ones {
|
||||||
println!("non overlapped line: {}", line);
|
return Some(line.to_string());
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -77,6 +77,35 @@ fn main() {
|
||||||
.map(|line| line.unwrap())
|
.map(|line| line.unwrap())
|
||||||
.collect();
|
.collect();
|
||||||
let map = build_map(&lines);
|
let map = build_map(&lines);
|
||||||
calc_overlap(&map);
|
let squares = calc_overlap(&map);
|
||||||
find_non_overlapped(&lines, &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]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@ use regex::Regex;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{BufRead, BufReader};
|
use std::io::{BufRead, BufReader};
|
||||||
use std::iter::Iterator;
|
|
||||||
|
|
||||||
type Day4Map = HashMap<u16, [u16; 60]>;
|
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 count_map: HashMap<u16, u16> = HashMap::new();
|
||||||
let mut max_gid = 0;
|
let mut max_gid = 0;
|
||||||
let mut max_count = 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);
|
count_map.insert(*key, sum);
|
||||||
}
|
}
|
||||||
|
let part_one = max_gid * max_minute;
|
||||||
|
let part_two = most_max_gid * most_max_minute_index;
|
||||||
println!(
|
println!(
|
||||||
"max guard id is {} sum {}, max minute of {} with val of {}",
|
"max guard id is {} sum {}, max minute of {} with val of {}",
|
||||||
max_gid,
|
max_gid, max_count, max_minute, part_one
|
||||||
max_count,
|
|
||||||
max_minute,
|
|
||||||
max_gid * max_minute
|
|
||||||
);
|
);
|
||||||
println!(
|
println!(
|
||||||
"guard {} most asleep on a single minute {} with a count of {} is {}",
|
"guard {} most asleep on a single minute {} with a count of {} is {}",
|
||||||
most_max_gid,
|
most_max_gid, most_max_minute_index, most_max_minute, part_two
|
||||||
most_max_minute_index,
|
|
||||||
most_max_minute,
|
|
||||||
most_max_gid * most_max_minute_index
|
|
||||||
);
|
);
|
||||||
count_map
|
(part_one, part_two)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -112,12 +107,38 @@ fn main() {
|
||||||
.collect();
|
.collect();
|
||||||
let mut map = Day4Map::new();
|
let mut map = Day4Map::new();
|
||||||
calc_minutes_from_lines(&mut lines, &mut map, 0, 0);
|
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);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@ extern crate regex;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{BufRead, BufReader};
|
use std::io::{BufRead, BufReader};
|
||||||
use std::iter::Iterator;
|
|
||||||
|
|
||||||
fn calc_remaining_monomers(polymers: &str) -> usize {
|
fn calc_remaining_monomers(polymers: &str) -> usize {
|
||||||
lazy_static! {
|
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 chars: Vec<char> = (b'a'..=b'z').map(char::from).collect();
|
||||||
let mut min_letter = 'a';
|
let mut min_letter = 'a';
|
||||||
let mut min_length = polymers.len();
|
let mut min_length = polymers.len();
|
||||||
|
@ -36,6 +35,7 @@ fn calc_most_significant_monomer(polymers: &str) {
|
||||||
"minimum new length {} found by replacing {}",
|
"minimum new length {} found by replacing {}",
|
||||||
min_length, min_letter
|
min_length, min_letter
|
||||||
);
|
);
|
||||||
|
min_length
|
||||||
}
|
}
|
||||||
|
|
||||||
fn react_monomer(polymers: &str, r: Regex) -> usize {
|
fn react_monomer(polymers: &str, r: Regex) -> usize {
|
||||||
|
@ -56,3 +56,22 @@ fn main() {
|
||||||
println!("remaining polymers has size {}", reacted_len);
|
println!("remaining polymers has size {}", reacted_len);
|
||||||
calc_most_significant_monomer(polymers);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{BufRead, BufReader};
|
use std::io::{BufRead, BufReader};
|
||||||
use std::iter::Iterator;
|
|
||||||
|
|
||||||
struct Point {
|
struct Point {
|
||||||
x: usize,
|
x: usize,
|
||||||
|
@ -10,7 +9,7 @@ struct Point {
|
||||||
|
|
||||||
impl Point {
|
impl Point {
|
||||||
fn distance(&self, other: &Point) -> i64 {
|
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);
|
let safe_zone = calc_safe_zone(&points, 10000);
|
||||||
println!("safe zone area {}", safe_zone);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use std::collections::{BTreeMap, HashMap};
|
use std::collections::{BTreeMap, HashMap};
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{BufRead, BufReader};
|
use std::io::{BufRead, BufReader};
|
||||||
use std::iter::Iterator;
|
|
||||||
|
|
||||||
type Day7Map = BTreeMap<char, Vec<char>>;
|
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();
|
let mut available: Vec<char> = Vec::new();
|
||||||
|
|
||||||
// decrement workers
|
// 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;
|
let mut needs_work = false;
|
||||||
for (key, values) in steps.iter_mut() {
|
for (key, values) in steps.iter_mut() {
|
||||||
if values.is_empty() {
|
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() {
|
for new_step in available.iter() {
|
||||||
// add new work
|
// 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();
|
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 line_str = line.unwrap();
|
||||||
let mut chars = line_str.chars();
|
let mut chars = line_str.chars();
|
||||||
let prereq = chars.nth(5).unwrap();
|
let prereq = chars.nth(5).unwrap();
|
||||||
|
@ -99,9 +106,39 @@ fn main() {
|
||||||
.or_insert(vec![prereq]);
|
.or_insert(vec![prereq]);
|
||||||
steps.entry(prereq).or_insert(vec![]);
|
steps.entry(prereq).or_insert(vec![]);
|
||||||
}
|
}
|
||||||
|
steps
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let steps: Day7Map = read_file("input");
|
||||||
print_map(&steps);
|
print_map(&steps);
|
||||||
let order = calc_order(&mut steps.clone());
|
let order = calc_order(&mut steps.clone());
|
||||||
println!("final order: {}", order);
|
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);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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.
|
|
@ -1,6 +1,5 @@
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{BufRead, BufReader};
|
use std::io::{BufRead, BufReader};
|
||||||
use std::iter::Iterator;
|
|
||||||
|
|
||||||
fn calc_metadata_sum(ints: &mut Vec<i32>) -> i32 {
|
fn calc_metadata_sum(ints: &mut Vec<i32>) -> i32 {
|
||||||
let subnode_count = ints.remove(0);
|
let subnode_count = ints.remove(0);
|
||||||
|
@ -60,3 +59,22 @@ fn main() {
|
||||||
let sum2 = calc_node_sum(&mut ints.clone());
|
let sum2 = calc_node_sum(&mut ints.clone());
|
||||||
println!("part 2 sum is {}", sum2);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ use regex::Regex;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{BufRead, BufReader};
|
use std::io::{BufRead, BufReader};
|
||||||
use std::iter::Iterator;
|
|
||||||
|
|
||||||
fn play_game_deque(num_players: usize, max_marbles: u64) -> u64 {
|
fn play_game_deque(num_players: usize, max_marbles: u64) -> u64 {
|
||||||
let mut game: VecDeque<u64> = VecDeque::with_capacity(max_marbles as usize);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue