(function() {
  var COLS, DIGITS, ROWS, assign, c, copy, cross, cs, display, eliminate, grid_values, nine_squares, ns, parse_grid, peers, puzzle, r, rs, s, search, squares, u, uniq_and_remove, unitlist, units, _i, _j, _k, _l, _len, _len2, _len3, _len4, _len5, _len6, _m, _n, _ref, _ref2;
  var __hasProp = Object.prototype.hasOwnProperty, __indexOf = Array.prototype.indexOf || function(item) {
    for (var i = 0, l = this.length; i < l; i++) {
      if (this[i] === item) return i;
    }
    return -1;
  };
  ROWS = "ABCDEFGHI";
  COLS = "123456789";
  DIGITS = COLS;
  cross = function(A, B) {
    var a, b, results, _i, _j, _len, _len2;
    results = [];
    for (_i = 0, _len = A.length; _i < _len; _i++) {
      a = A[_i];
      for (_j = 0, _len2 = B.length; _j < _len2; _j++) {
        b = B[_j];
        results.push(a + b);
      }
    }
    return results;
  };
  copy = function(obj) {
    var cl, k, v;
    cl = {};
    for (k in obj) {
      if (!__hasProp.call(obj, k)) continue;
      v = obj[k];
      cl[k] = v;
    }
    return cl;
  };
  uniq_and_remove = function(duparr, ele) {
    var arr, hash, key, sq, value, _i, _len;
    hash = {};
    for (_i = 0, _len = duparr.length; _i < _len; _i++) {
      sq = duparr[_i];
      hash[sq] = 0;
    }
    arr = [];
    for (key in hash) {
      if (!__hasProp.call(hash, key)) continue;
      value = hash[key];
      if (key !== ele) {
        arr.push(key);
      }
    }
    return arr;
  };
  squares = cross(ROWS, COLS);
  nine_squares = [];
  _ref = ['ABC', 'DEF', 'GHI'];
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
    rs = _ref[_i];
    _ref2 = ['123', '456', '789'];
    for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) {
      cs = _ref2[_j];
      nine_squares.push(cross(rs, cs));
    }
  }
  unitlist = ((function() {
    var _i, _len, _results;
    _results = [];
    for (_i = 0, _len = COLS.length; _i < _len; _i++) {
      c = COLS[_i];
      _results.push(cross(ROWS, c));
    }
    return _results;
  })()).concat((function() {
    var _i, _len, _results;
    _results = [];
    for (_i = 0, _len = ROWS.length; _i < _len; _i++) {
      r = ROWS[_i];
      _results.push(cross(r, COLS));
    }
    return _results;
  })()).concat(nine_squares);
  units = {};
  for (_k = 0, _len3 = squares.length; _k < _len3; _k++) {
    s = squares[_k];
    units[s] = [];
    for (_l = 0, _len4 = unitlist.length; _l < _len4; _l++) {
      u = unitlist[_l];
      if (__indexOf.call(u, s) >= 0) {
        units[s].push(u);
      }
    }
  }
  peers = {};
  for (_m = 0, _len5 = squares.length; _m < _len5; _m++) {
    s = squares[_m];
    peers[s] = [];
    peers[s] = peers[s].concat(cross(ROWS, s[1])).concat(cross(s[0], COLS));
    for (_n = 0, _len6 = nine_squares.length; _n < _len6; _n++) {
      ns = nine_squares[_n];
      if (__indexOf.call(ns, s) >= 0) {
        peers[s] = peers[s].concat(ns);
      }
    }
    peers[s] = uniq_and_remove(peers[s], s);
  }
  parse_grid = function(grid) {
    var d, s, values, _i, _len, _ref;
    values = {};
    for (_i = 0, _len = squares.length; _i < _len; _i++) {
      s = squares[_i];
      values[s] = DIGITS;
    }
    _ref = grid_values(grid);
    for (s in _ref) {
      if (!__hasProp.call(_ref, s)) continue;
      d = _ref[s];
      if (__indexOf.call(DIGITS, d) >= 0 && !assign(values, s, d)) {
        return False;
      }
    }
    return values;
  };
  grid_values = function(sgrid) {
    var grid, i, _ref, _ref2;
    grid = {};
    for (i = 0, _ref = sgrid.length; (0 <= _ref ? i < _ref : i > _ref); (0 <= _ref ? i += 1 : i -= 1)) {
      grid[squares[i]] = (_ref2 = sgrid[i], __indexOf.call(DIGITS, _ref2) >= 0) ? sgrid[i] : ".";
    }
    return grid;
  };
  assign = function(values, s, d) {
    var d2, other_values, _i, _len;
    other_values = values[s].replace(d, '');
    for (_i = 0, _len = other_values.length; _i < _len; _i++) {
      d2 = other_values[_i];
      if (!eliminate(values, s, d2)) {
        return false;
      }
    }
    return values;
  };
  eliminate = function(values, s, d) {
    var d2, dplaces, s, s2, u, _i, _j, _len, _len2, _ref;
    if (!(values[s].indexOf(d) >= 0)) {
      return values;
    }
    values[s] = values[s].replace(d, '');
    if (values[s].length === 0) {
      return false;
    } else if (values[s].length === 1) {
      d2 = values[s];
      _ref = peers[s];
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        s2 = _ref[_i];
        if (!eliminate(values, s2, d2)) {
          return false;
        }
      }
    }
    for (_j = 0, _len2 = units.length; _j < _len2; _j++) {
      u = units[_j];
      dplaces = (function() {
        var _i, _len, _results;
        _results = [];
        for (_i = 0, _len = u.length; _i < _len; _i++) {
          s = u[_i];
          if (__indexOf.call(values[s], d) >= 0) {
            _results.push(s);
          }
        }
        return _results;
      })();
      if (dplaces.length === 0) {
        return values;
      }
      if (dplaces.length === 1) {
        if (!assign(values, dplaces[0], d)) {
          return false;
        }
      }
    }
    return values;
  };
  display = function(values) {
    var c, line, r, row, _i, _j, _len, _len2;
    console.log("    " + COLS.replace(/(.)/g, "$1 "));
    line = "  |------+-----+-----|";
    console.log(line);
    for (_i = 0, _len = ROWS.length; _i < _len; _i++) {
      r = ROWS[_i];
      if (__indexOf.call("DG", r) >= 0) {
        console.log(line);
      }
      row = r + " | ";
      for (_j = 0, _len2 = COLS.length; _j < _len2; _j++) {
        c = COLS[_j];
        row = row.concat(values[r + c]);
        row = row.concat(__indexOf.call("369", c) >= 0 ? "|" : " ");
      }
      console.log(row);
    }
    return console.log(line);
  };
  search = function(values) {
    var d, key, max, min, sq, value, _i, _len, _ref;
    if (!values) {
      return false;
    }
    min = {
      pos: -1,
      length: 10
    };
    max = {
      pos: -1,
      length: 1
    };
    for (key in values) {
      if (!__hasProp.call(values, key)) continue;
      value = values[key];
      if (value.length > max.length) {
        max.length = value.length;
        max.pos = key;
      }
    }
    if (max.length === 1) {
      return values;
    }
    for (key in values) {
      if (!__hasProp.call(values, key)) continue;
      value = values[key];
      if (value.length < min.length && value.length > 1) {
        min.length = value.length;
        min.pos = key;
      }
    }
    sq = squares[min.pos];
    _ref = values[sq];
    for (_i = 0, _len = _ref.length; _i < _len; _i++) {
      d = _ref[_i];
      if (!search(assign(copy(values), sq, values[sq][d]))) {
        return true;
      }
    }
    return false;
  };
  puzzle = '003020600900305001001806400008102900700000008006708200002609500800203009005010300';
  display(search(parse_grid(puzzle)));
}).call(this);