September Morn Update

This commit is contained in:
Ingy döt Net 2019-09-12 10:33:56 -07:00
parent 4e2d22a71d
commit aac6731f2c
6856 changed files with 141342 additions and 21127 deletions

View file

@ -0,0 +1,75 @@
{.this: self.}
type
Sudoku = ref object
grid : array[81, int]
solved : bool
proc `$`(self: Sudoku): string =
var sb: string = ""
for i in 0..8:
for j in 0..8:
sb &= $grid[i * 9 + j]
sb &= " "
if j == 2 or j == 5:
sb &= "| "
sb &= "\n"
if i == 2 or i == 5:
sb &= "------+------+------\n"
sb
proc init(self: Sudoku, rows: array[9, string]) =
for i in 0..8:
for j in 0..8:
grid[9 * i + j] = rows[i][j].int - '0'.int
proc checkValidity(self: Sudoku, v, x, y: int): bool =
for i in 0..8:
if grid[y * 9 + i] == v or grid[i * 9 + x] == v:
return false
var startX = (x div 3) * 3
var startY = (y div 3) * 3
for i in startY..startY + 2:
for j in startX..startX + 2:
if grid[i * 9 + j] == v:
return false
result = true
proc placeNumber(self: Sudoku, pos: int) =
if solved:
return
if pos == 81:
solved = true
return
if grid[pos] > 0:
placeNumber(pos + 1)
return
for n in 1..9:
if checkValidity(n, pos mod 9, pos div 9):
grid[pos] = n
placeNumber(pos + 1)
if solved:
return
grid[pos] = 0
proc solve(self: Sudoku) =
echo "Starting grid:\n\n", $self
placeNumber(0)
if solved:
echo "Solution:\n\n", $self
else:
echo "Unsolvable!"
var rows = ["850002400",
"720000009",
"004000000",
"000107002",
"305000900",
"040000000",
"000080070",
"017000000",
"000036040"]
var puzzle = Sudoku()
puzzle.init(rows)
puzzle.solve()

View file

@ -0,0 +1,64 @@
type Sudoku = [u8; 81];
fn is_valid(val: u8, x: usize, y: usize, sudoku_ar: &mut Sudoku) -> bool {
(0..9).all(|i| sudoku_ar[y * 9 + i] != val && sudoku_ar[i * 9 + x] != val) && {
let (start_x, start_y) = ((x / 3) * 3, (y / 3) * 3);
(start_y..start_y + 3).all(|i| (start_x..start_x + 3).all(|j| sudoku_ar[i * 9 + j] != val))
}
}
fn place_number(pos: usize, sudoku_ar: &mut Sudoku) -> bool {
(pos..81).find(|&p| sudoku_ar[p] == 0).map_or(true, |pos| {
let (x, y) = (pos % 9, pos / 9);
for n in 1..10 {
if is_valid(n, x, y, sudoku_ar) {
sudoku_ar[pos] = n;
if place_number(pos + 1, sudoku_ar) {
return true;
}
sudoku_ar[pos] = 0;
}
}
false
})
}
fn pretty_print(sudoku_ar: Sudoku) {
let line_sep = "------+-------+------";
println!("{}", line_sep);
for (i, e) in sudoku_ar.iter().enumerate() {
print!("{} ", e);
if (i + 1) % 3 == 0 && (i + 1) % 9 != 0 {
print!("| ");
}
if (i + 1) % 9 == 0 {
println!(" ");
}
if (i + 1) % 27 == 0 {
println!("{}", line_sep);
}
}
}
fn solve(sudoku_ar: &mut Sudoku) -> bool {
place_number(0, sudoku_ar)
}
fn main() {
let mut sudoku_ar: Sudoku = [
8, 5, 0, 0, 0, 2, 4, 0, 0,
7, 2, 0, 0, 0, 0, 0, 0, 9,
0, 0, 4, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1, 0, 7, 0, 0, 2,
3, 0, 5, 0, 0, 0, 9, 0, 0,
0, 4, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 8, 0, 0, 7, 0,
0, 1, 7, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 3, 6, 0, 4, 0
];
if solve(&mut sudoku_ar) {
pretty_print(sudoku_ar);
} else {
println!("Unsolvable");
}
}

View file

@ -0,0 +1,29 @@
with
symbols (d) as (select to_char(level) from dual connect by level <= 9)
, board (i) as (select level from dual connect by level <= 81)
, neighbors (i, j) as (
select b1.i, b2.i
from board b1 inner join board b2
on b1.i != b2.i
and (
mod(b1.i - b2.i, 9) = 0
or ceil(b1.i / 9) = ceil(b2.i / 9)
or ceil(b1.i / 27) = ceil(b2.i / 27) and trunc(mod(b1.i - 1, 9) / 3) = trunc(mod(b2.i - 1, 9) / 3)
)
)
, r (str, pos) as (
select :game, instr(:game, ' ')
from dual
union all
select substr(r.str, 1, r.pos - 1) || s.d || substr(r.str, r.pos + 1), instr(r.str, ' ', r.pos + 1)
from r inner join symbols s
on r.pos > 0 and not exists (
select *
from neighbors n
where r.pos = n.i and s.d = substr(r.str, n.j, 1)
)
)
select str
from r
where pos = 0
;