Skip to content

Commit f39d6fc

Browse files
committed
Added skyscrapers and finalized both
It was simpler to bundle both in the same PR
1 parent 0e5ee8b commit f39d6fc

5 files changed

Lines changed: 77 additions & 229 deletions

File tree

cspuz_rs/src/serializer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1272,7 +1272,7 @@ where
12721272
let input = &input[0];
12731273

12741274
let surrounding = [&input.0[..], &input.1[..], &input.2[..], &input.3[..]].concat();
1275-
let ret = Seq::new(&self.base_serializer, width + height)
1275+
let ret = Seq::new(&self.base_serializer, 2 * (width + height))
12761276
.serialize(ctx, &[surrounding])?
12771277
.1;
12781278

cspuz_rs_puzzles/src/puzzles/easyasabc.rs

Lines changed: 26 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use cspuz_rs::serializer::{
2-
problem_to_url_with_context, url_to_problem, Choice, Combinator, Context, ContextBasedGrid,
3-
DecInt, HexInt, Optionalize, PrefixAndSuffix, Seq, Sequencer, Size, Spaces, Tuple2,
2+
problem_to_url_with_context, url_to_problem, Choice, Choice2, Combinator, Context,
3+
ContextBasedGrid, DecInt, Dict, HexInt, Optionalize, OutsideCells4, PrefixAndSuffix, Size,
4+
Spaces, Tuple3,
45
};
56
use cspuz_rs::solver::Solver;
67

@@ -72,107 +73,32 @@ pub fn solve_easy_as_abc(
7273
solver.irrefutable_facts().map(|f| f.get(numbers))
7374
}
7475

75-
pub type Grid = (
76-
Vec<Option<i32>>,
77-
Vec<Option<i32>>,
78-
Vec<Option<i32>>,
79-
Vec<Option<i32>>,
76+
pub type Problem = (
77+
i32,
78+
(
79+
Vec<Option<i32>>,
80+
Vec<Option<i32>>,
81+
Vec<Option<i32>>,
82+
Vec<Option<i32>>,
83+
),
8084
Option<Vec<Vec<Option<i32>>>>,
8185
);
8286

83-
pub type Problem = (i32, Grid);
84-
85-
fn internal_combinator() -> impl Combinator<Option<i32>> {
86-
Choice::new(vec![
87-
Box::new(Optionalize::new(HexInt)),
88-
Box::new(Spaces::new(None, 'g')),
89-
])
90-
}
91-
92-
pub struct GridCombinator;
93-
94-
impl Combinator<Grid> for GridCombinator {
95-
fn serialize(
96-
&self,
97-
ctx: &cspuz_rs::serializer::Context,
98-
input: &[Grid],
99-
) -> Option<(usize, Vec<u8>)> {
100-
if input.is_empty() {
101-
return None;
102-
}
103-
104-
let height = ctx.height?;
105-
let width = ctx.width?;
106-
107-
let problem = &input[0];
108-
109-
let surrounding = [
110-
&problem.0[..],
111-
&problem.1[..],
112-
&problem.2[..],
113-
&problem.3[..],
114-
]
115-
.concat();
116-
let mut ret = Seq::new(internal_combinator(), 2 * (width + height))
117-
.serialize(ctx, &[surrounding])?
118-
.1;
119-
120-
if let Some(cells) = &problem.4 {
121-
ret.extend(
122-
ContextBasedGrid::new(internal_combinator())
123-
.serialize(ctx, &[cells.clone()])?
124-
.1,
125-
);
126-
}
127-
128-
Some((1, ret))
129-
}
130-
131-
fn deserialize(
132-
&self,
133-
ctx: &cspuz_rs::serializer::Context,
134-
input: &[u8],
135-
) -> Option<(usize, Vec<Grid>)> {
136-
let mut sequencer = Sequencer::new(input);
137-
138-
let height = ctx.height?;
139-
let width = ctx.width?;
140-
141-
let surrounding =
142-
sequencer.deserialize(ctx, Seq::new(internal_combinator(), 2 * (width + height)))?;
143-
if surrounding.len() != 1 {
144-
return None;
145-
}
146-
let surrounding = surrounding.into_iter().next().unwrap();
147-
148-
let clues_up = surrounding[..width].to_vec();
149-
let clues_down = surrounding[width..(2 * width)].to_vec();
150-
let clues_left = surrounding[(2 * width)..(2 * width + height)].to_vec();
151-
let clues_right = surrounding[(2 * width + height)..].to_vec();
152-
153-
if sequencer.n_remaining() > 0 {
154-
let cells = sequencer.deserialize(ctx, ContextBasedGrid::new(internal_combinator()))?;
155-
if cells.len() != 1 {
156-
return None;
157-
}
158-
let cells = cells.into_iter().next().unwrap();
159-
Some((
160-
sequencer.n_read(),
161-
vec![(clues_up, clues_down, clues_left, clues_right, Some(cells))],
162-
))
163-
} else {
164-
Some((
165-
sequencer.n_read(),
166-
vec![(clues_up, clues_down, clues_left, clues_right, None)],
167-
))
168-
}
169-
}
170-
}
171-
17287
fn combinator() -> impl Combinator<Problem> {
173-
Size::new(Tuple2::new(
88+
Size::new(Tuple3::new(
17489
PrefixAndSuffix::new("", DecInt, "/"),
175-
GridCombinator,
90+
OutsideCells4::new(Choice::new(vec![
91+
Box::new(Optionalize::new(HexInt)),
92+
Box::new(Spaces::new(None, 'g')),
93+
])),
94+
Choice2::new(
95+
Optionalize::new(ContextBasedGrid::new(Choice::new(vec![
96+
Box::new(Optionalize::new(HexInt)),
97+
Box::new(Dict::new(Some(-1), ".")),
98+
Box::new(Spaces::new(None, 'g')),
99+
]))),
100+
Dict::new(None, ""),
101+
),
176102
))
177103
}
178104

@@ -205,15 +131,15 @@ mod tests {
205131
vec![None, None, None, None],
206132
vec![Some(2), None, None, Some(3)],
207133
vec![None, Some(3), None, None],
208-
None,
209134
),
135+
None,
210136
)
211137
}
212138

213139
#[test]
214140
fn test_easy_as_abc_problem() {
215141
{
216-
let (range, (clues_up, clues_down, clues_left, clues_right, cells)) =
142+
let (range, (clues_up, clues_down, clues_left, clues_right), cells) =
217143
problem_for_tests();
218144
let ans = solve_easy_as_abc(
219145
range,

cspuz_rs_puzzles/src/puzzles/skyscrapers.rs

Lines changed: 32 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use cspuz_rs::serializer::{
2-
problem_to_url_with_context, url_to_problem, Choice, Combinator, Context, ContextBasedGrid,
3-
HexInt, Optionalize, Seq, Sequencer, Size, Spaces,
2+
problem_to_url_with_context, url_to_problem, Choice, Choice2, Combinator, Context,
3+
ContextBasedGrid, Dict, HexInt, Optionalize, OutsideCells4, Size, Spaces, Tuple2,
44
};
55
use cspuz_rs::solver::{count_true, Solver};
66

@@ -91,110 +91,36 @@ pub fn solve_skyscrapers(
9191
solver.irrefutable_facts().map(|f| f.get(num))
9292
}
9393

94-
pub type Grid = (
95-
Vec<Option<i32>>,
96-
Vec<Option<i32>>,
97-
Vec<Option<i32>>,
98-
Vec<Option<i32>>,
94+
pub type Problem = (
95+
(
96+
Vec<Option<i32>>,
97+
Vec<Option<i32>>,
98+
Vec<Option<i32>>,
99+
Vec<Option<i32>>,
100+
),
99101
Option<Vec<Vec<Option<i32>>>>,
100102
);
101103

102-
pub type Problem = Grid;
103-
104-
fn internal_combinator() -> impl Combinator<Option<i32>> {
105-
Choice::new(vec![
106-
Box::new(Optionalize::new(HexInt)),
107-
Box::new(Spaces::new(None, 'g')),
108-
])
109-
}
110-
111-
pub struct GridCombinator;
112-
113-
impl Combinator<Grid> for GridCombinator {
114-
fn serialize(
115-
&self,
116-
ctx: &cspuz_rs::serializer::Context,
117-
input: &[Grid],
118-
) -> Option<(usize, Vec<u8>)> {
119-
if input.is_empty() {
120-
return None;
121-
}
122-
123-
let height = ctx.height?;
124-
let width = ctx.width?;
125-
126-
let problem = &input[0];
127-
128-
let surrounding = [
129-
&problem.0[..],
130-
&problem.1[..],
131-
&problem.2[..],
132-
&problem.3[..],
133-
]
134-
.concat();
135-
let mut ret = Seq::new(internal_combinator(), 2 * (width + height))
136-
.serialize(ctx, &[surrounding])?
137-
.1;
138-
139-
if let Some(cells) = &problem.4 {
140-
ret.extend(
141-
ContextBasedGrid::new(internal_combinator())
142-
.serialize(ctx, &[cells.clone()])?
143-
.1,
144-
);
145-
}
146-
147-
Some((1, ret))
148-
}
149-
150-
fn deserialize(
151-
&self,
152-
ctx: &cspuz_rs::serializer::Context,
153-
input: &[u8],
154-
) -> Option<(usize, Vec<Grid>)> {
155-
let mut sequencer = Sequencer::new(input);
156-
157-
let height = ctx.height?;
158-
let width = ctx.width?;
159-
160-
let surrounding =
161-
sequencer.deserialize(ctx, Seq::new(internal_combinator(), 2 * (width + height)))?;
162-
if surrounding.len() != 1 {
163-
return None;
164-
}
165-
let surrounding = surrounding.into_iter().next().unwrap();
166-
167-
let clues_up = surrounding[..width].to_vec();
168-
let clues_down = surrounding[width..(2 * width)].to_vec();
169-
let clues_left = surrounding[(2 * width)..(2 * width + height)].to_vec();
170-
let clues_right = surrounding[(2 * width + height)..].to_vec();
171-
172-
if sequencer.n_remaining() > 0 {
173-
let cells = sequencer.deserialize(ctx, ContextBasedGrid::new(internal_combinator()))?;
174-
if cells.len() != 1 {
175-
return None;
176-
}
177-
let cells = cells.into_iter().next().unwrap();
178-
Some((
179-
sequencer.n_read(),
180-
vec![(clues_up, clues_down, clues_left, clues_right, Some(cells))],
181-
))
182-
} else {
183-
Some((
184-
sequencer.n_read(),
185-
vec![(clues_up, clues_down, clues_left, clues_right, None)],
186-
))
187-
}
188-
}
189-
}
190-
191104
fn combinator() -> impl Combinator<Problem> {
192-
Size::new(GridCombinator)
105+
Size::new(Tuple2::new(
106+
OutsideCells4::new(Choice::new(vec![
107+
Box::new(Optionalize::new(HexInt)),
108+
Box::new(Spaces::new(None, 'g')),
109+
])),
110+
Choice2::new(
111+
Optionalize::new(ContextBasedGrid::new(Choice::new(vec![
112+
Box::new(Optionalize::new(HexInt)),
113+
Box::new(Dict::new(Some(-1), ".")),
114+
Box::new(Spaces::new(None, 'g')),
115+
]))),
116+
Dict::new(None, ""),
117+
),
118+
))
193119
}
194120

195121
pub fn serialize_problem(problem: &Problem) -> Option<String> {
196-
let height = problem.1.len();
197-
let width = problem.3.len();
122+
let height = problem.0 .1.len();
123+
let width = problem.0 .3.len();
198124

199125
problem_to_url_with_context(
200126
combinator(),
@@ -215,18 +141,20 @@ mod tests {
215141

216142
fn problem_for_tests() -> Problem {
217143
(
218-
vec![None, None, None, None],
219-
vec![None, Some(1), Some(3), None],
220-
vec![None, Some(4), None, None],
221-
vec![None, None, Some(3), None],
144+
(
145+
vec![None, None, None, None],
146+
vec![None, Some(1), Some(3), None],
147+
vec![None, Some(4), None, None],
148+
vec![None, None, Some(3), None],
149+
),
222150
None,
223151
)
224152
}
225153

226154
#[test]
227155
fn test_skyscrapers_problem() {
228156
{
229-
let (clues_up, clues_down, clues_left, clues_right, cells) = problem_for_tests();
157+
let ((clues_up, clues_down, clues_left, clues_right), cells) = problem_for_tests();
230158
let ans = solve_skyscrapers(&clues_up, &clues_down, &clues_left, &clues_right, &cells);
231159
assert!(ans.is_some());
232160
let ans = ans.unwrap();

0 commit comments

Comments
 (0)