main.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. import os, sys, copy
  2. from attr import field
  3. task_dir = os.path.dirname(__file__)
  4. sys.path.append(f'{task_dir}/..')
  5. import numpy as np
  6. from get_tasks import get_input, generate_readme, check_example, bench
  7. def can_move_any(field, hight, width, count):
  8. bools = []
  9. cucumbers = []
  10. for x in range(hight-1):
  11. for y in range(width-1):
  12. if field[x][y]=='>' and field[x][y+1] == '.':
  13. bools.append(True)
  14. cucumbers.append([1, x, y])
  15. if field[x][y]=='>' and field[x][y+1] != '.':
  16. bools.append(False)
  17. if field[x][y]=='v' and field[x+1][y] == '.':
  18. bools.append(True)
  19. cucumbers.append([2, x, y])
  20. if field[x][y]=='v' and field[x+1][y] != '.':
  21. bools.append(False)
  22. if (y == width-2) and (field[x][y+1] == '>') and (field[x][0] == '.'):
  23. bools.append(True)
  24. cucumbers.append([3, x, y+1])
  25. if (y == width-2) and (field[x][y+1] == '>') and (field[x][0] != '.'):
  26. bools.append(False)
  27. if (y == width-2) and (field[x][y+1] == 'v') and (field[x+1][y+1] == '.'):
  28. bools.append(True)
  29. cucumbers.append([2, x, y+1])
  30. if (y == width-2) and (field[x][y+1] == 'v') and (field[x+1][y+1] != '.'):
  31. bools.append(False)
  32. if (x == hight-2) and (field[x+1][y] == 'v') and (field[0][y] == '.'):
  33. bools.append(True)
  34. cucumbers.append([4, x+1, y])
  35. if (x == hight-2) and (field[x+1][y] == 'v') and (field[0][y] != '.'):
  36. bools.append(False)
  37. if (x == hight-2) and (field[x+1][y] == '>') and (field[x+1][y+1] == '.'):
  38. bools.append(True)
  39. cucumbers.append([1, x+1, y])
  40. if (x == hight-2) and (field[x+1][y] == '>') and (field[x+1][y+1] != '.'):
  41. bools.append(False)
  42. if field[hight-1][width-1]=='>' and field[hight-1][0]=='.':
  43. bools.append(True)
  44. cucumbers.append([3, hight-1, width-1])
  45. if field[hight-1][width-1]=='>' and field[hight-1][0]!='.':
  46. bools.append(False)
  47. if field[hight-1][width-1]=='v' and field[0][width-1]=='.':
  48. bools.append(True)
  49. cucumbers.append([4, hight-1, width-1])
  50. if field[hight-1][width-1]=='v' and field[0][width-1]!='.':
  51. bools.append(False)
  52. if len(bools) != count: raise Exception('count != bools!', len(bools))
  53. return cucumbers
  54. def moving(orig_field, step=None):
  55. copy_field = copy.deepcopy(orig_field)
  56. hight, width = len(copy_field), len(copy_field[0])
  57. count = 0
  58. for x in range(hight):
  59. for y in range(width):
  60. if copy_field[x][y] != '.': count+=1
  61. steps = 0
  62. move = True
  63. while move:
  64. steps+=1
  65. for herd in ['east', 'north']:
  66. cucumbers = can_move_any(copy_field, hight, width, count)
  67. if len(cucumbers) < 1: move = False
  68. for cucumber in cucumbers:
  69. if herd == 'east':
  70. match cucumber:
  71. case [1, x, y]: copy_field[x][y] = '.'; copy_field[x][y+1]='>'
  72. case [3, x, y]: copy_field[x][y] = '.'; copy_field[x][0]='>'
  73. else:
  74. match cucumber:
  75. case [2, x, y]: copy_field[x][y] = '.'; copy_field[x+1][y]='v'
  76. case [4, x, y]: copy_field[x][y]='.'; copy_field[0][y]='v'
  77. if step and steps == step:
  78. break
  79. return copy_field, steps, ["".join(line) for line in copy_field]
  80. def check_move(arr):
  81. right = np.where(arr == '>')
  82. down = np.where(arr == 'v')
  83. h, w = arr.shape
  84. can_move = []
  85. for x, y in zip(right[0], right[1]):
  86. if y == w-1:
  87. if arr[x, 0] == '.': can_move.append([3, x, y])
  88. else:
  89. if arr[x, y+1] == '.': can_move.append([1, x, y])
  90. for x, y in zip(down[0], down[1]):
  91. if x == h-1:
  92. if arr[0, y] == '.': can_move.append([4, x, y])
  93. else:
  94. if arr[x+1, y] == '.': can_move.append([2, x, y])
  95. return can_move, True if can_move else False
  96. def array_like(input):
  97. arr = np.array([list(line) for line in input])
  98. np.count_nonzero(arr!='.')
  99. steps = 0
  100. move = True
  101. while move:
  102. steps+=1
  103. for herd in ['east', 'north']:
  104. cucumbers, move = check_move(arr)
  105. if len(cucumbers) < 1: move = False; break
  106. for cucumber in cucumbers:
  107. if herd == 'east':
  108. match cucumber:
  109. case [1, x, y]: arr[x][y] = '.'; arr[x][y+1]='>'
  110. case [3, x, y]: arr[x][y] = '.'; arr[x][0]='>'
  111. else:
  112. match cucumber:
  113. case [2, x, y]: arr[x][y] = '.'; arr[x+1][y]='v'
  114. case [4, x, y]: arr[x][y]='.'; arr[0][y]='v'
  115. return arr, steps, ["".join(line) for line in arr]
  116. @bench
  117. def part1(input):
  118. field = [list(line) for line in input]
  119. _, steps, _ = array_like(field)
  120. print('The asnwer of part1 is:', steps+1)
  121. if __name__ == '__main__':
  122. input, example = get_input(task_dir, 25)
  123. check_example(example, part1)
  124. part1(input)
  125. generate_readme(task_dir, 25)