-use std::{iter::Iterator, io::BufRead, ops::AddAssign, cmp::Reverse};
+use std::{cmp::Reverse, io::BufRead, iter::Iterator, ops::AddAssign};
use itertools::*;
pub fn read_calories<R>(reader: R) -> Vec<i64>
where
- R: BufRead
+ R: BufRead,
{
let mut calories = vec![0i64];
for l in reader.lines() {
if trimmed == "" {
calories.push(0);
} else {
- calories.last_mut().unwrap().add_assign(trimmed.parse::<i64>().unwrap());
+ calories
+ .last_mut()
+ .unwrap()
+ .add_assign(trimmed.parse::<i64>().unwrap());
}
}
calories
}
pub fn get_sum_most_three_calories(calories: &[i64]) -> i64 {
- calories.iter().map(Reverse).k_smallest(3).fold(0, |s, v| s + v.0)
+ calories
+ .iter()
+ .map(Reverse)
+ .k_smallest(3)
+ .fold(0, |s, v| s + v.0)
}
#[cfg(test)]
mod tests {
use super::*;
- static CALORIES: &str =
- "1000
+ static CALORIES: &str = "1000
2000
3000
#[test]
fn part1() {
- assert_eq!(get_most_calories(&read_calories(CALORIES.as_bytes())), 24000);
+ assert_eq!(
+ get_most_calories(&read_calories(CALORIES.as_bytes())),
+ 24000
+ );
}
#[test]
fn part2() {
- assert_eq!(get_sum_most_three_calories(&read_calories(CALORIES.as_bytes())), 45000);
+ assert_eq!(
+ get_sum_most_three_calories(&read_calories(CALORIES.as_bytes())),
+ 45000
+ );
}
-
-}
\ No newline at end of file
+}
impl Shape {
pub fn battle(&self, other: &Shape) -> i32 {
(match (self, other) {
- (Shape::Rock, Shape::Scissors) |
- (Shape::Paper, Shape::Rock) |
- (Shape::Scissors, Shape::Paper) => 6,
+ (Shape::Rock, Shape::Scissors)
+ | (Shape::Paper, Shape::Rock)
+ | (Shape::Scissors, Shape::Paper) => 6,
(a, b) if a == b => 3,
_ => 0,
- }) +
- match self { Shape::Rock => 1, Shape::Paper => 2, Shape::Scissors => 3, }
+ }) + match self {
+ Shape::Rock => 1,
+ Shape::Paper => 2,
+ Shape::Scissors => 3,
+ }
}
pub fn parse(str: &str) -> Self {
"A" | "X" => Shape::Rock,
"B" | "Y" => Shape::Paper,
"C" | "Z" => Shape::Scissors,
- _ => panic!("Unknown letter: {}", str)
+ _ => panic!("Unknown letter: {}", str),
}
}
}
pub fn read_shapes<R>(reader: R) -> Vec<(Shape, Shape)>
where
- R: BufRead
+ R: BufRead,
{
let mut shapes: Vec<(Shape, Shape)> = Vec::new();
for l in reader.lines() {
pub fn read_shapes_2<R>(reader: R) -> Vec<(Shape, Shape)>
where
- R: BufRead
+ R: BufRead,
{
let mut shapes: Vec<(Shape, Shape)> = Vec::new();
for l in reader.lines() {
let l: Vec<&str> = l.trim().split(' ').collect();
let s1: Shape = Shape::parse(l[0]);
let s2 = match l[1] {
- "X" => match s1 { Shape::Rock => Shape::Scissors, Shape::Paper => Shape::Rock, Shape::Scissors => Shape::Paper, }, // Need to lose.
- "Z" => match s1 { Shape::Rock => Shape::Paper, Shape::Paper => Shape::Scissors, Shape::Scissors => Shape::Rock, }, // Need to win.
+ // Need to lose.
+ "X" => match s1 {
+ Shape::Rock => Shape::Scissors,
+ Shape::Paper => Shape::Rock,
+ Shape::Scissors => Shape::Paper,
+ },
+ // Need to win.
+ "Z" => match s1 {
+ Shape::Rock => Shape::Paper,
+ Shape::Paper => Shape::Scissors,
+ Shape::Scissors => Shape::Rock,
+ },
_ => s1, // Draw.
};
mod tests {
use super::*;
- static STRATEGY_GUIDE: &str =
- "A Y
- B X
- C Z";
+ static STRATEGY_GUIDE: &str = "A Y
+ B X
+ C Z";
#[test]
fn part1() {
fn part2() {
assert_eq!(get_score(&read_shapes_2(STRATEGY_GUIDE.as_bytes())), 12);
}
-}
\ No newline at end of file
+}
pub fn parse(s: &str) -> Vec<Vec<u8>> {
s.lines()
- .map(|l| {
- l.as_bytes().into_iter().map(letter_to_priority).collect()
- }).collect()
+ .map(|l| l.as_bytes().into_iter().map(letter_to_priority).collect())
+ .collect()
}
fn letter_to_priority(v: &u8) -> u8 {
- if *v >= 97 { // >= 'a'
+ if *v >= 97 {
+ // >= 'a'
v - 96
- } else { // < 'a'
+ } else {
+ // < 'a'
v - 38
}
}
mod tests {
use super::*;
- static RUCKSACKS: &str =
- "vJrwpWtwJgWrhcsFMMfFFhFp
+ static RUCKSACKS: &str = "vJrwpWtwJgWrhcsFMMfFFhFp
jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL
PmmdzqPrVvPwwTWBwg
wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn
fn part2() {
assert_eq!(badge_sum(&parse(RUCKSACKS)), 70);
}
-}
\ No newline at end of file
+}
let r = Regex::new(r"^(\d+)-(\d+),(\d+)-(\d+)$").unwrap();
for l in s.lines() {
let cap = r.captures(l).unwrap();
- sections.push(((cap[1].parse::<i32>().unwrap(), cap[2].parse::<i32>().unwrap()), (cap[3].parse::<i32>().unwrap(), cap[4].parse::<i32>().unwrap())));
+ sections.push((
+ (
+ cap[1].parse::<i32>().unwrap(),
+ cap[2].parse::<i32>().unwrap(),
+ ),
+ (
+ cap[3].parse::<i32>().unwrap(),
+ cap[4].parse::<i32>().unwrap(),
+ ),
+ ));
}
return sections;
}
pub fn number_fully_contain(pairs: &[Pair]) -> i32 {
- pairs.iter().filter_map(|((a1, a2), (b1, b2))| {
- if a1 <= b1 && a2 >= b2 || b1 <= a1 && b2 >= a2 { Some(1) } else { None }
- }).sum()
+ pairs
+ .iter()
+ .filter_map(|((a1, a2), (b1, b2))| {
+ if a1 <= b1 && a2 >= b2 || b1 <= a1 && b2 >= a2 {
+ Some(1)
+ } else {
+ None
+ }
+ })
+ .sum()
}
pub fn number_overlaps(pairs: &[Pair]) -> i32 {
- pairs.iter().filter_map(|((a1, a2), (b1, b2))| {
- if a2 >= b1 && a1 <= b2 { Some(1) } else { None }
- }).sum()
+ pairs
+ .iter()
+ .filter_map(
+ |((a1, a2), (b1, b2))| {
+ if a2 >= b1 && a1 <= b2 {
+ Some(1)
+ } else {
+ None
+ }
+ },
+ )
+ .sum()
}
#[cfg(test)]
mod tests {
use super::*;
- static PAIRS: &str ="2-4,6-8
+ static PAIRS: &str = "2-4,6-8
2-3,4-5
5-7,7-9
2-8,3-7
fn part2() {
assert_eq!(number_overlaps(&parse(PAIRS)), 4);
}
-}
\ No newline at end of file
+}
let mut moves = Vec::new();
while let Some(line) = lines.next() {
let cap = r.captures(line).unwrap();
- moves.push(Move { n: cap[1].parse().unwrap(), from: cap[2].parse::<usize>().unwrap() - 1, to: cap[3].parse::<usize>().unwrap() - 1 });
+ moves.push(Move {
+ n: cap[1].parse().unwrap(),
+ from: cap[2].parse::<usize>().unwrap() - 1,
+ to: cap[3].parse::<usize>().unwrap() - 1,
+ });
}
(stacks, moves)
mod tests {
use super::*;
- static STACKS_AND_MOVES: &str =" [D]
+ static STACKS_AND_MOVES: &str = " [D]
[N] [C]
[Z] [M] [P]
1 2 3
apply_moves_by_crate_mover_9001(&mut stacks, &moves);
assert_eq!(get_top_as_string(&stacks), "MCD");
}
-}
\ No newline at end of file
+}
// Warning: O(n^2).
fn contains_same_char(chars: &[char]) -> bool {
for i in 0..chars.len() {
- for j in i+1..chars.len() {
+ for j in i + 1..chars.len() {
if chars[i] == chars[j] {
return true;
}
assert_eq!(first_marker_pos("mjqjpqmgbljsphdztnvjfqwrcgsmlb", 14), 19);
assert_eq!(first_marker_pos("bvwbjplbgvbhsrlpgdmjqwftvncz", 14), 23);
assert_eq!(first_marker_pos("nppdvjthqldpwncqszvftbrmjlhg", 14), 23);
- assert_eq!(first_marker_pos("nznrnfrfntjfmvfwmzdfjlvtqnbhcprsg", 14), 29);
+ assert_eq!(
+ first_marker_pos("nznrnfrfntjfmvfwmzdfjlvtqnbhcprsg", 14),
+ 29
+ );
assert_eq!(first_marker_pos("zcfzfwzzqfrljwzlrfnpqdbhtmscgvjw", 14), 26);
}
-}
\ No newline at end of file
+}
impl Dir {
fn new() -> Dir {
- Dir { files: Vec::new(), dirs: Vec::new() }
+ Dir {
+ files: Vec::new(),
+ dirs: Vec::new(),
+ }
}
fn get_file_size(&self) -> i64 {
where
P: Fn(i64) -> bool + Copy,
{
- let size = self.get_file_size() + self.dirs.iter().map(|dir| dir.dir_sizes(predicate, result)).sum::<i64>();
+ let size = self.get_file_size()
+ + self
+ .dirs
+ .iter()
+ .map(|dir| dir.dir_sizes(predicate, result))
+ .sum::<i64>();
+
if predicate(size) {
result.push(size)
}
root.dir_sizes(|size| size >= to_free, &mut sizes);
assert_eq!(*sizes.iter().min().unwrap(), 2_493_3642);
}
-}
\ No newline at end of file
+}
-use itertools::{FoldWhile::{Continue, Done}, Itertools};
+use itertools::{
+ FoldWhile::{Continue, Done},
+ Itertools,
+};
#[derive(Clone, Copy)]
enum Orientation {
impl<T> Matrix<T>
where
- T: Default + Clone
+ T: Default + Clone,
{
fn new(h: usize, w: usize) -> Self {
let mut m: Vec<Vec<T>> = Vec::new();
}
}
-
pub fn parse(input: &str) -> Matrix<i32> {
let mut m: Vec<Vec<i32>> = Vec::new();
for l in input.lines() {
- let row: Vec<i32> = l.trim().chars().map(|c| c.to_digit(10).unwrap() as i32).collect();
+ let row: Vec<i32> = l
+ .trim()
+ .chars()
+ .map(|c| c.to_digit(10).unwrap() as i32)
+ .collect();
m.push(row);
}
Matrix(m)
let mut visibility = Matrix::<bool>::new(h, w);
let mut nb_visible_tree = 0;
- for o in [Orientation::West, Orientation::North, Orientation::Est, Orientation::South] {
+ for o in [
+ Orientation::West,
+ Orientation::North,
+ Orientation::Est,
+ Orientation::South,
+ ] {
for i in 0..h {
let mut max = -1;
for j in 0..w {
let mut current_best_score = -1;
- for i in 1..h-1 {
- for j in 1..w-1 {
+ for i in 1..h - 1 {
+ for j in 1..w - 1 {
let current = forest.get(i, j);
- let dist_w = (1..j).rev().fold_while(1, |dist, j2| if forest.get(i, j2) >= current { Done(dist) } else { Continue(dist + 1) }).into_inner();
- let dist_n = (1..i).rev().fold_while(1, |dist, i2| if forest.get(i2, j) >= current { Done(dist) } else { Continue(dist + 1) }).into_inner();
- let dist_e = (j+1..w-1).fold_while(1, |dist, j2| if forest.get(i, j2) >= current { Done(dist) } else { Continue(dist + 1) }).into_inner();
- let dist_s = (i+1..h-1).fold_while(1, |dist, i2| if forest.get(i2, j) >= current { Done(dist) } else { Continue(dist + 1) }).into_inner();
+ let dist_w = (1..j)
+ .rev()
+ .fold_while(1, |dist, j2| {
+ if forest.get(i, j2) >= current {
+ Done(dist)
+ } else {
+ Continue(dist + 1)
+ }
+ })
+ .into_inner();
+
+ let dist_n = (1..i)
+ .rev()
+ .fold_while(1, |dist, i2| {
+ if forest.get(i2, j) >= current {
+ Done(dist)
+ } else {
+ Continue(dist + 1)
+ }
+ })
+ .into_inner();
+
+ let dist_e = (j + 1..w - 1)
+ .fold_while(1, |dist, j2| {
+ if forest.get(i, j2) >= current {
+ Done(dist)
+ } else {
+ Continue(dist + 1)
+ }
+ })
+ .into_inner();
+
+ let dist_s = (i + 1..h - 1)
+ .fold_while(1, |dist, i2| {
+ if forest.get(i2, j) >= current {
+ Done(dist)
+ } else {
+ Continue(dist + 1)
+ }
+ })
+ .into_inner();
let score = dist_w * dist_n * dist_e * dist_s;
if score > current_best_score {
mod tests {
use super::*;
- static FOREST: &str =
- "30373
- 25512
- 65332
- 33549
- 35390";
+ static FOREST: &str = "30373
+ 25512
+ 65332
+ 33549
+ 35390";
#[test]
fn part1() {
let forest = parse(FOREST);
assert_eq!(best_scenic_score(&forest), 8)
}
-}
\ No newline at end of file
+}
}
pub fn parse(input: &str) -> Vec<Movement> {
- input.lines().map(|l| {
- let split: Vec<&str> = l.trim().split(' ').collect();
- Movement {
- direction: match split[0] {
- "L" => Direction::Left,
- "U" => Direction::Up,
- "R" => Direction::Right,
- "D" => Direction::Down,
- other => panic!("Uknown movement: {}", other),
- },
- distance: split[1].parse().expect("Can't parse distance"),
- }
- }).collect()
+ input
+ .lines()
+ .map(|l| {
+ let split: Vec<&str> = l.trim().split(' ').collect();
+ Movement {
+ direction: match split[0] {
+ "L" => Direction::Left,
+ "U" => Direction::Up,
+ "R" => Direction::Right,
+ "D" => Direction::Down,
+ other => panic!("Uknown movement: {}", other),
+ },
+ distance: split[1].parse().expect("Can't parse distance"),
+ }
+ })
+ .collect()
}
pub fn nb_positions_visited_by_tail<const N: usize>(movements: &[Movement]) -> usize {
for m in movements {
for _ in 0..m.distance {
// 1) Move the head.
- let h = &mut rope[N-1];
+ let h = &mut rope[N - 1];
*h = match m.direction {
Direction::Left => (h.0 - 1, h.1),
Direction::Up => (h.0, h.1 - 1),
};
// 2) Move the rest of the rope.
- for i in (0..N-1).rev() {
- let target = rope[i+1];
+ for i in (0..N - 1).rev() {
+ let target = rope[i + 1];
let node = &mut rope[i];
let (dx, dy): (i32, i32) = (target.0 - node.0, target.1 - node.1);
}
}
}
- };
+ }
visited.len()
}
mod tests {
use super::*;
- static MOVEMENTS: &str =
- "R 4
- U 4
- L 3
- D 1
- R 4
- D 1
- L 5
- R 2";
+ static MOVEMENTS: &str = "R 4
+ U 4
+ L 3
+ D 1
+ R 4
+ D 1
+ L 5
+ R 2";
#[test]
fn part1() {
let movements_2 = parse(
"R 5
- U 8
- L 8
- D 3
- R 17
- D 10
- L 25
- U 20");
+ U 8
+ L 8
+ D 3
+ R 17
+ D 10
+ L 25
+ U 20",
+ );
assert_eq!(nb_positions_visited_by_tail::<10>(&movements_2), 36);
}
-}
\ No newline at end of file
+}
}
pub fn parse(input: &str) -> Vec<Instruction> {
- input.lines().map(|l| {
- let split: Vec<&str> = l.trim().split(' ').collect();
- match split[0] {
- "noop" => Instruction::Noop,
- "addx" => Instruction::Addx(split[1].parse::<i32>().unwrap()),
- other => panic!("Unknown instruction: {}", other),
- }
- }).collect()
+ input
+ .lines()
+ .map(|l| {
+ let split: Vec<&str> = l.trim().split(' ').collect();
+ match split[0] {
+ "noop" => Instruction::Noop,
+ "addx" => Instruction::Addx(split[1].parse::<i32>().unwrap()),
+ other => panic!("Unknown instruction: {}", other),
+ }
+ })
+ .collect()
}
pub struct Screen {
if (cycle - 20) % 40 == 0 {
signal_strength += x * cycle;
}
-
};
for i in instructions {
pub fn to_ascii(&self) -> String {
let mut ascii = String::new();
for line in self.screen.iter() {
- ascii += &line.iter().map(|p| if *p { '#' } else { '.' }).collect::<String>();
+ ascii += &line
+ .iter()
+ .map(|p| if *p { '#' } else { '.' })
+ .collect::<String>();
ascii += "\n";
}
ascii
mod tests {
use super::*;
- static INSTRUCTION: &str =
- "addx 15
- addx -11
- addx 6
- addx -3
- addx 5
- addx -1
- addx -8
- addx 13
- addx 4
- noop
- addx -1
- addx 5
- addx -1
- addx 5
- addx -1
- addx 5
- addx -1
- addx 5
- addx -1
- addx -35
- addx 1
- addx 24
- addx -19
- addx 1
- addx 16
- addx -11
- noop
- noop
- addx 21
- addx -15
- noop
- noop
- addx -3
- addx 9
- addx 1
- addx -3
- addx 8
- addx 1
- addx 5
- noop
- noop
- noop
- noop
- noop
- addx -36
- noop
- addx 1
- addx 7
- noop
- noop
- noop
- addx 2
- addx 6
- noop
- noop
- noop
- noop
- noop
- addx 1
- noop
- noop
- addx 7
- addx 1
- noop
- addx -13
- addx 13
- addx 7
- noop
- addx 1
- addx -33
- noop
- noop
- noop
- addx 2
- noop
- noop
- noop
- addx 8
- noop
- addx -1
- addx 2
- addx 1
- noop
- addx 17
- addx -9
- addx 1
- addx 1
- addx -3
- addx 11
- noop
- noop
- addx 1
- noop
- addx 1
- noop
- noop
- addx -13
- addx -19
- addx 1
- addx 3
- addx 26
- addx -30
- addx 12
- addx -1
- addx 3
- addx 1
- noop
- noop
- noop
- addx -9
- addx 18
- addx 1
- addx 2
- noop
- noop
- addx 9
- noop
- noop
- noop
- addx -1
- addx 2
- addx -37
- addx 1
- addx 3
- noop
- addx 15
- addx -21
- addx 22
- addx -6
- addx 1
- noop
- addx 2
- addx 1
- noop
- addx -10
- noop
- noop
- addx 20
- addx 1
- addx 2
- addx 2
- addx -6
- addx -11
- noop
- noop
- noop";
+ static INSTRUCTION: &str = "addx 15
+ addx -11
+ addx 6
+ addx -3
+ addx 5
+ addx -1
+ addx -8
+ addx 13
+ addx 4
+ noop
+ addx -1
+ addx 5
+ addx -1
+ addx 5
+ addx -1
+ addx 5
+ addx -1
+ addx 5
+ addx -1
+ addx -35
+ addx 1
+ addx 24
+ addx -19
+ addx 1
+ addx 16
+ addx -11
+ noop
+ noop
+ addx 21
+ addx -15
+ noop
+ noop
+ addx -3
+ addx 9
+ addx 1
+ addx -3
+ addx 8
+ addx 1
+ addx 5
+ noop
+ noop
+ noop
+ noop
+ noop
+ addx -36
+ noop
+ addx 1
+ addx 7
+ noop
+ noop
+ noop
+ addx 2
+ addx 6
+ noop
+ noop
+ noop
+ noop
+ noop
+ addx 1
+ noop
+ noop
+ addx 7
+ addx 1
+ noop
+ addx -13
+ addx 13
+ addx 7
+ noop
+ addx 1
+ addx -33
+ noop
+ noop
+ noop
+ addx 2
+ noop
+ noop
+ noop
+ addx 8
+ noop
+ addx -1
+ addx 2
+ addx 1
+ noop
+ addx 17
+ addx -9
+ addx 1
+ addx 1
+ addx -3
+ addx 11
+ noop
+ noop
+ addx 1
+ noop
+ addx 1
+ noop
+ noop
+ addx -13
+ addx -19
+ addx 1
+ addx 3
+ addx 26
+ addx -30
+ addx 12
+ addx -1
+ addx 3
+ addx 1
+ noop
+ noop
+ noop
+ addx -9
+ addx 18
+ addx 1
+ addx 2
+ noop
+ noop
+ addx 9
+ noop
+ noop
+ noop
+ addx -1
+ addx 2
+ addx -37
+ addx 1
+ addx 3
+ noop
+ addx 15
+ addx -21
+ addx 22
+ addx -6
+ addx 1
+ noop
+ addx 2
+ addx 1
+ noop
+ addx -10
+ noop
+ noop
+ addx 20
+ addx 1
+ addx 2
+ addx 2
+ addx -6
+ addx -11
+ noop
+ noop
+ noop";
#[test]
fn part1() {
screen.draw_screen(&instructions);
println!("{}", screen.to_ascii());
- assert_eq!(screen.to_ascii(),
- "##..##..##..##..##..##..##..##..##..##..
+ assert_eq!(
+ screen.to_ascii(),
+ "##..##..##..##..##..##..##..##..##..##..
###...###...###...###...###...###...###.
####....####....####....####....####....
#####.....#####.....#####.....#####.....
######......######......######......####
#######.......#######.......#######.....
-");
+"
+ );
}
-}
\ No newline at end of file
+}
-use std::{str::Lines, collections::VecDeque};
+use std::{collections::VecDeque, str::Lines};
use itertools::Itertools;
impl Operation {
fn parse(op: &[&str]) -> Self {
match op[1] {
- "*" => if op[2] == "old" { Operation::MulOld } else { Operation::Mul(op[2].parse::<u64>().unwrap()) },
+ "*" => {
+ if op[2] == "old" {
+ Operation::MulOld
+ } else {
+ Operation::Mul(op[2].parse::<u64>().unwrap())
+ }
+ }
"+" => Operation::Add(op[2].parse::<u64>().unwrap()),
unknown => panic!("Unknown operation: {}", unknown),
}
lines.next()?; // Skip first line (Monkey number).
Some(Monkey {
- items: split_line(lines.next()?).skip(2).map(|v| v.parse::<u64>().unwrap()).collect(),
+ items: split_line(lines.next()?)
+ .skip(2)
+ .map(|v| v.parse::<u64>().unwrap())
+ .collect(),
operation: Operation::parse(&split_line(lines.next()?).skip(3).collect::<Vec<&str>>()),
- divisible_test: split_line(lines.next()?).nth(3).unwrap().parse::<u64>().unwrap(),
+ divisible_test: split_line(lines.next()?)
+ .nth(3)
+ .unwrap()
+ .parse::<u64>()
+ .unwrap(),
monkey_to_throw_if_true: split_line(lines.next()?).nth(5).unwrap().parse().unwrap(),
monkey_to_throw_if_false: split_line(lines.next()?).nth(5).unwrap().parse().unwrap(),
})
pub fn run(monkeys: &mut [Monkey], nb_rounds: u64, worry_divided: u64) -> u64 {
let mut inspected = vec![0u64; monkeys.len()];
- let base = monkeys.iter().fold(1, |product, m| product * m.divisible_test);
+ let base = monkeys
+ .iter()
+ .fold(1, |product, m| product * m.divisible_test);
for _ in 0..nb_rounds {
for i in 0..monkeys.len() {
inspected[i] += 1;
let new_worry = (monkeys[i].operation.apply(item) / worry_divided) % base;
if new_worry % monkeys[i].divisible_test == 0 {
- monkeys[monkeys[i].monkey_to_throw_if_true].items.push_back(new_worry);
+ monkeys[monkeys[i].monkey_to_throw_if_true]
+ .items
+ .push_back(new_worry);
} else {
- monkeys[monkeys[i].monkey_to_throw_if_false].items.push_back(new_worry);
+ monkeys[monkeys[i].monkey_to_throw_if_false]
+ .items
+ .push_back(new_worry);
}
}
}
mod tests {
use super::*;
- static MONKEYS: &str =
- "Monkey 0:
+ static MONKEYS: &str = "Monkey 0:
Starting items: 79, 98
Operation: new = old * 19
Test: divisible by 23
let mut monkeys = parse(MONKEYS);
assert_eq!(run(&mut monkeys, 10000, 1), 2713310158);
}
-}
\ No newline at end of file
+}
}
pub fn parse(input: &str) -> Heightmap {
- let mut hm = Heightmap { elevations: Vec::new(), start: (0, 0), end: (0, 0) };
+ let mut hm = Heightmap {
+ elevations: Vec::new(),
+ start: (0, 0),
+ end: (0, 0),
+ };
for (i, l) in input.lines().enumerate() {
let mut row = Vec::new();
for (j, c) in l.trim().chars().enumerate() {
let neighbors = |i, j| {
let mut positions = Vec::new();
- if i > 0 { positions.push((i - 1, j)); }
- if i < n - 1 { positions.push((i + 1, j)); }
- if j > 0 { positions.push((i, j - 1)); }
- if j < m - 1 { positions.push((i, j + 1)); }
+ if i > 0 {
+ positions.push((i - 1, j));
+ }
+ if i < n - 1 {
+ positions.push((i + 1, j));
+ }
+ if j > 0 {
+ positions.push((i, j - 1));
+ }
+ if j < m - 1 {
+ positions.push((i, j + 1));
+ }
positions
};
loop {
step = step + 1;
for (i, j) in positions.drain(..) {
- if path == Path::StartToEnd && (i, j) == hm.start || path == Path::EndTo0Elevation && hm.elevations[i][j] == 0 {
+ if path == Path::StartToEnd && (i, j) == hm.start
+ || path == Path::EndTo0Elevation && hm.elevations[i][j] == 0
+ {
return step;
}
mod tests {
use super::*;
- static HEIGHTMAP: &str =
- "Sabqponm
- abcryxxl
- accszExk
- acctuvwj
- abdefghi";
+ static HEIGHTMAP: &str = "Sabqponm
+ abcryxxl
+ accszExk
+ acctuvwj
+ abdefghi";
#[test]
fn part1() {
-use std::{fs, io::{BufReader, Seek, SeekFrom}};
+use std::{
+ fs,
+ io::{BufReader, Seek, SeekFrom},
+};
use crate::*;
pub fn day01() -> String {
let f = fs::File::open("data/day01.input").unwrap();
let calories = day01::read_calories(BufReader::new(f));
- format!("part1: {}, part2: {}", day01::get_most_calories(&calories), day01::get_sum_most_three_calories(&calories))
+ format!(
+ "part1: {}, part2: {}",
+ day01::get_most_calories(&calories),
+ day01::get_sum_most_three_calories(&calories)
+ )
}
pub fn day02() -> String {
let shapes = day02::read_shapes(BufReader::new(f.try_clone().unwrap()));
let _ = f.seek(SeekFrom::Start(0));
let shapes_2 = day02::read_shapes_2(BufReader::new(f));
- format!("part1: {}, part2: {}", day02::get_score(&shapes), day02::get_score(&shapes_2))
+ format!(
+ "part1: {}, part2: {}",
+ day02::get_score(&shapes),
+ day02::get_score(&shapes_2)
+ )
}
pub fn day03() -> String {
let rucksacks = day03::parse(&fs::read_to_string("data/day03.input").unwrap());
- format!("part1: {}, part2: {}", day03::priority_sum(&rucksacks), day03::badge_sum(&rucksacks))
+ format!(
+ "part1: {}, part2: {}",
+ day03::priority_sum(&rucksacks),
+ day03::badge_sum(&rucksacks)
+ )
}
pub fn day04() -> String {
let pairs = day04::parse(&fs::read_to_string("data/day04.input").unwrap());
- format!("part1: {}, part2: {}", day04::number_fully_contain(&pairs), day04::number_overlaps(&pairs))
+ format!(
+ "part1: {}, part2: {}",
+ day04::number_fully_contain(&pairs),
+ day04::number_overlaps(&pairs)
+ )
}
pub fn day05() -> String {
let mut stacks2 = stacks.clone();
day05::apply_moves_by_crate_mover_9000(&mut stacks, &moves);
day05::apply_moves_by_crate_mover_9001(&mut stacks2, &moves);
- format!("part1: {}, part2: {}", day05::get_top_as_string(&stacks), day05::get_top_as_string(&stacks2))
+ format!(
+ "part1: {}, part2: {}",
+ day05::get_top_as_string(&stacks),
+ day05::get_top_as_string(&stacks2)
+ )
}
pub fn day06() -> String {
let signals = fs::read_to_string("data/day06.input").unwrap();
- format!("part1: {}, part2: {}", day06::first_marker_pos(&signals, 4), day06::first_marker_pos(&signals, 14))
+ format!(
+ "part1: {}, part2: {}",
+ day06::first_marker_pos(&signals, 4),
+ day06::first_marker_pos(&signals, 14)
+ )
}
pub fn day07() -> String {
let root = day07::parse(&fs::read_to_string("data/day07.input").unwrap());
- let (root_size, sum_part1, ) = {
+ let (root_size, sum_part1) = {
let mut sizes: Vec<i64> = Vec::new();
- (root.dir_sizes(|size| size <= 100_000, &mut sizes), sizes.iter().sum::<i64>())
+ (
+ root.dir_sizes(|size| size <= 100_000, &mut sizes),
+ sizes.iter().sum::<i64>(),
+ )
};
let min_part2 = {
pub fn day08() -> String {
let forest = day08::parse(&fs::read_to_string("data/day08.input").unwrap());
- format!("part1: {}, part2: {}", day08::number_of_visible_trees(&forest), day08::best_scenic_score(&forest))
+ format!(
+ "part1: {}, part2: {}",
+ day08::number_of_visible_trees(&forest),
+ day08::best_scenic_score(&forest)
+ )
}
pub fn day09() -> String {
let movements = day09::parse(&fs::read_to_string("data/day09.input").unwrap());
- format!("part1: {}, part2: {}", day09::nb_positions_visited_by_tail::<2>(&movements), day09::nb_positions_visited_by_tail::<10>(&movements))
+ format!(
+ "part1: {}, part2: {}",
+ day09::nb_positions_visited_by_tail::<2>(&movements),
+ day09::nb_positions_visited_by_tail::<10>(&movements)
+ )
}
pub fn day10() -> String {
let instructions = day10::parse(&fs::read_to_string("data/day10.input").unwrap());
let mut screen = day10::Screen::new();
let sum_signal_strength = screen.draw_screen(&instructions);
- format!("part1: {}, part2: \n{}", sum_signal_strength, screen.to_ascii())
+ format!(
+ "part1: {}, part2: \n{}",
+ sum_signal_strength,
+ screen.to_ascii()
+ )
}
pub fn day11() -> String {
let monkeys = day11::parse(&fs::read_to_string("data/day11.input").unwrap());
- format!("part1: {}, part2: {}", day11::run(&mut monkeys.clone(), 20, 3), day11::run(&mut monkeys.clone(), 10000, 1))
+ format!(
+ "part1: {}, part2: {}",
+ day11::run(&mut monkeys.clone(), 20, 3),
+ day11::run(&mut monkeys.clone(), 10000, 1)
+ )
}
pub fn day12() -> String {
let heightmap = day12::parse(&fs::read_to_string("data/day12.input").unwrap());
- format!("part1: {}, part2: {}", day12::nb_steps(&heightmap, day12::Path::StartToEnd), day12::nb_steps(&heightmap, day12::Path::EndTo0Elevation))
+ format!(
+ "part1: {}, part2: {}",
+ day12::nb_steps(&heightmap, day12::Path::StartToEnd),
+ day12::nb_steps(&heightmap, day12::Path::EndTo0Elevation)
+ )
}
use std::{env, time::Instant};
-mod common;
-mod days;
mod day01;
mod day02;
mod day03;
mod day10;
mod day11;
mod day12;
+mod days;
fn main() {
println!("https://adventofcode.com/2022");
- let days: Vec<fn() -> String> = vec!(
+ let days: Vec<fn() -> String> = vec![
days::day01,
days::day02,
days::day03,
days::day10,
days::day11,
days::day12,
- );
+ ];
let args: Vec<String> = env::args().skip(1).collect();
// No argument -> execute all day problems.
if args.is_empty() {
let now = Instant::now();
- for i in 1 ..= days.len() {
+ for i in 1..=days.len() {
do_day(&days, i)
}
- println!("Time to execute all days: {}", format_micros(now.elapsed().as_micros()));
+ println!(
+ "Time to execute all days: {}",
+ format_micros(now.elapsed().as_micros())
+ );
} else {
for arg in args {
match arg.parse::<usize>() {
- Ok(day) if day >= 1 && day <= days.len() =>
- do_day(&days, day),
- Ok(day) =>
- println!("Unknown day: {}", day),
- Err(error) =>
- println!("Unable to parse day number: \"{}\", error: {}", arg, error)
+ Ok(day) if day >= 1 && day <= days.len() => do_day(&days, day),
+ Ok(day) => println!("Unknown day: {}", day),
+ Err(error) => println!("Unable to parse day number: \"{}\", error: {}", arg, error),
}
}
}
fn do_day(days: &[fn() -> String], day: usize) {
let now = Instant::now();
- println!("Result of day {:02}: {} (time: {})", day, days[day - 1](), format_micros(now.elapsed().as_micros()));
+ println!(
+ "Result of day {:02}: {} (time: {})",
+ day,
+ days[day - 1](),
+ format_micros(now.elapsed().as_micros())
+ );
}
fn format_micros(t: u128) -> String {