2020: day24: part 1

This commit is contained in:
Antoine Martin 2020-12-24 15:10:48 +01:00
parent d998cb02aa
commit 3ebbba3953
6 changed files with 777 additions and 0 deletions

144
aoc2020/src/day24.rs Normal file
View file

@ -0,0 +1,144 @@
use std::collections::HashSet;
use std::fmt::Write;
use anyhow::{bail, Context, Result};
const INPUT: &str = include_str!("../input/day24.txt");
pub fn run() -> Result<String> {
let mut res = String::with_capacity(128);
writeln!(res, "part 1: {}", part1(INPUT)?)?;
Ok(res)
}
fn part1(input: &str) -> Result<usize> {
let mut black_tiles = HashSet::new();
for line in input.lines() {
let mut line = line;
let mut tile_pos = HexCoordinates::default();
// compute tile coordinates by going through the whole line
while !line.is_empty() {
match line.chars().next().unwrap() {
'e' => {
tile_pos = tile_pos.east();
line = &line[1..];
}
'w' => {
tile_pos = tile_pos.west();
line = &line[1..];
}
'n' => {
match line
.chars()
.nth(1)
.context("invalid input, missing char after `n`")?
{
'e' => tile_pos = tile_pos.north_east(),
'w' => tile_pos = tile_pos.north_west(),
other => bail!("unexpected character in input: `{}`", other),
}
line = &line[2..];
}
's' => {
match line
.chars()
.nth(1)
.context("invalid input, missing char after `s`")?
{
'e' => tile_pos = tile_pos.south_east(),
'w' => tile_pos = tile_pos.south_west(),
other => bail!("unexpected character in input: `{}`", other),
}
line = &line[2..];
}
other => bail!("unexpected character in input: `{}`", other),
}
}
if black_tiles.contains(&tile_pos) {
black_tiles.remove(&tile_pos);
} else {
black_tiles.insert(tile_pos);
}
}
Ok(black_tiles.len())
}
/// Hexagonal tile coordinate representation
///
/// These use the axial coordinates described here:
///
/// https://www.redblobgames.com/grids/hexagons/#coordinates-axial
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
struct HexCoordinates {
q: i64,
r: i64,
}
impl HexCoordinates {
fn east(self) -> Self {
Self {
q: self.q + 1,
r: self.r,
}
}
fn west(self) -> Self {
Self {
q: self.q - 1,
r: self.r,
}
}
fn north_west(self) -> Self {
Self {
q: self.q,
r: self.r - 1,
}
}
fn south_east(self) -> Self {
Self {
q: self.q,
r: self.r + 1,
}
}
fn north_east(self) -> Self {
self.north_west().east()
}
fn south_west(self) -> Self {
self.south_east().west()
}
}
impl Default for HexCoordinates {
fn default() -> Self {
Self { q: 0, r: 0 }
}
}
#[cfg(test)]
mod tests {
use super::*;
const PROVIDED: &str = include_str!("../input/day24_provided.txt");
#[test]
fn part1_provided() {
assert_eq!(part1(PROVIDED).unwrap(), 10);
}
#[test]
fn part1_real() {
assert_eq!(part1(INPUT).unwrap(), 528);
}
}

View file

@ -22,3 +22,4 @@ pub mod day19;
pub mod day21;
pub mod day22;
pub mod day23;
pub mod day24;

View file

@ -24,6 +24,7 @@ use aoc2020::day19;
use aoc2020::day21;
use aoc2020::day22;
use aoc2020::day23;
use aoc2020::day24;
fn main() -> Result<()> {
let days: &[DayFunc] = &[
@ -49,6 +50,7 @@ fn main() -> Result<()> {
day21::run,
day22::run,
day23::run,
day24::run,
];
aoc::run(days)