Skip to content

Commit c832ca6

Browse files
committed
CQ problem 14
1 parent 2476a98 commit c832ca6

File tree

3 files changed

+115
-16
lines changed

3 files changed

+115
-16
lines changed

codingquest_clp_solutions/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@ use codingquest_clp::build_solvers;
66

77
pub mod helpers;
88
pub mod problem_13;
9+
pub mod problem_14;
910

1011
pub type Error = codingquest_clp::Error;
1112
pub type Result<T> = codingquest_clp::Result<T>;
1213

1314
build_solvers! {
14-
[13]
15+
[13, 14]
1516
}

codingquest_clp_solutions/src/problem_13.rs

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::ops::Deref;
2+
13
use codingquest_clp::solvers_impl::input::get_input;
24
use itertools::Itertools;
35

@@ -6,22 +8,23 @@ use crate::helpers::get_problem_input_data;
68
pub fn solve() -> usize {
79
let (board, moves) = input();
810

11+
let move_player = |p: &mut i32, p_move: i32| {
12+
*p += p_move;
13+
while (*p as usize) < board.len() && board[*p as usize] != 0 {
14+
*p += board[*p as usize];
15+
}
16+
};
17+
918
let mut p1 = 0;
1019
let mut p2 = 0;
11-
for (count, &(p1_move, p2_move)) in moves.moves.iter().enumerate() {
12-
p1 += p1_move;
13-
while (p1 as usize) < board.tiles.len() && board.tiles[p1 as usize] != 0 {
14-
p1 += board.tiles[p1 as usize];
15-
}
16-
if (p1 as usize) >= board.tiles.len() {
20+
for (count, &(p1_move, p2_move)) in moves.iter().enumerate() {
21+
move_player(&mut p1, p1_move);
22+
if (p1 as usize) >= board.len() {
1723
return count + 1;
1824
}
1925

20-
p2 += p2_move;
21-
while (p2 as usize) < board.tiles.len() && board.tiles[p2 as usize] != 0 {
22-
p2 += board.tiles[p2 as usize];
23-
}
24-
if (p2 as usize) >= board.tiles.len() {
26+
move_player(&mut p2, p2_move);
27+
if (p2 as usize) >= board.len() {
2528
return 2 * (count + 1);
2629
}
2730
}
@@ -35,13 +38,13 @@ fn input() -> (Board, Moves) {
3538
}
3639

3740
struct Board {
38-
pub tiles: Vec<i32>,
41+
tiles: Vec<i32>,
3942
}
4043

4144
const BOARD_SIZE: usize = 20;
4245

4346
impl Board {
44-
fn from_input_data<I>(input_data: I) -> Self
47+
pub fn from_input_data<I>(input_data: I) -> Self
4548
where
4649
I: AsRef<str>,
4750
{
@@ -70,12 +73,20 @@ impl Board {
7073
}
7174
}
7275

76+
impl Deref for Board {
77+
type Target = [i32];
78+
79+
fn deref(&self) -> &Self::Target {
80+
&self.tiles
81+
}
82+
}
83+
7384
struct Moves {
74-
pub moves: Vec<(i32, i32)>,
85+
moves: Vec<(i32, i32)>,
7586
}
7687

7788
impl Moves {
78-
fn from_input_data<I>(input_data: I) -> Self
89+
pub fn from_input_data<I>(input_data: I) -> Self
7990
where
8091
I: AsRef<str>,
8192
{
@@ -93,3 +104,11 @@ impl Moves {
93104
}
94105
}
95106
}
107+
108+
impl Deref for Moves {
109+
type Target = [(i32, i32)];
110+
111+
fn deref(&self) -> &Self::Target {
112+
&self.moves
113+
}
114+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
use std::collections::{HashMap, HashSet};
2+
3+
use codingquest_clp::solvers_impl::input::get_input;
4+
use itertools::Itertools;
5+
6+
use crate::helpers::get_problem_input_data;
7+
8+
pub fn solve() -> String {
9+
let word_list = word_list();
10+
let rules: Rules = GUESSES.into();
11+
12+
word_list
13+
.into_iter()
14+
.filter(|word| rules.matches(word))
15+
.exactly_one()
16+
.unwrap()
17+
.clone()
18+
}
19+
20+
fn word_list() -> Vec<String> {
21+
get_input(get_problem_input_data(14).unwrap())
22+
.unwrap()
23+
.safe_into_many()
24+
}
25+
26+
const GUESSES: &[(&str, &str)] =
27+
&[("keyless", "YYBBYYG"), ("society", "YGYYYBB"), ("phobias", "BBGBGBG")];
28+
29+
#[derive(Debug, Default)]
30+
struct Rules {
31+
green: HashMap<usize, char>,
32+
yellow: HashSet<char>,
33+
black: HashSet<char>,
34+
}
35+
36+
impl Rules {
37+
pub fn matches<S>(&self, word: S) -> bool
38+
where
39+
S: AsRef<str>,
40+
{
41+
let word = word.as_ref();
42+
43+
word.chars()
44+
.enumerate()
45+
.filter(|(i, c)| {
46+
if let Some(green) = self.green.get(i) {
47+
green == c
48+
} else {
49+
self.yellow.contains(c) && !self.black.contains(c)
50+
}
51+
})
52+
.count()
53+
== word.len()
54+
}
55+
}
56+
57+
impl From<&[(&str, &str)]> for Rules {
58+
fn from(value: &[(&str, &str)]) -> Self {
59+
let rules: HashMap<_, _> = value
60+
.iter()
61+
.flat_map(|&(guess, colored)| {
62+
guess
63+
.chars()
64+
.enumerate()
65+
.zip_eq(colored.chars())
66+
.map(|((i, g), color)| (color, (i, g)))
67+
})
68+
.into_group_map();
69+
70+
let color_rule = |color| rules.get(&color).unwrap().clone();
71+
let simple_color_rule = |color| color_rule(color).into_iter().map(|(_, g)| g).collect();
72+
let indexed_color_rule = |color| color_rule(color).into_iter().collect();
73+
74+
let green = indexed_color_rule('G');
75+
let yellow = simple_color_rule('Y');
76+
let black = simple_color_rule('B');
77+
Self { green, yellow, black }
78+
}
79+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy