Skip to content

Instantly share code, notes, and snippets.

@espio999
Created September 11, 2021 23:59
Show Gist options
  • Save espio999/043209cab91ce377e24b0d88bae127e6 to your computer and use it in GitHub Desktop.
Save espio999/043209cab91ce377e24b0d88bae127e6 to your computer and use it in GitHub Desktop.
42 SILICON VALLEY Piscine 2017 Rush01 - sudoku1
def make_puzzle(args):
puzzle = []
row = []
i = 0
for c in args:
row.append(c)
if (i + 1) % 9 == 0:
puzzle.append(row)
row = []
i += 1
return puzzle
def make_workbd():
digits = '123456789'
workbd = []
row = []
c = 0
r = 0
while r < 9:
while c < 9:
row.append(digits)
if (c + 1) % 9 == 0:
workbd.append(row)
row = []
c = 0
r += 1
break
else:
c += 1
return workbd
def print_workbd(isGrid):
r = 0
c = 0
buf = ''
while r < 9:
while c < 9:
buf += my_workbd[r][c]
if isGrid == True and (c == 2 or c == 5):
buf += '|'
c += 1
buf += '\n'
if isGrid == True and (r == 2 or r == 5):
buf += '---+---+---\n'
c = 0
r += 1
print(buf)
def update_workbd(r, c, d, isRD):
try_num = my_workbd[r][c]
buf = ''
for i in try_num:
if i == d:
continue
buf += i
if isRD == False:
my_workbd[r][c] = buf
return buf
def search_number(num, val):
for i in val:
if i == num:
return True
return False
def get_box_range(val):
if 0 <= val and val <= 2:
return 0
elif 3 <= val and val <= 5:
return 3
elif 6 <= val and val <= 8:
return 6
def get_pos(r, c, isPeer):
pos = []
row = []
col = []
box = []
sr = get_box_range(r)
sc = get_box_range(c)
#row
i = 0
while i < 9:
if isPeer == True and (i == sc or i == sc + 1 or i == sc + 2):
i += 1
continue
pos.append(r)
pos.append(i)
row.append(pos)
pos = []
i += 1
#column
i = 0
while i < 9:
if isPeer == True and (i == sr or i == sr + 1 or i == sr + 2):
i += 1
continue
pos.append(i)
pos.append(c)
col.append(pos)
pos = []
i += 1
#box
x = sc
y = sr
while y < sr + 3:
while x < sc + 3:
if isPeer == True and x == c and y == r:
x += 1
continue
pos.append(y)
pos.append(x)
box.append(pos)
pos = []
x += 1
x = sc
y += 1
return row + col + box
def check_peer(r, c, d):
for peer_pos in get_pos(r, c, True):
if eliminate(peer_pos[0], peer_pos[1], d) == False:
return False
return True
def check_unit(r, c, d):
psbl_pos = []
for unit_pos in get_pos(r, c, False):
y = unit_pos[0]
x = unit_pos[1]
if search_number(d, my_workbd[y][x]) == True:
psbl_pos.append(unit_pos)
l = len(psbl_pos)
if l == 0:
return False
elif l == 1:
y = psbl_pos[0][0]
x = psbl_pos[0][1]
if assign(y, x, d) == False:
return False
return True
def eliminate(r, c, d):
cell = my_workbd[r][c]
if search_number(d, cell) == False:
return True
cell = update_workbd(r, c, d, False)
l = len(cell)
if l == 0:
return False
elif l == 1:
if check_peer(r, c, cell) == False:
return False
if check_unit(r, c, d) == False:
return False
return True
def assign(r, c, d):
psbl_num = update_workbd(r, c, d, True)
for try_num in psbl_num:
if eliminate(r, c, try_num) == False:
return False
return True
#42SV Piscine 2017 sample
args = "9...7...." "2...9..53" ".6..124.." "84...1.9." "5.....8.." ".31..4..." "..37..68." ".9..5.741" "47......."
#easy
#args = '..3.2.6..' '9..3.5..1' '..18.64..' '..81.29..' '7.......8' '..67.82..' '..26.95..' '8..2.3..9' '..5.1.3..'
#hard
#args = '4.....8.5' '.3.......' '...7.....' '.2.....6.' '....8.4..' '....1....' '...6.3.7.' '5..2.....' '1.4......'
my_puzzle = make_puzzle(args)
my_workbd = make_workbd()
r = 0
c = 0
while r < 9:
while c < 9:
d = my_puzzle[r][c]
if d != '.':
assign(r, c, d)
c += 1
c = 0
r += 1
print_workbd(True)
print_workbd(False)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment