演者クラス:
1 php
2 クラス Deducer
3 {
4 プライベート $array ;
5 public function __construct( $array )
6 {
7 $this ->配列 = 配列();
8 for ( $row = 0 ; $row 9 {
10 for ( $column = 0 ; $column 11 {
12 $this ->配列 [ $row ][ $column ] = $array [ $row ][ $column ];
13
14 }
15 }
16 private function isFinished()
17 {
18 for ( $row = 0 ; $row ++ )
19 {
20 for ( $column = 0 ; $column < $column ++ )
21 {
22 if ( $this -> 配列 [ $row ] [ $column ] == 0 )
23 {
24 return false ;
25 }
26
27
28 戻り値 true ;
29 }
30 public function deduceAll()
31 {
32 if ( $this -> isFinished())
33 {
34戻る ;
35
36 for ( $row = 0 ; $row 37 {
38 for ( $column = 0 ; $column 39 {
40 if ( $this ->reducedFromOneZone( $this -> array , $row , $column ))
41 {
42 $this ->推測すべて();
43 戻る ;
44 }
45
46
47 for ( $row = 0 ; $row 48 {
49 if ( $this ->gt;reduceFromOneRow( $this ->array , $行 ))
50 {
51 $this ->推測すべて();
52 戻る ;
53
54 }
55 for ( $column = 0 ; $column 56 {
57 if ( $this ->reduceFromOneColumn( $this -> array , $column ) )
58 {
59 $this ->推測すべて();
60 戻る ;
61
62
63 for ( $row = 0 ; $row 64 {
65 if ( $this ->reduceFromThreeRows( $this -> array , $row , $row + 2 ))
66 {
67 $this ->推測すべて();
68 戻る ;
69
70 }
71 for ( $column = 0 ; $column 72 {
73 if ( $this ->reduceFromThreeColumns( $this -> array , $column , $column + 2 ))
74 {
75 $this ->推測すべて();
76 戻る ;
77
78
79
80 public function deduceOnce()
81 {
82 for ( $row = 0 ; $row 83 {
84列 = 0 ; $column 85 {
86 if ( $this -> array , $row , $column ))
87 {
88 戻る ;
89
90
91
92 for ( $row = 0 ; $row 93 {
94 if ( $this ->reduceFromOneRow( $this -> array , $行 ))
95 {
96 戻る ;
97
98
99 for ( $column = 0 ; $column 100 {
101 if ( $this ->reduceFromOneColumn( $this -> array , $column ) )
102 {
103 戻る ;
104
105
106 for ( $row = 0 ; $row 107 {
108 if ( $this ->reduceFromThreeRows( $this -> array , $row , $row + 2 ))
109 {
110 リターン ;
111
112 }
113 for ( $column = 0 ; $column 114 {
1 15 if ( $this ->reduceFromThreeColumns( $this -> array , $column , $column + 2 ))
116 {
117 リターン ;
118
119
120 }
121 プライベート 関数 reduceFromOneZone( & $array , $row , $column )
122 {
12 3 $startRow = (floor ( $row / 3 )) * 3 ;
124 $startColumn = (floor ( $column / 3 )) * 3 ;
125 $unknown = array ();
126 for ( $pointer = 0 ; $pointer 127 {
128 $unknown [ $pointer ] = $pointer + 1 ;
129 }
130 for ( $rowPointer = $startRow ; $rowPointer < $startRow + 3 ; $rowPointer ++ )
131 {
132 for ( = $startColumn <$startColumn + 3; columnPointer ++ )
133 {
134 if ( $array [ $rowPointer ][ $columnPointer ] != 0 )
135 {
136 $unknown [ $array [ $rowPointer ][ $columnPointer ] - 1 ] = 0 ;
137 }
138
139 }
140 for ( $digit = 0 ; $digit < 9 ; $digit ++ )
141 {
142 if ( $unknown [ $digit ] != 0 )
143 {
144 $number = $unknown [ $digit ];
145 $posibility = 0 ;
146 $rowPosition =- 1 ;
147 $columnPosition =- 1 ;
148 for ( $rowPointer = $startRow ; $rowPointer < $startRow + 3 ; $rowPointer ++ )
149 {
150 for ( $列ポインタ = $startColumn < $columnPointer ; )
151 {
152 if ( $array [ $rowPointer ][ $columnPointer ] == 0 )
153 {
154 if ( $this -> isPossibleInThatCellCheckByColumn( $array , $number , $rowPointer , $columnPointer ) && $これ -> isPossibleInThatCellCheckByRow( $array , $number , $rowPointer , $columnPointer ))
155 {
156 $rowPosition = $rowPointer ;
157 $columnPosition = $columnPointer ;
158 $可能性++ ;
159
160
161
162 }
163 if ( $posibilities == 1 )
164 {
165 $array [ $rowPosition ][ ] = $number ;
166 戻り値 true ;
167
168
169
170 return false ;
171 }
172 プライベート 関数 reduceFromOneRow( & $array , $row )
173 {
174 $unknown = array ();
175 for ( $column = 0 ; $column 176 {
177 $unknown [ $column ] = $column + 1 ;
178 }
179 for ( $column = 0 ; $column 180 {
181 if ( $array [ $row ][ ] != 0 )
182 {
183 $不明 [ $array [ $row ] [ $column ] - 1 ] = 0 ;
184
185 }
186 for ( $column = 0 ; $column 187 {
188 if ( $unknown [ $column ] != 0 )
189 {
190 $number = $unknown [ $column ];
191 $posibility = 0 ;
192 $position =- 1 ;
193 for ( $pointer = 0 ; $pointer 194 {
195 if ( $array [ $row ][ er ] == 0 )
196 {
197 if ( $this -> isPossibleInThatCellCheckByColumnAndZone( $array , $number , $row , $pointer ))
198 {
199 $position = $pointer ;
200 $可能性++ ;
201
202
203 if ( $posi能力 == 1 )
205 {
206 $array [ $row ][ $position ] = $number ;
207 true を返します。
208
209
210
211 return false ;
212 }
213 プライベート 関数 reduceFromOneColumn( & $array , $column )
214 {
215 $unknown = array ();
216 for ( $row = 0 ; $row 217 {
218 $unknown [ $row ] = $row + 1 ;
219 }
220 for ( $row = 0 ; $row 221 {
222 if ( $array [ $row ][ $column ] != 0 )
223 {
224 $不明 [ $array [ $row ] [ $column ] - 1 ] = 0 ;
225
226 }
227 for ( $row = 0 ; $row 228 {
229 if ( $unknown [ $row ] != 0 )
230 {
231 $number = $unknown [ $row ];
232 $posibility = 0 ;
233 $position =- 1 ;
234 for ( $pointer = 0 ; $pointer 235 {
236 if ( $pointer ][列] == 0 )
237 {
238 if ( $this - &gt; ispossible inthatcellcheckbyrowandzone($ array、$ number、$ pointer、$ column))
241 $可能性++ ;
242
243
244 if ( $posi能力 == 1 )
246 {
247 $array [ $position ][ $column ] = $number ;
248 戻り値 true ;
249 }
250
251
252 return false ;
253 }
254 プライベート 関数 isPossibleInThatCellCheckByRowAndZone( $array , $number , $row , $column )
255 {
256 if ( ! $this -> ByRow( $array , $number , $row , $column ))
257 {
258 戻り値 false ;
259 }
260 else if ( ! $this -> isPossibleInThatCellCheckByZone( $array , $number , $row , $column ))
261 {
262 return偽 ;
263 }
264 else if ( ! $this -> canBeInThatZoneCheckByColumn( $array , $number , $row , $column ))
265 {
266 return false ;
267 }
268 else
269 {
270 return true ;
271 }
272 }
273 プライベート 関数 isPossibleInThatCellCheckByColumnAndZone( $array , $number , $row , $column )
274 {
275 if ( ! $this -> isPossibleInThatCellCheckByColumn( $array , $number , $column ))
276 {
277 戻り値 false ;
278 }
279 else if ( ! $this -> isPossibleInThatCellCheckByZone( $array , $number , $row , $column ))
280 {
281戻り値 false ;
282 }
283 else if ( ! $this -> canBeInThatZoneCheckByRow( $array , $number , $row , $column ))
284 {
285 false を返します。
286 }
287 else
288 {
289 return true ;
290
291 }
292 プライベート 関数 canBeInThatZoneCheckByRow( $array , $number , $row , $column )
293 {
294 $start行 = (フロア ( $row / 3 )) * 3 ;
295 $startColumn = (floor ( $column / 3 )) * 3 ;
296 for ( $rowPointer = $startRow ; $rowPointer < $startRow + 3 ; $rowPointer ++ )
297 {
298 if ( $rowPointer != $row )
299 {
300 if ( ! $this -> ; isPossibleInThatCellCheckByRow( $array , $number , $rowPointer , $column ))
301 {
302 続行 ; 303
304 $canItBe = true ;
305 for ( $columnPointer = 0 ; $columnPointer < 9 ; $columnPointer ++ )
306 {
307 if ( $co lumnPointer < $startColumn || $startColumn + 2 )
308 {
309 if ( $array [ $rowPointer ][ $columnPointer ] == 0 )
310 {
311 if ( $this -> isPossibleInThatCellCheckByColumn( $array , $number , $rowPointer , $columnPointer ) && $this - > isPossibleInThatCellCheckByZone( $array , $number , $rowPointer , $columnPointer ))
312 {
313 $ canItBe = false ;
314
315
316
317 }
318 if ( $canItBe )
319 {
320 false を返す ;
321 }
322
323
324 戻り値 true ;
325 }
326 プライベート 関数 canBeInThatZoneCheckByColumn( $array , $number , $row , $column )
327 {
328 $startRow = ( Floor ( $row / 3 )) * 3 ;
329 $startColumn = (floor ( $column / 3 )) * 3 ;
330 for ( $columnPointer = $startColumn ; $columnPointer < $startColumn + 3 ; $columnPointer ++ )
331 {
332 if ( $columnPointer != $column )
333 {
334 if ( ! $this -> ; isPossibleInThatCellCheckByColumn( $array , $number , $row , $columnPointer ))
335 {
336 続行 ; 337
338 $canItBe = true ;
339 for ( $rowPointer = 0 ; $rowPointer < 9 ; $rowPointer ++ )
340 {
341 if ( $rowPointer < $ startRow || $rowPointer > $startRow + 2 )
342 {
343 if ( $array [ $rowPointer ][ $columnPointer ] == 0 )
344 {
if ( $this -> isPossibleInThatCellCheckByRow( $array , $number , $rowPointer , $columnPointer ) && $this -> isPossibleInThatCellCheckByZone ( $array 、 $number 、 $rowPointer 、 $columnPointer ))
346 {
347 $canItBe = false ;
348
349
350
351 }
352 if ( $canItBe )
353 {
354 false を返す ;
355
356
357
358 戻り値 true ;
359 }
360 プライベート関数 isPossibleInThatCellCheckByZone( $array , $number , $row , $column )
361 {
362 $startRow = ( Floor ( $row / 3 )) * 3 ;
363 $startColumn = (floor ( $column / 3 )) * 3 ;
364 for ( $rowPointer = $startRow ; $rowPointer < $startRow + 3 ; $rowPointer ++ )
365 {
366 for ( $columnPointer = $startColumn ; $columnPointer < $startColumn + 3 ; $columnPointer ++ )
367 {
368 if ( $array [ $rowPointer ][ $columnPointer ] == $number )
369 {
370 false を返します。
371 }
372
373
374 戻り値 true ;
375 }
376 プライベート 関数 reduceFromThreeColumns( & $array , $firstColumn , $lastColumn )
377 {
378 $numberAndCount = array ();
379 $numberAndPosition = 配列();
380 for ( $row = 0 ; $row < 9 ; $row ++ )
381 {
382 $numberAndCount [ $row ][ 0 ] = $row + 1 ;
383 $numberAndCount [ $row ][ 1 ] = 0 ;
384 }
385 for ( $row = 0 ; $row < 27 ; $row ++ )
386 {
387 for ( $column = 0 ; $column < 3 ; $column ++ )
388 {
389 $numberAndPosition [ $row ][ $column ] = 0 ;
390
391
392 for ( $column = $firstColumn ; $column <= $lastColumn ; $column ++ )
393 {
394 for ( $row = 0 ; $row < 9 ; $row + + )
395 {
396 if ( $array [ $row ][ $column ] != 0 )
397 {
398 $numberAndCount [ $array [ $row ][ $column ] - 1 ][ 1 ] ++ ;
399 $numberAndPosition [ 9 * ( $column % 3 ) + $row ][ 0 ] = $array [ $row ][ $column ];
400 $numberAndPosition [ 9 * ( $column % 3 ) + $row ][ 1 ] = $row ;
401 $numberAndPosition [ 9 * ( $column % 3 ) + $row ][ 2 ] = $column ;
402
403
404
405 for ( $row = 0 ; $row < 9 ; $row ++ )
406 {
407 if ( $numberAndCount [ $row ][ 1 ] == 2 )
408 {
409 $number = $numberAndCount [ $row ][ 0 ];
410 $pointer = 0 ;
411 $firstAppearanceRowPosition =- 1 ;
412 $firstAppearanceColumnPosition =- 1 ;
413 $secondAppearanceRowPosition =- 1 ;
414 $secondAppearanceColumnPosition =- 1 ;
415 while ( $pointer < 27 )
416 {
417 if ( $numberAndPosition [ $pointer ][ 0 ] == $number )
418 {
419 $firstAppearanceRowPosition = $numberAndPosition [ $pointer ][ 1 ];
420 $firstAppearanceColumnPosition = $numberAndPosition [ $pointer ][ 2 ];
421 $pointer ++ ;
422 休憩;
423
424 その他
425 {
426 $pointer ++ ;
427
428
429 while ( $pointer < 27 )
430 {
431 if ( $numberAndPosition [ $pointer ][ 0 ] == $number )
432 {
433 $sec earanceRowPosition = $numberAndPosition [ $pointer ][1];
434 $secondAppearanceColumnPosition = $numberAndPosition [ $pointer ][ 2 ];
435 休憩;
436
437 その他
438 {
439 $pointer ++ ;
440
441
442 $thirdAppearanceColumnPosition = 3 * (floor ( $firstAppearanceColumnPosition / 3 )) + 3 - anceColumnPosition %3 - $secondAppearanceColumnPosition %3 ;
443 $ thirdAppearanceRowStartPosition = ( 3 - ( フロア ( $firstAppearanceRowPosition / 3 )) - ( フロア ( $secondAppearanceRowPosition / 3 ))) * 3 ;
444 $posibility = 0 ;
445 $ thirdAppearanceRowPosition =- 1 ;
446 for ( $indicator = $thirdAppearanceRowStartPosition ; $indicator < $thirdAppearanceRowStartPosition + 3 ; $indicator ++ )
447 {
448 if ( $array [ $indicator ][ $thirdAppearanceColumnPosition ] == 0 )
449 {
450 if ( $this -> isPossibleInThatCellCheckByRow( $array , $number , $indicator , $thirdAppearanceColumnPosition ))
451 {
452 $thirdAppearanceRowPosition = $indicator ;
453 $可能性++ ;
454
455
456 if ( $posi能力 == 1 )
458 {
459 $array [ $ thirdAppearanceRowPosition ][ $ thirdAppearanceColumnPosition ] = $number ;
460 true を返します。
461
462
463
464 戻り値 false ;
465 }
466 プライベート function reduceFromThreeRows( & $array , $firstRow , $lastRow )
467 {
468 $numberAndCount = array ();
469 $numberAndPosition = 配列();
470 for ( $column = 0 ; $column 471 {
472 $numberAndCount [ 0 ][ $column ] = $column + 1 ;
473 $numberAndCount [ 1 ][ $column ] = 0 ;
474 }
475 for ( $row = 0 ; $row 476 {
477 for ( $column = 0 ; $column 478 {
479 $numberAndPosition [ $row ][ $column ] = 0 ;
480
481 }
482 for ( $row = $firstRow ; $row 483 {
484 for ( $column = 0 ; $column 485 {
486 if ( $array [ $row ][ $column ] != 0 )
487 {
488 $numberAndCount [ 1 ][ $array [ $row ][ $column ] - 1 ] ++ ;
489 $numberAndPosition [ 0 ][ 9 * ( $row % 3 ) + $column ] = $array [ $row ][ $column ];
490 $numberAndPosition [1][9 * ($row % 3 ) + $column ] = $row ;
491 $numberAndPosition [ 2 ][ 9 * ( $row % 3 ) + $column ] = $column ;
492
493
494
495 for ( $column = 0 ; $column 496 {
497 if ( $numberAndCount [ 1 ][ $column ] == 2 )
498 {
499 $number = $numberAndCount [ 0 ][ $column ];
500 $pointer = 0 ;
501 $firstAppearanceRowPosition =- 1 ;
502 $firstAppearanceColumnPosition =- 1 ;
503 $secondAppearanceRowPosition =- 1 ;
504 $secondAppearanceColumnPosition =- 1 ;
505 while ( $pointer < 27 )
506 {
507 if ( $numberAndPosition [ 0 ][ $pointer ] == $number )
508 {
509 $firstAppearanceRowPosition = $numberAndPosition [ 1 ][ $pointer ];
510 $firstAppearanceColumnPosition = $numberAndPosition [ 2 ][ $pointer ];
511 $pointer ++ ;
512 休憩 ;
513
514 その他
515 {
516 $pointer ++ ;
517
518
519 while ( $pointer < 27 )
520 {
521 if ( $numberAndPosition [ 0 ][ $pointer ] == $number )
522 {
523 $secondApp earanceRowPosition = $numberAndPosition [ 1 ] [ $pointer ];
524 $secondAppearanceColumnPosition = $numberAndPosition [ 2 ][ $pointer ];
525 休憩;
526
527 その他
528 {
529 $pointer ++ ;
530
531
532 $thirdAppearanceRowPosition = 3 * (floor ( $firstAppearanceRowPosition / 3 )) + 3 -外観行位置 %3 - $秒外観行位置 %3 ;
533 $ thirdAppearanceColumnStartPosition = ( 3 - ( フロア ( $firstAppearanceColumnPosition / 3 )) - ( フロア ( $secondAppearanceColumnPosition / 3 ))) * 3 ;
534