day20 part 1
This commit is contained in:
parent
769937bf97
commit
5b051a8ff9
1728
input/2020/day20.txt
Normal file
1728
input/2020/day20.txt
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
|||||||
|
use crate::split_once;
|
||||||
use aoc_runner_derive::aoc;
|
use aoc_runner_derive::aoc;
|
||||||
use std::ops::RangeInclusive;
|
use std::ops::RangeInclusive;
|
||||||
use crate::split_once;
|
|
||||||
|
|
||||||
struct Rule<'a> {
|
struct Rule<'a> {
|
||||||
name: &'a str,
|
name: &'a str,
|
||||||
|
|||||||
220
src/day20.rs
Normal file
220
src/day20.rs
Normal file
@ -0,0 +1,220 @@
|
|||||||
|
use crate::split_once;
|
||||||
|
use aoc_runner_derive::aoc;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Tile {
|
||||||
|
id: usize,
|
||||||
|
data: [bool; 100],
|
||||||
|
}
|
||||||
|
impl Tile {
|
||||||
|
fn parse(input: &str) -> Option<Tile> {
|
||||||
|
let (id_line, input_data) = split_once(input, ":\n")?;
|
||||||
|
let (_, id) = split_once(id_line, " ")?;
|
||||||
|
let mut data = [false; 100];
|
||||||
|
for idx in input_data
|
||||||
|
.as_bytes()
|
||||||
|
.iter()
|
||||||
|
.cloned()
|
||||||
|
.filter(|&b| b != b'\n')
|
||||||
|
.enumerate()
|
||||||
|
.filter_map(|(idx, b)| if b == b'#' { Some(idx) } else { None })
|
||||||
|
{
|
||||||
|
data[idx] = true;
|
||||||
|
}
|
||||||
|
Some(Tile {
|
||||||
|
id: id.parse().ok()?,
|
||||||
|
data,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sides(&self) -> Vec<u16> {
|
||||||
|
let top = self.data[0..10]
|
||||||
|
.iter()
|
||||||
|
.cloned()
|
||||||
|
.enumerate()
|
||||||
|
.filter(|&(_, b)| b)
|
||||||
|
.fold(0u16, |accum, (idx, _)| accum | (1 << idx));
|
||||||
|
let bottom = self.data[90..100]
|
||||||
|
.iter()
|
||||||
|
.cloned()
|
||||||
|
.enumerate()
|
||||||
|
.filter(|&(_, b)| b)
|
||||||
|
.fold(0u16, |accum, (idx, _)| accum | (1 << idx));
|
||||||
|
|
||||||
|
let left = self
|
||||||
|
.data
|
||||||
|
.iter()
|
||||||
|
.step_by(10)
|
||||||
|
.cloned()
|
||||||
|
.enumerate()
|
||||||
|
.filter(|&(_, b)| b)
|
||||||
|
.fold(0u16, |accum, (idx, _)| accum | (1 << idx));
|
||||||
|
|
||||||
|
let right = self
|
||||||
|
.data
|
||||||
|
.iter()
|
||||||
|
.skip(9)
|
||||||
|
.step_by(10)
|
||||||
|
.cloned()
|
||||||
|
.enumerate()
|
||||||
|
.filter(|&(_, b)| b)
|
||||||
|
.fold(0u16, |accum, (idx, _)| accum | (1 << idx));
|
||||||
|
|
||||||
|
// Put the id's in a consistent order.
|
||||||
|
fn consistent_id(id: u16) -> u16 {
|
||||||
|
let reversed = id.reverse_bits() >> 6;
|
||||||
|
if id < reversed {
|
||||||
|
reversed
|
||||||
|
} else {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vec![
|
||||||
|
consistent_id(top),
|
||||||
|
consistent_id(right),
|
||||||
|
consistent_id(bottom),
|
||||||
|
consistent_id(left),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const EXAMPLE: &str = "Tile 2311:
|
||||||
|
..##.#..#.
|
||||||
|
##..#.....
|
||||||
|
#...##..#.
|
||||||
|
####.#...#
|
||||||
|
##.##.###.
|
||||||
|
##...#.###
|
||||||
|
.#.#.#..##
|
||||||
|
..#....#..
|
||||||
|
###...#.#.
|
||||||
|
..###..###
|
||||||
|
|
||||||
|
Tile 1951:
|
||||||
|
#.##...##.
|
||||||
|
#.####...#
|
||||||
|
.....#..##
|
||||||
|
#...######
|
||||||
|
.##.#....#
|
||||||
|
.###.#####
|
||||||
|
###.##.##.
|
||||||
|
.###....#.
|
||||||
|
..#.#..#.#
|
||||||
|
#...##.#..
|
||||||
|
|
||||||
|
Tile 1171:
|
||||||
|
####...##.
|
||||||
|
#..##.#..#
|
||||||
|
##.#..#.#.
|
||||||
|
.###.####.
|
||||||
|
..###.####
|
||||||
|
.##....##.
|
||||||
|
.#...####.
|
||||||
|
#.##.####.
|
||||||
|
####..#...
|
||||||
|
.....##...
|
||||||
|
|
||||||
|
Tile 1427:
|
||||||
|
###.##.#..
|
||||||
|
.#..#.##..
|
||||||
|
.#.##.#..#
|
||||||
|
#.#.#.##.#
|
||||||
|
....#...##
|
||||||
|
...##..##.
|
||||||
|
...#.#####
|
||||||
|
.#.####.#.
|
||||||
|
..#..###.#
|
||||||
|
..##.#..#.
|
||||||
|
|
||||||
|
Tile 1489:
|
||||||
|
##.#.#....
|
||||||
|
..##...#..
|
||||||
|
.##..##...
|
||||||
|
..#...#...
|
||||||
|
#####...#.
|
||||||
|
#..#.#.#.#
|
||||||
|
...#.#.#..
|
||||||
|
##.#...##.
|
||||||
|
..##.##.##
|
||||||
|
###.##.#..
|
||||||
|
|
||||||
|
Tile 2473:
|
||||||
|
#....####.
|
||||||
|
#..#.##...
|
||||||
|
#.##..#...
|
||||||
|
######.#.#
|
||||||
|
.#...#.#.#
|
||||||
|
.#########
|
||||||
|
.###.#..#.
|
||||||
|
########.#
|
||||||
|
##...##.#.
|
||||||
|
..###.#.#.
|
||||||
|
|
||||||
|
Tile 2971:
|
||||||
|
..#.#....#
|
||||||
|
#...###...
|
||||||
|
#.#.###...
|
||||||
|
##.##..#..
|
||||||
|
.#####..##
|
||||||
|
.#..####.#
|
||||||
|
#..#.#..#.
|
||||||
|
..####.###
|
||||||
|
..#.#.###.
|
||||||
|
...#.#.#.#
|
||||||
|
|
||||||
|
Tile 2729:
|
||||||
|
...#.#.#.#
|
||||||
|
####.#....
|
||||||
|
..#.#.....
|
||||||
|
....#..#.#
|
||||||
|
.##..##.#.
|
||||||
|
.#.####...
|
||||||
|
####.#.#..
|
||||||
|
##.####...
|
||||||
|
##..#.##..
|
||||||
|
#.##...##.
|
||||||
|
|
||||||
|
Tile 3079:
|
||||||
|
#.#.#####.
|
||||||
|
.#..######
|
||||||
|
..#.......
|
||||||
|
######....
|
||||||
|
####.#..#.
|
||||||
|
.#...#.##.
|
||||||
|
#.#####.##
|
||||||
|
..#.###...
|
||||||
|
..#.......
|
||||||
|
..#.###...
|
||||||
|
";
|
||||||
|
|
||||||
|
#[aoc(day20, part1)]
|
||||||
|
fn solve_d20_p1(input: &str) -> usize {
|
||||||
|
let tiles: Vec<_> = input
|
||||||
|
.split("\n\n")
|
||||||
|
.map(|i| Tile::parse(i).unwrap())
|
||||||
|
.collect();
|
||||||
|
let mut side_to_tile: HashMap<_, Vec<_>> = HashMap::new();
|
||||||
|
for tile in &tiles {
|
||||||
|
for side in tile.sides() {
|
||||||
|
side_to_tile.entry(side).or_default().push(tile.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tiles
|
||||||
|
.iter()
|
||||||
|
.filter_map(|tile| {
|
||||||
|
let num_unique_sides = tile.sides().iter().fold(0, |accum, side| {
|
||||||
|
if side_to_tile.get(&side).unwrap().len() == 1 {
|
||||||
|
accum + 1
|
||||||
|
} else {
|
||||||
|
accum
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if num_unique_sides == 2 {
|
||||||
|
Some(tile.id)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.product()
|
||||||
|
}
|
||||||
@ -10,6 +10,7 @@ pub mod day17;
|
|||||||
pub mod day18;
|
pub mod day18;
|
||||||
pub mod day19;
|
pub mod day19;
|
||||||
pub mod day2;
|
pub mod day2;
|
||||||
|
pub mod day20;
|
||||||
pub mod day3;
|
pub mod day3;
|
||||||
pub mod day4;
|
pub mod day4;
|
||||||
pub mod day5;
|
pub mod day5;
|
||||||
@ -23,4 +24,4 @@ aoc_runner_derive::aoc_lib! { year = 2020 }
|
|||||||
fn split_once<'a>(input: &'a str, delimeter: &str) -> Option<(&'a str, &'a str)> {
|
fn split_once<'a>(input: &'a str, delimeter: &str) -> Option<(&'a str, &'a str)> {
|
||||||
let idx = input.find(delimeter)?;
|
let idx = input.find(delimeter)?;
|
||||||
Some((&input[..idx], &input[idx + delimeter.len()..]))
|
Some((&input[..idx], &input[idx + delimeter.len()..]))
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user