1
Fork 0
advent-of-code/source/year_2020/day_05/mod.rs

87 lines
2.1 KiB
Rust

//! Day 05 of 2020.
use crate::prelude::*;
/// Get the solution for day 05 of 2020.
pub fn solution() -> Solution {
Solution::new(Day::new(5, 2020), part_1, part_2).with_expected(850, 599)
}
/// The maximum range of rows.
const MAX_ROW_RANGE: i32 = 128;
/// The maximum range of columns.
const MAX_COLUMN_RANGE: i32 = 8;
/// Calculate the row and column from the input according to the puzzle's
/// instructions.
fn calculate_row_and_column(input: &str) -> (i32, i32) {
let mut row_range = 0..MAX_ROW_RANGE;
let mut column_range = 0..MAX_COLUMN_RANGE;
for character in input.chars() {
let row_min = row_range.start;
let row_max = row_range.end;
let row_difference = (row_max - row_min) / 2;
let column_min = column_range.start;
let column_max = column_range.end;
let column_difference = (column_max - column_min) / 2;
match character {
'F' => {
row_range = row_min..(row_max - row_difference);
}
'B' => {
row_range = (row_min + row_difference)..row_max;
}
'L' => {
column_range = column_min..(column_max - column_difference);
}
'R' => {
column_range = (column_min + column_difference)..column_max;
}
_ => unreachable!("{character}"),
}
}
(row_range.start, column_range.start)
}
/// Calculate the sead ID by multiplying the row by 8 and adding the column.
fn calculate_seat_id((row, column): (i32, i32)) -> i32 {
(row * 8) + column
}
/// The logic to solve part one.
fn part_1(input: &str) -> Result<String> {
Ok(
input
.lines()
.map(calculate_row_and_column)
.map(calculate_seat_id)
.max()
.unwrap()
.to_string(),
)
}
/// The logic to solve part two.
fn part_2(input: &str) -> Result<String> {
let seat_ids = input
.lines()
.map(calculate_row_and_column)
.map(calculate_seat_id)
.collect::<Vec<i32>>();
let max_seat_id = seat_ids.iter().max().unwrap();
let min_seat_id = seat_ids.iter().min().unwrap();
Ok(
(*min_seat_id..*max_seat_id)
.find(|index| !seat_ids.contains(index))
.map(|id| id.to_string())
.unwrap(),
)
}