[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 day18;
|
||||
mod day19;
|
||||
mod day20;
|
||||
|
||||
const MAX_DAY: u8 = 19;
|
||||
const MAX_DAY: u8 = 20;
|
||||
const BENCHMARK_AMOUNT: u32 = 100;
|
||||
|
||||
fn solve(day: u8) {
|
||||
@@ -46,6 +47,7 @@ fn solve(day: u8) {
|
||||
17 => day17::solve(),
|
||||
18 => day18::solve(),
|
||||
19 => day19::solve(),
|
||||
20 => day20::solve(),
|
||||
_ => println!("This day is not yet implemented")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user