11use 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} ;
55use 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-
191104fn 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
195121pub 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