Complete day 5

This commit is contained in:
2020-12-05 16:23:12 -05:00
parent 1cdc019c79
commit 31b6323fcc
5 changed files with 970 additions and 0 deletions

119
day05/src/main.rs Normal file
View File

@@ -0,0 +1,119 @@
use anyhow::{anyhow, Error, Result};
use std::fs::File;
use std::io::prelude::*;
use std::io::BufReader;
use std::str::FromStr;
const INPUT: &str = "input/input.txt";
#[derive(Debug, PartialEq)]
struct Seat {
row: u32,
col: u32,
}
impl Seat {
fn id(&self) -> u32 {
self.row * 8 + self.col
}
}
impl FromStr for Seat {
type Err = Error;
fn from_str(s: &str) -> Result<Self> {
let row = s.chars().take(7).try_fold(0..128, |range, c| match c {
'F' => Ok(range.start..(range.end - ((range.end - range.start) / 2))),
'B' => Ok((range.start + ((range.end - range.start) / 2))..range.end),
_ => Err(anyhow!("Unrecognized row character: {}", c)),
})?;
let col = s
.chars()
.skip(7)
.take(3)
.try_fold(0..8, |range, c| match c {
'L' => Ok(range.start..(range.end - ((range.end - range.start) / 2))),
'R' => Ok((range.start + ((range.end - range.start) / 2))..range.end),
_ => Err(anyhow!("Unrecognized row character: {}", c)),
})?;
Ok(Self {
row: row.start,
col: col.start,
})
}
}
fn solve_part1(input_path: &str) -> Result<u32> {
let file = File::open(input_path)?;
let reader = BufReader::new(file);
Ok(reader
.lines()
.map(|line| Seat::from_str(&line.unwrap()).unwrap())
.map(|seat| seat.id())
.max()
.ok_or(anyhow!("No seats found in input"))?)
}
fn solve_part2(input_path: &str) -> Result<u32> {
let file = File::open(input_path)?;
let reader = BufReader::new(file);
let mut seat_ids: Vec<u32> = reader
.lines()
.map(|line| Seat::from_str(&line.unwrap()).unwrap())
.map(|seat| seat.id())
.collect();
seat_ids.sort_unstable();
let mut prev_seat = None;
for seat_id in seat_ids {
if let Some(prev_seat) = prev_seat {
if seat_id != prev_seat + 1 {
return Ok(prev_seat + 1);
}
}
prev_seat = Some(seat_id);
}
Err(anyhow!("No missing seat was found in input"))
}
fn main() {
println!("Part 1: {}", solve_part1(INPUT).unwrap());
println!("Part 2: {}", solve_part2(INPUT).unwrap());
}
#[cfg(test)]
mod tests {
use super::*;
const TEST_INPUT: &str = "input/test.txt";
#[test]
fn parses_input() {
let file = File::open(TEST_INPUT).unwrap();
let reader = BufReader::new(file);
let seats: Vec<Seat> = reader
.lines()
.map(|line| Seat::from_str(&line.unwrap()))
.collect::<Result<Vec<Seat>>>()
.unwrap();
assert_eq!(seats[0], Seat { row: 70, col: 7 });
assert_eq!(seats[0].id(), 567);
assert_eq!(seats[1], Seat { row: 14, col: 7 });
assert_eq!(seats[1].id(), 119);
assert_eq!(seats[2], Seat { row: 102, col: 4 });
assert_eq!(seats[2].id(), 820);
}
#[test]
fn solves_part1() {
assert_eq!(solve_part1(TEST_INPUT).unwrap(), 820);
}
#[test]
fn solves_part2() {
assert_eq!(solve_part2(TEST_INPUT).unwrap(), 120);
}
}