Finish day 4
This commit is contained in:
85
day_04/README.md
Normal file
85
day_04/README.md
Normal file
@@ -0,0 +1,85 @@
|
||||
# --- Day 4: Ceres Search ---
|
||||
|
||||
"Looks like the Chief's not here. Next!" One of The Historians pulls out a device and pushes the only button on it. After a brief flash, you recognize the interior of the Ceres monitoring station!
|
||||
|
||||
As the search for the Chief continues, a small Elf who lives on the station tugs on your shirt; she'd like to know if you could help her with her word search (your puzzle input). She only has to find one word: `XMAS`.
|
||||
|
||||
This word search allows words to be horizontal, vertical, diagonal, written backwards, or even overlapping other words. It's a little unusual, though, as you don't merely need to find one instance of `XMAS` - you need to find all of them. Here are a few ways `XMAS` might appear, where irrelevant characters have been replaced with `.`:
|
||||
|
||||
```
|
||||
..X...
|
||||
.SAMX.
|
||||
.A..A.
|
||||
XMAS.S
|
||||
.X....
|
||||
```
|
||||
|
||||
The actual word search will be full of letters instead. For example:
|
||||
|
||||
```
|
||||
MMMSXXMASM
|
||||
MSAMXMSMSA
|
||||
AMXSXMAAMM
|
||||
MSAMASMSMX
|
||||
XMASAMXAMM
|
||||
XXAMMXXAMA
|
||||
SMSMSASXSS
|
||||
SAXAMASAAA
|
||||
MAMMMXMMMM
|
||||
MXMXAXMASX
|
||||
```
|
||||
|
||||
In this word search, XMAS occurs a total of 18 times; here's the same word search again, but where letters not involved in any XMAS have been replaced with .:
|
||||
|
||||
```
|
||||
....XXMAS.
|
||||
.SAMXMS...
|
||||
...S..A...
|
||||
..A.A.MS.X
|
||||
XMASAMX.MM
|
||||
X.....XA.A
|
||||
S.S.S.S.SS
|
||||
.A.A.A.A.A
|
||||
..M.M.M.MM
|
||||
.X.X.XMASX
|
||||
```
|
||||
|
||||
Take a look at the little Elf's word search. How many times does XMAS appear?
|
||||
|
||||
Your puzzle answer was 2524.
|
||||
# --- Part Two ---
|
||||
|
||||
The Elf looks quizzically at you. Did you misunderstand the assignment?
|
||||
|
||||
Looking for the instructions, you flip over the word search to find that this isn't actually an XMAS puzzle; it's an X-MAS puzzle in which you're supposed to find two MAS in the shape of an X. One way to achieve that is like this:
|
||||
|
||||
```
|
||||
M.S
|
||||
.A.
|
||||
M.S
|
||||
```
|
||||
|
||||
Irrelevant characters have again been replaced with . in the above diagram. Within the X, each MAS can be written forwards or backwards.
|
||||
|
||||
Here's the same example from before, but this time all of the X-MASes have been kept instead:
|
||||
|
||||
```
|
||||
.M.S......
|
||||
..A..MSMS.
|
||||
.M.S.MAA..
|
||||
..A.ASMSM.
|
||||
.M.S.M....
|
||||
..........
|
||||
S.S.S.S.S.
|
||||
.A.A.A.A..
|
||||
M.M.M.M.M.
|
||||
..........
|
||||
```
|
||||
|
||||
In this example, an X-MAS appears 9 times.
|
||||
|
||||
Flip the word search from the instructions back over to the word search side and try again. How many times does an X-MAS appear?
|
||||
|
||||
Your puzzle answer was 1873.
|
||||
|
||||
Both parts of this puzzle are complete! They provide two gold stars: **
|
||||
@@ -28,18 +28,24 @@ impl<'a> CrosswordCell<'a> {
|
||||
self.value_by_index(self.x, self.y)
|
||||
}
|
||||
|
||||
fn take(&self, num_of_letters: usize, direction: (isize, isize)) -> String {
|
||||
fn take(&self, num_of_letters: usize, direction: (isize, isize), start: isize) -> String {
|
||||
let mut word = String::new();
|
||||
|
||||
for i in 0..num_of_letters {
|
||||
let x = self.x as isize + (i as isize * direction.1);
|
||||
let y = self.y as isize + (i as isize * direction.0);
|
||||
let end = start + num_of_letters as isize;
|
||||
|
||||
for i in start..end {
|
||||
let x = self.x as isize + (i * direction.1);
|
||||
let y = self.y as isize + (i * direction.0);
|
||||
if x < 0
|
||||
|| x >= self.crossword.width as isize
|
||||
|| y < 0
|
||||
|| y >= self.crossword.height as isize
|
||||
{
|
||||
break;
|
||||
if i < 0 {
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
word.push(self.value_by_index(x as usize, y as usize));
|
||||
}
|
||||
@@ -47,36 +53,76 @@ impl<'a> CrosswordCell<'a> {
|
||||
word
|
||||
}
|
||||
|
||||
const DIRECTION_N: (isize, isize) = (-1, 0);
|
||||
pub fn n(&self, num_of_letters: usize) -> String {
|
||||
self.take(num_of_letters, (-1, 0))
|
||||
self.take(num_of_letters, CrosswordCell::DIRECTION_N, 0)
|
||||
}
|
||||
|
||||
pub fn n2(&self, num_of_letters: usize, start: isize) -> String {
|
||||
self.take(num_of_letters, CrosswordCell::DIRECTION_N, start)
|
||||
}
|
||||
|
||||
const DIRECTION_NE: (isize, isize) = (-1, 1);
|
||||
pub fn ne(&self, num_of_letters: usize) -> String {
|
||||
self.take(num_of_letters, (-1, 1))
|
||||
self.take(num_of_letters, CrosswordCell::DIRECTION_NE, 0)
|
||||
}
|
||||
|
||||
pub fn ne2(&self, num_of_letters: usize, start: isize) -> String {
|
||||
self.take(num_of_letters, CrosswordCell::DIRECTION_NE, start)
|
||||
}
|
||||
|
||||
const DIRECTION_E: (isize, isize) = (0, 1);
|
||||
pub fn e(&self, num_of_letters: usize) -> String {
|
||||
self.take(num_of_letters, (0, 1))
|
||||
self.take(num_of_letters, CrosswordCell::DIRECTION_E, 0)
|
||||
}
|
||||
|
||||
pub fn e2(&self, num_of_letters: usize, start: isize) -> String {
|
||||
self.take(num_of_letters, CrosswordCell::DIRECTION_E, start)
|
||||
}
|
||||
|
||||
const DIRECTION_SE: (isize, isize) = (1, 1);
|
||||
pub fn se(&self, num_of_letters: usize) -> String {
|
||||
self.take(num_of_letters, (1, 1))
|
||||
self.take(num_of_letters, CrosswordCell::DIRECTION_SE, 0)
|
||||
}
|
||||
|
||||
pub fn se2(&self, num_of_letters: usize, start: isize) -> String {
|
||||
self.take(num_of_letters, CrosswordCell::DIRECTION_SE, start)
|
||||
}
|
||||
|
||||
const DIRECTION_S: (isize, isize) = (1, 0);
|
||||
pub fn s(&self, num_of_letters: usize) -> String {
|
||||
self.take(num_of_letters, (1, 0))
|
||||
self.take(num_of_letters, CrosswordCell::DIRECTION_S, 0)
|
||||
}
|
||||
|
||||
pub fn s2(&self, num_of_letters: usize, start: isize) -> String {
|
||||
self.take(num_of_letters, CrosswordCell::DIRECTION_S, start)
|
||||
}
|
||||
|
||||
const DIRECTION_SW: (isize, isize) = (1, -1);
|
||||
pub fn sw(&self, num_of_letters: usize) -> String {
|
||||
self.take(num_of_letters, (1, -1))
|
||||
self.take(num_of_letters, CrosswordCell::DIRECTION_SW, 0)
|
||||
}
|
||||
|
||||
pub fn sw2(&self, num_of_letters: usize, start: isize) -> String {
|
||||
self.take(num_of_letters, CrosswordCell::DIRECTION_SW, start)
|
||||
}
|
||||
|
||||
const DIRECTION_W: (isize, isize) = (0, -1);
|
||||
pub fn w(&self, num_of_letters: usize) -> String {
|
||||
self.take(num_of_letters, (0, -1))
|
||||
self.take(num_of_letters, CrosswordCell::DIRECTION_W, 0)
|
||||
}
|
||||
|
||||
pub fn w2(&self, num_of_letters: usize, start: isize) -> String {
|
||||
self.take(num_of_letters, CrosswordCell::DIRECTION_W, start)
|
||||
}
|
||||
|
||||
const DIRECTION_NW: (isize, isize) = (-1, -1);
|
||||
pub fn nw(&self, num_of_letters: usize) -> String {
|
||||
self.take(num_of_letters, (-1, -1))
|
||||
self.take(num_of_letters, CrosswordCell::DIRECTION_NW, 0)
|
||||
}
|
||||
|
||||
pub fn nw2(&self, num_of_letters: usize, start: isize) -> String {
|
||||
self.take(num_of_letters, CrosswordCell::DIRECTION_NW, start)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,6 +244,10 @@ mod tests {
|
||||
assert_eq!(crossword.cell(1, 1).n(1), "5");
|
||||
assert_eq!(crossword.cell(1, 1).n(2), "52");
|
||||
assert_eq!(crossword.cell(1, 1).n(3), "52");
|
||||
assert_eq!(crossword.cell(1, 1).n2(3, 1), "2");
|
||||
assert_eq!(crossword.cell(1, 1).n2(3, 0), "52");
|
||||
assert_eq!(crossword.cell(1, 1).n2(3, -1), "852");
|
||||
assert_eq!(crossword.cell(1, 1).n2(3, -2), "85");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -207,6 +257,10 @@ mod tests {
|
||||
assert_eq!(crossword.cell(1, 1).ne(1), "5");
|
||||
assert_eq!(crossword.cell(1, 1).ne(2), "53");
|
||||
assert_eq!(crossword.cell(1, 1).ne(3), "53");
|
||||
assert_eq!(crossword.cell(1, 1).ne2(3, 1), "3");
|
||||
assert_eq!(crossword.cell(1, 1).ne2(3, 0), "53");
|
||||
assert_eq!(crossword.cell(1, 1).ne2(3, -1), "753");
|
||||
assert_eq!(crossword.cell(1, 1).ne2(3, -2), "75");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -216,6 +270,10 @@ mod tests {
|
||||
assert_eq!(crossword.cell(1, 1).e(1), "5");
|
||||
assert_eq!(crossword.cell(1, 1).e(2), "56");
|
||||
assert_eq!(crossword.cell(1, 1).e(3), "56");
|
||||
assert_eq!(crossword.cell(1, 1).e2(3, 1), "6");
|
||||
assert_eq!(crossword.cell(1, 1).e2(3, 0), "56");
|
||||
assert_eq!(crossword.cell(1, 1).e2(3, -1), "456");
|
||||
assert_eq!(crossword.cell(1, 1).e2(3, -2), "45");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -225,6 +283,10 @@ mod tests {
|
||||
assert_eq!(crossword.cell(1, 1).se(1), "5");
|
||||
assert_eq!(crossword.cell(1, 1).se(2), "59");
|
||||
assert_eq!(crossword.cell(1, 1).se(3), "59");
|
||||
assert_eq!(crossword.cell(1, 1).se2(3, 1), "9");
|
||||
assert_eq!(crossword.cell(1, 1).se2(3, 0), "59");
|
||||
assert_eq!(crossword.cell(1, 1).se2(3, -1), "159");
|
||||
assert_eq!(crossword.cell(1, 1).se2(3, -2), "15");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -234,6 +296,10 @@ mod tests {
|
||||
assert_eq!(crossword.cell(1, 1).s(1), "5");
|
||||
assert_eq!(crossword.cell(1, 1).s(2), "58");
|
||||
assert_eq!(crossword.cell(1, 1).s(3), "58");
|
||||
assert_eq!(crossword.cell(1, 1).s2(3, 1), "8");
|
||||
assert_eq!(crossword.cell(1, 1).s2(3, 0), "58");
|
||||
assert_eq!(crossword.cell(1, 1).s2(3, -1), "258");
|
||||
assert_eq!(crossword.cell(1, 1).s2(3, -2), "25");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -243,6 +309,10 @@ mod tests {
|
||||
assert_eq!(crossword.cell(1, 1).sw(1), "5");
|
||||
assert_eq!(crossword.cell(1, 1).sw(2), "57");
|
||||
assert_eq!(crossword.cell(1, 1).sw(3), "57");
|
||||
assert_eq!(crossword.cell(1, 1).sw2(3, 1), "7");
|
||||
assert_eq!(crossword.cell(1, 1).sw2(3, 0), "57");
|
||||
assert_eq!(crossword.cell(1, 1).sw2(3, -1), "357");
|
||||
assert_eq!(crossword.cell(1, 1).sw2(3, -2), "35");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -252,6 +322,10 @@ mod tests {
|
||||
assert_eq!(crossword.cell(1, 1).w(1), "5");
|
||||
assert_eq!(crossword.cell(1, 1).w(2), "54");
|
||||
assert_eq!(crossword.cell(1, 1).w(3), "54");
|
||||
assert_eq!(crossword.cell(1, 1).w2(3, 1), "4");
|
||||
assert_eq!(crossword.cell(1, 1).w2(3, 0), "54");
|
||||
assert_eq!(crossword.cell(1, 1).w2(3, -1), "654");
|
||||
assert_eq!(crossword.cell(1, 1).w2(3, -2), "65");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -261,5 +335,9 @@ mod tests {
|
||||
assert_eq!(crossword.cell(1, 1).nw(1), "5");
|
||||
assert_eq!(crossword.cell(1, 1).nw(2), "51");
|
||||
assert_eq!(crossword.cell(1, 1).nw(3), "51");
|
||||
assert_eq!(crossword.cell(1, 1).nw2(3, 1), "1");
|
||||
assert_eq!(crossword.cell(1, 1).nw2(3, 0), "51");
|
||||
assert_eq!(crossword.cell(1, 1).nw2(3, -1), "951");
|
||||
assert_eq!(crossword.cell(1, 1).nw2(3, -2), "95");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
//
|
||||
// Run command: cargo run ./input.txt
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
use std::env;
|
||||
use std::error::Error;
|
||||
use std::fs::File;
|
||||
@@ -64,9 +66,23 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
}
|
||||
|
||||
println!(
|
||||
"Count of the work '{}' in crossword: {}",
|
||||
"Count of the word '{}' in crossword: {}",
|
||||
word_to_find, count
|
||||
);
|
||||
|
||||
let mas = "MAS".to_owned();
|
||||
let mas_rev = mas.chars().rev().collect::<String>();
|
||||
let mut count = 0;
|
||||
for cell in crossword.iter_cells() {
|
||||
let se_word = cell.se2(3, -1);
|
||||
let sw_word = cell.sw2(3, -1);
|
||||
|
||||
if (se_word == mas || se_word == mas_rev) && (sw_word == mas || sw_word == mas_rev) {
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
println!("Count of the MAS Xes in crossword: {}", count);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user