neighbors_sum_grids.py 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. '''
  2. @author: olivier.massot, 2019
  3. '''
  4. import itertools
  5. import sys
  6. import time
  7. def log(*msg):
  8. print(*msg, file=sys.stderr)
  9. t0 = time.time()
  10. # matrix = [[int(j) for j in input().split()] for _ in range(5)]
  11. matrix = [[21, 14, 10, 0, 0], [0, 4, 1, 6, 0], [0, 3, 5, 11, 13], [15, 0, 0, 0, 0], [23, 24, 0, 20, 25]]
  12. # matrix = [[19, 15, 11, 0, 23], [0, 0, 0, 0, 13], [0, 0, 1, 0, 22], [0, 0, 0, 0, 16], [14, 12, 21, 0, 25]]
  13. # matrix = [[23, 22, 8, 0, 18], [0, 0, 0, 5, 0], [0, 0, 12, 0, 0], [0, 10, 0, 11, 9], [0, 0, 0, 0, 0]]
  14. # matrix = [[0, 12, 0, 0, 0], [0, 0, 17, 0, 7], [0, 4, 3, 0, 18], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
  15. log(matrix)
  16. grid = {(x, y): v for y, row in enumerate(matrix) for x, v in enumerate(row)}
  17. crd = [(x, y) for x in range(5) for y in range(5)]
  18. ocrd = sorted(crd, key=lambda c: c[0] + c[1])
  19. def get(grid, x, y):
  20. if x < 0 or y < 0:
  21. raise IndexError
  22. return grid[y][x]
  23. def get_neighbors(x, y, d=5):
  24. return [(x+dx, y+dy) for dx in range(-1, 2) for dy in range(-1,2) \
  25. if (dx or dy) and 0 <= x + dx < d and 0 <= y + dy < d ]
  26. neighbors = {c: get_neighbors(*c) for c in crd}
  27. log("\n".join([" ".join([str(j).rjust(2) for j in row]) for row in matrix]))
  28. def validate(grid, unused, start):
  29. x0, y0 = start
  30. scan = [(x, y) for x in range(x0 - 1, x0 + 2) for y in range(y0 - 1, y0 + 2) if (x, y) in grid]
  31. for c in scan:
  32. v = grid[c]
  33. if v <= 2:
  34. continue
  35. neighs = [grid.get(n) for n in get_neighbors(*c, d=len(grid))]
  36. neighs = [x for x in neighs if x is not None]
  37. if 0 in neighs:
  38. return True
  39. if not any(n1 + n2 == v for n1, n2 in itertools.combinations(neighs, 2)):
  40. return False
  41. return True
  42. def test_candidates(grid):
  43. try:
  44. x, y = next(c for c, v in grid.items() if v == 0)
  45. except StopIteration:
  46. return grid
  47. unused = [j for j in range(25,0,-1) if not j in grid.values()]
  48. for j in unused:
  49. new_grid = dict(grid)
  50. new_grid[(x, y)] = j
  51. valid = validate(new_grid, unused, (x, y))
  52. if valid:
  53. r = test_candidates(new_grid)
  54. if r:
  55. return r
  56. dim = 5
  57. new_grid = {c: v for c, v in grid.items() if c[0] in range(dim) and c[1] in range(dim)}
  58. print(new_grid)
  59. r = test_candidates(new_grid)
  60. print(r)
  61. m = [[r[(x, y)] for x in range(dim)] for y in range(dim)]
  62. log("\n".join([" ".join([str(j).rjust(2) for j in row]) for row in m]))
  63. log(time.time() - t0)
  64. for row in m:
  65. print(" ".join(map(str, row)))