Day 4 part 1 complete
This commit is contained in:
@@ -10,25 +10,99 @@ pub struct Crossword {
|
||||
height: usize,
|
||||
}
|
||||
|
||||
pub struct WordPuller<'a> {
|
||||
pub struct CrosswordCell<'a> {
|
||||
x: usize,
|
||||
y: usize,
|
||||
direction: (isize, isize),
|
||||
crossword: &'a Crossword,
|
||||
}
|
||||
|
||||
impl<'a> WordPuller<'a> {
|
||||
pub fn take(&self, num_of_letters: usize) -> String {
|
||||
impl<'a> CrosswordCell<'a> {
|
||||
fn value_by_index(&self, x: usize, y: usize) -> char {
|
||||
// x and y are reverse because we store by row
|
||||
//
|
||||
// data[ROW][COLUMN]
|
||||
self.crossword.data[y][x]
|
||||
}
|
||||
|
||||
pub fn value(&self) -> char {
|
||||
self.value_by_index(self.x, self.y)
|
||||
}
|
||||
|
||||
fn take(&self, num_of_letters: usize, direction: (isize, isize)) -> String {
|
||||
let mut word = String::new();
|
||||
|
||||
for i in 0..num_of_letters {
|
||||
let x = self.x as isize + (i as isize * self.direction.0);
|
||||
let y = self.y as isize + (i as isize * self.direction.1);
|
||||
word.push(self.crossword.data[x as usize][y as usize]);
|
||||
let x = self.x as isize + (i as isize * direction.1);
|
||||
let y = self.y as isize + (i as isize * direction.0);
|
||||
if x < 0
|
||||
|| x >= self.crossword.width as isize
|
||||
|| y < 0
|
||||
|| y >= self.crossword.height as isize
|
||||
{
|
||||
break;
|
||||
}
|
||||
word.push(self.value_by_index(x as usize, y as usize));
|
||||
}
|
||||
|
||||
word
|
||||
}
|
||||
|
||||
pub fn n(&self, num_of_letters: usize) -> String {
|
||||
self.take(num_of_letters, (-1, 0))
|
||||
}
|
||||
|
||||
pub fn ne(&self, num_of_letters: usize) -> String {
|
||||
self.take(num_of_letters, (-1, 1))
|
||||
}
|
||||
|
||||
pub fn e(&self, num_of_letters: usize) -> String {
|
||||
self.take(num_of_letters, (0, 1))
|
||||
}
|
||||
|
||||
pub fn se(&self, num_of_letters: usize) -> String {
|
||||
self.take(num_of_letters, (1, 1))
|
||||
}
|
||||
|
||||
pub fn s(&self, num_of_letters: usize) -> String {
|
||||
self.take(num_of_letters, (1, 0))
|
||||
}
|
||||
|
||||
pub fn sw(&self, num_of_letters: usize) -> String {
|
||||
self.take(num_of_letters, (1, -1))
|
||||
}
|
||||
|
||||
pub fn w(&self, num_of_letters: usize) -> String {
|
||||
self.take(num_of_letters, (0, -1))
|
||||
}
|
||||
|
||||
pub fn nw(&self, num_of_letters: usize) -> String {
|
||||
self.take(num_of_letters, (-1, -1))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CrosswordIterator<'a> {
|
||||
crossword: &'a Crossword,
|
||||
position: usize,
|
||||
}
|
||||
|
||||
impl<'a> Iterator for CrosswordIterator<'a> {
|
||||
type Item = CrosswordCell<'a>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let y = self.position / self.crossword.width;
|
||||
let x = self.position - y * self.crossword.width;
|
||||
self.position += 1;
|
||||
|
||||
if x < self.crossword.width && y < self.crossword.height {
|
||||
Some(CrosswordCell {
|
||||
x,
|
||||
y,
|
||||
crossword: self.crossword,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Crossword {
|
||||
@@ -41,6 +115,8 @@ impl Crossword {
|
||||
input_buffer.read_line(&mut first_line)?;
|
||||
let first_line = first_line.trim_end().to_owned();
|
||||
let width = first_line.len();
|
||||
data.push(first_line.chars().collect());
|
||||
|
||||
for line in input_buffer.lines() {
|
||||
let line = line?;
|
||||
if line.len() != width {
|
||||
@@ -58,6 +134,16 @@ impl Crossword {
|
||||
})
|
||||
}
|
||||
|
||||
fn from_data(data: Vec<Vec<char>>) -> Crossword {
|
||||
let height = data.len();
|
||||
let width = data[0].len();
|
||||
Crossword {
|
||||
data,
|
||||
width,
|
||||
height,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn width(&self) -> usize {
|
||||
self.width
|
||||
}
|
||||
@@ -66,67 +152,17 @@ impl Crossword {
|
||||
self.height
|
||||
}
|
||||
|
||||
pub fn n(&self, x: usize, y: usize) -> WordPuller {
|
||||
WordPuller {
|
||||
x,
|
||||
y,
|
||||
direction: (-1, 0),
|
||||
pub fn iter_cells(&self) -> CrosswordIterator {
|
||||
CrosswordIterator {
|
||||
crossword: self,
|
||||
position: 0,
|
||||
}
|
||||
}
|
||||
pub fn ne(&self, x: usize, y: usize) -> WordPuller {
|
||||
WordPuller {
|
||||
|
||||
pub fn select_cell(&self, x: usize, y: usize) -> CrosswordCell {
|
||||
CrosswordCell {
|
||||
x,
|
||||
y,
|
||||
direction: (-1, 1),
|
||||
crossword: self,
|
||||
}
|
||||
}
|
||||
pub fn e(&self, x: usize, y: usize) -> WordPuller {
|
||||
WordPuller {
|
||||
x,
|
||||
y,
|
||||
direction: (0, 1),
|
||||
crossword: self,
|
||||
}
|
||||
}
|
||||
pub fn se(&self, x: usize, y: usize) -> WordPuller {
|
||||
WordPuller {
|
||||
x,
|
||||
y,
|
||||
direction: (1, 1),
|
||||
crossword: self,
|
||||
}
|
||||
}
|
||||
pub fn s(&self, x: usize, y: usize) -> WordPuller {
|
||||
WordPuller {
|
||||
x,
|
||||
y,
|
||||
direction: (1, 0),
|
||||
crossword: self,
|
||||
}
|
||||
}
|
||||
pub fn sw(&self, x: usize, y: usize) -> WordPuller {
|
||||
WordPuller {
|
||||
x,
|
||||
y,
|
||||
direction: (1, -1),
|
||||
crossword: self,
|
||||
}
|
||||
}
|
||||
pub fn w(&self, x: usize, y: usize) -> WordPuller {
|
||||
WordPuller {
|
||||
x,
|
||||
y,
|
||||
direction: (0, -1),
|
||||
crossword: self,
|
||||
}
|
||||
}
|
||||
pub fn nw(&self, x: usize, y: usize) -> WordPuller {
|
||||
WordPuller {
|
||||
x,
|
||||
y,
|
||||
direction: (-1, -1),
|
||||
crossword: self,
|
||||
}
|
||||
}
|
||||
@@ -141,3 +177,89 @@ impl Display for Crossword {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
// Note this useful idiom: importing names from outer (for mod tests) scope.
|
||||
use super::*;
|
||||
|
||||
fn small_test_crossword() -> Crossword {
|
||||
Crossword::from_data(vec![
|
||||
vec!['1', '2', '3'],
|
||||
vec!['4', '5', '6'],
|
||||
vec!['7', '8', '9'],
|
||||
])
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_north() {
|
||||
let crossword = small_test_crossword();
|
||||
assert_eq!(crossword.select_cell(1, 1).n(0), "");
|
||||
assert_eq!(crossword.select_cell(1, 1).n(1), "5");
|
||||
assert_eq!(crossword.select_cell(1, 1).n(2), "52");
|
||||
assert_eq!(crossword.select_cell(1, 1).n(3), "52");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_northeast() {
|
||||
let crossword = small_test_crossword();
|
||||
assert_eq!(crossword.select_cell(1, 1).ne(0), "");
|
||||
assert_eq!(crossword.select_cell(1, 1).ne(1), "5");
|
||||
assert_eq!(crossword.select_cell(1, 1).ne(2), "53");
|
||||
assert_eq!(crossword.select_cell(1, 1).ne(3), "53");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_east() {
|
||||
let crossword = small_test_crossword();
|
||||
assert_eq!(crossword.select_cell(1, 1).e(0), "");
|
||||
assert_eq!(crossword.select_cell(1, 1).e(1), "5");
|
||||
assert_eq!(crossword.select_cell(1, 1).e(2), "56");
|
||||
assert_eq!(crossword.select_cell(1, 1).e(3), "56");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_southeast() {
|
||||
let crossword = small_test_crossword();
|
||||
assert_eq!(crossword.select_cell(1, 1).se(0), "");
|
||||
assert_eq!(crossword.select_cell(1, 1).se(1), "5");
|
||||
assert_eq!(crossword.select_cell(1, 1).se(2), "59");
|
||||
assert_eq!(crossword.select_cell(1, 1).se(3), "59");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_south() {
|
||||
let crossword = small_test_crossword();
|
||||
assert_eq!(crossword.select_cell(1, 1).s(0), "");
|
||||
assert_eq!(crossword.select_cell(1, 1).s(1), "5");
|
||||
assert_eq!(crossword.select_cell(1, 1).s(2), "58");
|
||||
assert_eq!(crossword.select_cell(1, 1).s(3), "58");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_southwest() {
|
||||
let crossword = small_test_crossword();
|
||||
assert_eq!(crossword.select_cell(1, 1).sw(0), "");
|
||||
assert_eq!(crossword.select_cell(1, 1).sw(1), "5");
|
||||
assert_eq!(crossword.select_cell(1, 1).sw(2), "57");
|
||||
assert_eq!(crossword.select_cell(1, 1).sw(3), "57");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_west() {
|
||||
let crossword = small_test_crossword();
|
||||
assert_eq!(crossword.select_cell(1, 1).w(0), "");
|
||||
assert_eq!(crossword.select_cell(1, 1).w(1), "5");
|
||||
assert_eq!(crossword.select_cell(1, 1).w(2), "54");
|
||||
assert_eq!(crossword.select_cell(1, 1).w(3), "54");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_northwest() {
|
||||
let crossword = small_test_crossword();
|
||||
assert_eq!(crossword.select_cell(1, 1).nw(0), "");
|
||||
assert_eq!(crossword.select_cell(1, 1).nw(1), "5");
|
||||
assert_eq!(crossword.select_cell(1, 1).nw(2), "51");
|
||||
assert_eq!(crossword.select_cell(1, 1).nw(3), "51");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user