[TASK] Solved Day 20 Pt 1
This commit is contained in:
1727
input/day20.txt
Normal file
1727
input/day20.txt
Normal file
File diff suppressed because it is too large
Load Diff
107
input/day20_example.txt
Normal file
107
input/day20_example.txt
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
Tile 2311:
|
||||||
|
..##.#..#.
|
||||||
|
##..#.....
|
||||||
|
#...##..#.
|
||||||
|
####.#...#
|
||||||
|
##.##.###.
|
||||||
|
##...#.###
|
||||||
|
.#.#.#..##
|
||||||
|
..#....#..
|
||||||
|
###...#.#.
|
||||||
|
..###..###
|
||||||
|
|
||||||
|
Tile 1951:
|
||||||
|
#.##...##.
|
||||||
|
#.####...#
|
||||||
|
.....#..##
|
||||||
|
#...######
|
||||||
|
.##.#....#
|
||||||
|
.###.#####
|
||||||
|
###.##.##.
|
||||||
|
.###....#.
|
||||||
|
..#.#..#.#
|
||||||
|
#...##.#..
|
||||||
|
|
||||||
|
Tile 1171:
|
||||||
|
####...##.
|
||||||
|
#..##.#..#
|
||||||
|
##.#..#.#.
|
||||||
|
.###.####.
|
||||||
|
..###.####
|
||||||
|
.##....##.
|
||||||
|
.#...####.
|
||||||
|
#.##.####.
|
||||||
|
####..#...
|
||||||
|
.....##...
|
||||||
|
|
||||||
|
Tile 1427:
|
||||||
|
###.##.#..
|
||||||
|
.#..#.##..
|
||||||
|
.#.##.#..#
|
||||||
|
#.#.#.##.#
|
||||||
|
....#...##
|
||||||
|
...##..##.
|
||||||
|
...#.#####
|
||||||
|
.#.####.#.
|
||||||
|
..#..###.#
|
||||||
|
..##.#..#.
|
||||||
|
|
||||||
|
Tile 1489:
|
||||||
|
##.#.#....
|
||||||
|
..##...#..
|
||||||
|
.##..##...
|
||||||
|
..#...#...
|
||||||
|
#####...#.
|
||||||
|
#..#.#.#.#
|
||||||
|
...#.#.#..
|
||||||
|
##.#...##.
|
||||||
|
..##.##.##
|
||||||
|
###.##.#..
|
||||||
|
|
||||||
|
Tile 2473:
|
||||||
|
#....####.
|
||||||
|
#..#.##...
|
||||||
|
#.##..#...
|
||||||
|
######.#.#
|
||||||
|
.#...#.#.#
|
||||||
|
.#########
|
||||||
|
.###.#..#.
|
||||||
|
########.#
|
||||||
|
##...##.#.
|
||||||
|
..###.#.#.
|
||||||
|
|
||||||
|
Tile 2971:
|
||||||
|
..#.#....#
|
||||||
|
#...###...
|
||||||
|
#.#.###...
|
||||||
|
##.##..#..
|
||||||
|
.#####..##
|
||||||
|
.#..####.#
|
||||||
|
#..#.#..#.
|
||||||
|
..####.###
|
||||||
|
..#.#.###.
|
||||||
|
...#.#.#.#
|
||||||
|
|
||||||
|
Tile 2729:
|
||||||
|
...#.#.#.#
|
||||||
|
####.#....
|
||||||
|
..#.#.....
|
||||||
|
....#..#.#
|
||||||
|
.##..##.#.
|
||||||
|
.#.####...
|
||||||
|
####.#.#..
|
||||||
|
##.####...
|
||||||
|
##..#.##..
|
||||||
|
#.##...##.
|
||||||
|
|
||||||
|
Tile 3079:
|
||||||
|
#.#.#####.
|
||||||
|
.#..######
|
||||||
|
..#.......
|
||||||
|
######....
|
||||||
|
####.#..#.
|
||||||
|
.#...#.##.
|
||||||
|
#.#####.##
|
||||||
|
..#.###...
|
||||||
|
..#.......
|
||||||
|
..#.###...
|
||||||
157
src/day20.rs
Normal file
157
src/day20.rs
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
use super::util;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
const PIECE_SIZE: u16 = 10;
|
||||||
|
// const POSSIBLE_EDGE_COUNT: u16 = 1 << (PIECE_SIZE + 1);
|
||||||
|
|
||||||
|
pub fn solve() {
|
||||||
|
let lines = util::read_file("input/day20.txt");
|
||||||
|
let mut piece_id = 0u32;
|
||||||
|
let mut piece_lines: Vec<PieceLine> = Vec::new();
|
||||||
|
let mut pieces = Vec::new();
|
||||||
|
for line in &lines {
|
||||||
|
|
||||||
|
if line == &"" {
|
||||||
|
pieces.push(Piece::from(piece_id, piece_lines));
|
||||||
|
piece_lines = Vec::new();
|
||||||
|
} else if line.starts_with("Tile") {
|
||||||
|
piece_id = line[5..(line.len() - 1)].parse::<u32>().unwrap();
|
||||||
|
} else {
|
||||||
|
piece_lines.push(PieceLine::parse(&line));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !piece_lines.is_empty() {
|
||||||
|
pieces.push(Piece::from(piece_id, piece_lines));
|
||||||
|
}
|
||||||
|
pieces.sort_by_key(|p| p.id);
|
||||||
|
|
||||||
|
// Let's create an array containing for each puzzle piece side, in which pieces it appears:
|
||||||
|
let mut piece_matches = HashMap::new();
|
||||||
|
for piece in &pieces {
|
||||||
|
add_to_piece_matches(piece.id, &piece.top_edge, &piece.flipped_top_edge, &mut piece_matches);
|
||||||
|
add_to_piece_matches(piece.id, &piece.bottom_edge, &piece.flipped_bottom_edge, &mut piece_matches);
|
||||||
|
add_to_piece_matches(piece.id, &piece.left_edge, &piece.flipped_left_edge, &mut piece_matches);
|
||||||
|
add_to_piece_matches(piece.id, &piece.right_edge, &piece.flipped_right_edge, &mut piece_matches);
|
||||||
|
}
|
||||||
|
|
||||||
|
// println!("{:?}", piece_matches);
|
||||||
|
|
||||||
|
// And now we find which pieces are adjacent (same edge) to which other pieces (not caring about orientation at all)
|
||||||
|
let mut edge_matches: HashMap<u32, usize> = HashMap::new();
|
||||||
|
for piece_match in piece_matches {
|
||||||
|
if piece_match.1.len() == 1 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
piece_match.1.iter().for_each(|m| { edge_matches.entry(m.clone()).and_modify(|c| *c += 1 ).or_insert(1); })
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("{:?}", edge_matches);
|
||||||
|
let corner_pieces: Vec<u32> = edge_matches.iter().filter(|e| e.1 == &2).map(|e| e.0.clone()).collect::<Vec<_>>();
|
||||||
|
|
||||||
|
assert_eq!(corner_pieces.len(), 4);
|
||||||
|
|
||||||
|
let part1 = corner_pieces.iter().fold(1u64, |a, b| a as u64 * b.clone() as u64);
|
||||||
|
println!("Day X Part 1: {}", part1);
|
||||||
|
|
||||||
|
|
||||||
|
let part2 = 0;
|
||||||
|
println!("Day X Part 2: {}", part2);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_to_piece_matches(piece_id: u32, edge: &PieceLine, flipped_edge: &PieceLine, piece_matches: &mut HashMap<u16, Vec<u32>>) {
|
||||||
|
|
||||||
|
let use_flipped = flipped_edge.data < edge.data;
|
||||||
|
let bookkeeping_edge = if use_flipped { flipped_edge } else { edge };
|
||||||
|
|
||||||
|
piece_matches.entry(bookkeeping_edge.data).and_modify(|d| d.push(piece_id)).or_insert(vec![ piece_id ]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
struct Piece {
|
||||||
|
|
||||||
|
id: u32,
|
||||||
|
piece_lines: Vec<PieceLine>,
|
||||||
|
|
||||||
|
// left to right top edge
|
||||||
|
top_edge: PieceLine,
|
||||||
|
// left to right bottom edge
|
||||||
|
bottom_edge: PieceLine,
|
||||||
|
// Left edge (from top to bottom)
|
||||||
|
left_edge: PieceLine,
|
||||||
|
// Right edge (from to to bottom)
|
||||||
|
right_edge: PieceLine,
|
||||||
|
// Right to left top edge
|
||||||
|
flipped_top_edge: PieceLine,
|
||||||
|
// Right to left bottom edge
|
||||||
|
flipped_bottom_edge: PieceLine,
|
||||||
|
// Bottom to top left edge
|
||||||
|
flipped_left_edge: PieceLine,
|
||||||
|
// Bottom to top right edge
|
||||||
|
flipped_right_edge: PieceLine,
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Piece {
|
||||||
|
|
||||||
|
fn from(id: u32, piece_lines: Vec<PieceLine>) -> Piece {
|
||||||
|
|
||||||
|
let top_edge = piece_lines[0].clone();
|
||||||
|
let bottom_edge = piece_lines[(PIECE_SIZE - 1) as usize].clone();
|
||||||
|
let left_edge = Piece::get_vertical(0, &piece_lines);
|
||||||
|
let right_edge = Piece::get_vertical(PIECE_SIZE - 1, &piece_lines);
|
||||||
|
|
||||||
|
return Piece {
|
||||||
|
id, piece_lines,
|
||||||
|
flipped_top_edge: top_edge.flipped(), flipped_bottom_edge: bottom_edge.flipped(),
|
||||||
|
flipped_left_edge: left_edge.flipped(), flipped_right_edge: right_edge.flipped(),
|
||||||
|
top_edge, bottom_edge, left_edge, right_edge,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_vertical(x: u16, piece_lines: &Vec<PieceLine>) -> PieceLine {
|
||||||
|
let mut vert = 0;
|
||||||
|
for i in 0..PIECE_SIZE {
|
||||||
|
if piece_lines[i as usize].get(x as usize) {
|
||||||
|
vert |= 1 << i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return PieceLine { data: vert };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
|
struct PieceLine {
|
||||||
|
data: u16,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PieceLine {
|
||||||
|
fn parse(line: &String) -> PieceLine {
|
||||||
|
|
||||||
|
let mut data = 0u16;
|
||||||
|
let mut i = 0;
|
||||||
|
for char in line.chars() {
|
||||||
|
if char == '#' {
|
||||||
|
data |= 1 << i;
|
||||||
|
}
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PieceLine { data };
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get(&self, i: usize) -> bool {
|
||||||
|
|
||||||
|
let mask = 1u16 << i;
|
||||||
|
return self.data & mask == mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn flipped(&self) -> PieceLine {
|
||||||
|
let mut res = 0u16;
|
||||||
|
for i in 0..PIECE_SIZE {
|
||||||
|
if self.get(i as usize) {
|
||||||
|
res |= 1 << (PIECE_SIZE - i - 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return PieceLine { data: res };
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,8 +21,9 @@ mod day16;
|
|||||||
mod day17;
|
mod day17;
|
||||||
mod day18;
|
mod day18;
|
||||||
mod day19;
|
mod day19;
|
||||||
|
mod day20;
|
||||||
|
|
||||||
const MAX_DAY: u8 = 19;
|
const MAX_DAY: u8 = 20;
|
||||||
const BENCHMARK_AMOUNT: u32 = 100;
|
const BENCHMARK_AMOUNT: u32 = 100;
|
||||||
|
|
||||||
fn solve(day: u8) {
|
fn solve(day: u8) {
|
||||||
@@ -46,6 +47,7 @@ fn solve(day: u8) {
|
|||||||
17 => day17::solve(),
|
17 => day17::solve(),
|
||||||
18 => day18::solve(),
|
18 => day18::solve(),
|
||||||
19 => day19::solve(),
|
19 => day19::solve(),
|
||||||
|
20 => day20::solve(),
|
||||||
_ => println!("This day is not yet implemented")
|
_ => println!("This day is not yet implemented")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user