Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 118 additions & 0 deletions cspuz_rs/src/serializer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1190,6 +1190,124 @@ where
Some((n_read, vec![(clue_vertical, clue_horizontal)]))
}
}

pub struct OutsideCells2<C> {
base_serializer: C,
}

impl<C> OutsideCells2<C> {
pub fn new(base_serializer: C) -> OutsideCells2<C> {
OutsideCells2 { base_serializer }
}
}

impl<T, C> Combinator<(Vec<T>, Vec<T>)> for OutsideCells2<C>
where
T: Clone + PartialEq,
C: Combinator<T>,
{
fn serialize(&self, ctx: &Context, input: &[(Vec<T>, Vec<T>)]) -> Option<(usize, Vec<u8>)> {
if input.len() == 0 {
return None;
}
let height = ctx.height?;
let width = ctx.width?;

let input = &input[0];

let surrounding = [&input.0[..], &input.1[..]].concat();
let ret = Seq::new(&self.base_serializer, width + height)
.serialize(ctx, &[surrounding])?
.1;

Some((1, ret))
}

fn deserialize(&self, ctx: &Context, input: &[u8]) -> Option<(usize, Vec<(Vec<T>, Vec<T>)>)> {
let mut sequencer = Sequencer::new(input);

let height = ctx.height?;
let width = ctx.width?;

let surrounding =
sequencer.deserialize(ctx, Seq::new(&self.base_serializer, width + height))?;
if surrounding.len() != 1 {
return None;
}
let surrounding = surrounding.into_iter().next().unwrap();

let clues_up = surrounding[..width].to_vec();
let clues_left = surrounding[width..].to_vec();

Some((sequencer.n_read(), vec![(clues_up, clues_left)]))
}
}

pub struct OutsideCells4<C> {
base_serializer: C,
}

impl<C> OutsideCells4<C> {
pub fn new(base_serializer: C) -> OutsideCells4<C> {
OutsideCells4 { base_serializer }
}
}

impl<T, C> Combinator<(Vec<T>, Vec<T>, Vec<T>, Vec<T>)> for OutsideCells4<C>
where
T: Clone + PartialEq,
C: Combinator<T>,
{
fn serialize(
&self,
ctx: &Context,
input: &[(Vec<T>, Vec<T>, Vec<T>, Vec<T>)],
) -> Option<(usize, Vec<u8>)> {
if input.len() == 0 {
return None;
}
let height = ctx.height?;
let width = ctx.width?;

let input = &input[0];

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

Some((1, ret))
}

fn deserialize(
&self,
ctx: &Context,
input: &[u8],
) -> Option<(usize, Vec<(Vec<T>, Vec<T>, Vec<T>, Vec<T>)>)> {
let mut sequencer = Sequencer::new(input);

let height = ctx.height?;
let width = ctx.width?;

let surrounding =
sequencer.deserialize(ctx, Seq::new(&self.base_serializer, 2 * (width + height)))?;
if surrounding.len() != 1 {
return None;
}
let surrounding = surrounding.into_iter().next().unwrap();

let clues_up = surrounding[..width].to_vec();
let clues_down = surrounding[width..(2 * width)].to_vec();
let clues_left = surrounding[(2 * width)..(2 * width + height)].to_vec();
let clues_right = surrounding[(2 * width + height)..].to_vec();

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I verified this order (up -> down -> left -> right) is consistent with that in Skyscrapers URLs


Some((
sequencer.n_read(),
vec![(clues_up, clues_down, clues_left, clues_right)],
))
}
}

pub struct Rooms;

impl Combinator<InnerGridEdges<Vec<Vec<bool>>>> for Rooms {
Expand Down
67 changes: 9 additions & 58 deletions cspuz_rs_puzzles/src/puzzles/aquarium.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use cspuz_rs::graph;
use cspuz_rs::serializer::{
problem_to_url_with_context, url_to_problem, Choice, Combinator, Context, Dict, HexInt,
Optionalize, PrefixAndSuffix, Rooms, Seq, Sequencer, Size, Spaces, Tuple2,
Optionalize, OutsideCells2, PrefixAndSuffix, Rooms, Size, Spaces, Tuple2,
};
use cspuz_rs::solver::Solver;

Expand Down Expand Up @@ -89,62 +89,6 @@ type Problem = (
),
);

fn internal_combinator() -> impl Combinator<Option<i32>> {
Choice::new(vec![
Box::new(Optionalize::new(HexInt)),
Box::new(Spaces::new(None, 'g')),
])
}

pub struct AquariumCombinator;

impl Combinator<(Vec<Option<i32>>, Vec<Option<i32>>)> for AquariumCombinator {
fn serialize(
&self,
ctx: &cspuz_rs::serializer::Context,
input: &[(Vec<Option<i32>>, Vec<Option<i32>>)],
) -> Option<(usize, Vec<u8>)> {
if input.is_empty() {
return None;
}

let height = ctx.height?;
let width = ctx.width?;

let problem = &input[0];

let surrounding = [&problem.0[..], &problem.1[..]].concat();
let ret = Seq::new(internal_combinator(), width + height)
.serialize(ctx, &[surrounding])?
.1;

Some((1, ret))
}

fn deserialize(
&self,
ctx: &cspuz_rs::serializer::Context,
input: &[u8],
) -> Option<(usize, Vec<(Vec<Option<i32>>, Vec<Option<i32>>)>)> {
let mut sequencer = Sequencer::new(input);

let height = ctx.height?;
let width = ctx.width?;

let surrounding =
sequencer.deserialize(ctx, Seq::new(internal_combinator(), width + height))?;
if surrounding.len() != 1 {
return None;
}
let surrounding = surrounding.into_iter().next().unwrap();

let clues_up = surrounding[..width].to_vec();
let clues_left = surrounding[width..].to_vec();

Some((sequencer.n_read(), vec![(clues_up, clues_left)]))
}
}

fn combinator() -> impl Combinator<Problem> {
Tuple2::new(
Choice::new(vec![
Expand All @@ -153,7 +97,14 @@ fn combinator() -> impl Combinator<Problem> {
]),
Size::new(Tuple2::new(
Rooms,
PrefixAndSuffix::new("/", AquariumCombinator, ""),
PrefixAndSuffix::new(
"/",
OutsideCells2::new(Choice::new(vec![
Box::new(Optionalize::new(HexInt)),
Box::new(Spaces::new(None, 'g')),
])),
"",
),
)),
)
}
Expand Down
Loading
Loading