js/src/tests/js1_8/genexps/regress-380237-01.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6
michael@0 7 //-----------------------------------------------------------------------------
michael@0 8 var BUGNUMBER = 380237;
michael@0 9 var summary = 'Generator expressions - sudoku';
michael@0 10 var actual = '';
michael@0 11 var expect = '';
michael@0 12
michael@0 13
michael@0 14 //-----------------------------------------------------------------------------
michael@0 15 test();
michael@0 16 //-----------------------------------------------------------------------------
michael@0 17
michael@0 18 function test()
michael@0 19 {
michael@0 20 enterFunc ('test');
michael@0 21 printBugNumber(BUGNUMBER);
michael@0 22 printStatus (summary);
michael@0 23
michael@0 24 if (this.version) version(180);
michael@0 25
michael@0 26 // XXX should be standard (and named clone, after Java?)
michael@0 27 Object.prototype.copy = function () {
michael@0 28 let o = {}
michael@0 29 for (let i in this)
michael@0 30 o[i] = this[i]
michael@0 31 return o
michael@0 32 }
michael@0 33
michael@0 34 // Make arrays and strings act more like Python lists by iterating their values, not their keys.
michael@0 35 Array.prototype.__iterator__ = String.prototype.__iterator__ = function () {
michael@0 36 for (let i = 0; i < this.length; i++)
michael@0 37 yield this[i]
michael@0 38 }
michael@0 39
michael@0 40 // Containment testing for arrays and strings that should be coherent with their __iterator__.
michael@0 41 Array.prototype.contains = String.prototype.contains = function (e) {
michael@0 42 return this.indexOf(e) != -1
michael@0 43 }
michael@0 44
michael@0 45 Array.prototype.repeat = String.prototype.repeat = function (n) {
michael@0 46 let s = this.constructor()
michael@0 47 for (let i = 0; i < n; i++)
michael@0 48 s = s.concat(this)
michael@0 49 return s
michael@0 50 }
michael@0 51
michael@0 52 String.prototype.center = function (w) {
michael@0 53 let n = this.length
michael@0 54 if (w <= n)
michael@0 55 return this
michael@0 56 let m = Math.floor((w - n) / 2)
michael@0 57 return ' '.repeat(m) + this + ' '.repeat(w - n - m)
michael@0 58 }
michael@0 59
michael@0 60 Array.prototype.toString = Array.prototype.toSource
michael@0 61 Object.prototype.toString = Object.prototype.toSource
michael@0 62
michael@0 63 // XXX thought spurred by the next two functions: array extras should default to identity function
michael@0 64
michael@0 65 function all(seq) {
michael@0 66 for (let e in seq)
michael@0 67 if (!e)
michael@0 68 return false
michael@0 69 return true
michael@0 70 }
michael@0 71
michael@0 72 function some(seq) {
michael@0 73 for (let e in seq)
michael@0 74 if (e)
michael@0 75 return e
michael@0 76 return false
michael@0 77 }
michael@0 78
michael@0 79 function cross(A, B) {
michael@0 80 return [a+b for (a in A) for (b in B)]
michael@0 81 }
michael@0 82
michael@0 83 function dict(A) {
michael@0 84 let d = {}
michael@0 85 for (let e in A)
michael@0 86 d[e[0]] = e[1]
michael@0 87 return d
michael@0 88 }
michael@0 89
michael@0 90 function set(A) {
michael@0 91 let s = []
michael@0 92 for (let e in A)
michael@0 93 if (!s.contains(e))
michael@0 94 s.push(e)
michael@0 95 return s
michael@0 96 }
michael@0 97
michael@0 98 function zip(A, B) {
michael@0 99 let z = []
michael@0 100 let n = Math.min(A.length, B.length)
michael@0 101 for (let i = 0; i < n; i++)
michael@0 102 z.push([A[i], B[i]])
michael@0 103 return z
michael@0 104 }
michael@0 105
michael@0 106 rows = 'ABCDEFGHI'
michael@0 107 cols = '123456789'
michael@0 108 digits = '123456789'
michael@0 109 squares = cross(rows, cols)
michael@0 110 unitlist = [cross(rows, c) for (c in cols)]
michael@0 111 .concat([cross(r, cols) for (r in rows)])
michael@0 112 .concat([cross(rs, cs) for (rs in ['ABC','DEF','GHI']) for (cs in ['123','456','789'])])
michael@0 113 units = dict([s, [u for (u in unitlist) if (u.contains(s))]]
michael@0 114 for (s in squares))
michael@0 115 peers = dict([s, set([s2 for (u in units[s]) for (s2 in u) if (s2 != s)])]
michael@0 116 for (s in squares))
michael@0 117
michael@0 118 // Given a string of 81 digits (or . or 0 or -), return a dict of {cell:values}.
michael@0 119 function parse_grid(grid) {
michael@0 120 grid = [c for (c in grid) if ('0.-123456789'.contains(c))]
michael@0 121 let values = dict([s, digits] for (s in squares))
michael@0 122
michael@0 123 for (let [s, d] in zip(squares, grid))
michael@0 124 if (digits.contains(d) && !assign(values, s, d))
michael@0 125 return false
michael@0 126 return values
michael@0 127 }
michael@0 128
michael@0 129 // Eliminate all the other values (except d) from values[s] and propagate.
michael@0 130 function assign(values, s, d) {
michael@0 131 if (all(eliminate(values, s, d2) for (d2 in values[s]) if (d2 != d)))
michael@0 132 return values
michael@0 133 return false
michael@0 134 }
michael@0 135
michael@0 136 // Eliminate d from values[s]; propagate when values or places <= 2.
michael@0 137 function eliminate(values, s, d) {
michael@0 138 if (!values[s].contains(d))
michael@0 139 return values // Already eliminated
michael@0 140 values[s] = values[s].replace(d, '')
michael@0 141 if (values[s].length == 0)
michael@0 142 return false // Contradiction: removed last value
michael@0 143 if (values[s].length == 1) {
michael@0 144 // If there is only one value (d2) left in square, remove it from peers
michael@0 145 let d2 = values[s][0]
michael@0 146 if (!all(eliminate(values, s2, d2) for (s2 in peers[s])))
michael@0 147 return false
michael@0 148 }
michael@0 149 // Now check the places where d appears in the units of s
michael@0 150 for (let u in units[s]) {
michael@0 151 let dplaces = [s for (s in u) if (values[s].contains(d))]
michael@0 152 if (dplaces.length == 0)
michael@0 153 return false
michael@0 154 if (dplaces.length == 1)
michael@0 155 // d can only be in one place in unit; assign it there
michael@0 156 if (!assign(values, dplaces[0], d))
michael@0 157 return false
michael@0 158 }
michael@0 159 return values
michael@0 160 }
michael@0 161
michael@0 162 // Used for debugging.
michael@0 163 function print_board(values) {
michael@0 164 let width = 1 + Math.max.apply(Math, [values[s].length for (s in squares)])
michael@0 165 let line = '\n' + ['-'.repeat(width*3)].repeat(3).join('+')
michael@0 166 for (let r in rows)
michael@0 167 print([values[r+c].center(width) + ('36'.contains(c) && '|' || '')
michael@0 168 for (c in cols)].join('') + ('CF'.contains(r) && line || ''))
michael@0 169 print('\n')
michael@0 170 }
michael@0 171
michael@0 172 easy = "..3.2.6..9..3.5..1..18.64....81.29..7.......8..67.82....26.95..8..2.3..9..5.1.3.."
michael@0 173
michael@0 174 print_board(parse_grid(easy))
michael@0 175
michael@0 176 // Using depth-first search and constraint propagation, try all possible values.
michael@0 177 function search(values) {
michael@0 178 if (!values)
michael@0 179 return false // Failed earlier
michael@0 180 if (all(values[s].length == 1 for (s in squares)))
michael@0 181 return values // Solved!
michael@0 182
michael@0 183 // Choose the unfilled square s with the fewest possibilities
michael@0 184 // XXX Math.min etc. should work with generator expressions and other iterators
michael@0 185 // XXX Math.min etc. should work on arrays (lists or tuples in Python) as well as numbers
michael@0 186 let a = [values[s].length + s for (s in squares) if (values[s].length > 1)].sort()
michael@0 187 let s = a[0].slice(-2)
michael@0 188
michael@0 189 return some(search(assign(values.copy(), s, d)) for (d in values[s]))
michael@0 190 }
michael@0 191
michael@0 192 hard = '4.....8.5.3..........7......2.....6.....8.4......1.......6.3.7.5..2.....1.4......'
michael@0 193
michael@0 194 print_board(search(parse_grid(hard)))
michael@0 195
michael@0 196 delete Object.prototype.copy;
michael@0 197
michael@0 198 reportCompare(expect, actual, summary);
michael@0 199
michael@0 200 exitFunc ('test');
michael@0 201 }

mercurial