Let's see how far I get this year.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

пре 11 месеци
пре 11 месеци
пре 11 месеци
пре 11 месеци
пре 11 месеци
пре 11 месеци
пре 11 месеци
пре 11 месеци
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. from helpers import Helper
  2. helper = Helper(debug=True)
  3. debug = helper.debug
  4. load_input = helper.load_input
  5. class InputNumber:
  6. def __init__(self, number, start_pos, end_pos, line):
  7. self.number = number
  8. self.start_pos = start_pos
  9. self.end_pos = end_pos
  10. self.line = line
  11. def _is_symbol(self, char):
  12. return (char != "." and not char.isdigit())
  13. def _check_up(self, input):
  14. if self.line == 0:
  15. return False
  16. cur_line = input[self.line - 1]
  17. for i in range(max(0, self.start_pos-1), min(len(cur_line)-1, self.end_pos+2)):
  18. char = cur_line[i]
  19. if self._is_symbol(char):
  20. debug(f"Found symbol next to {self.number} at line {self.line-1}: {i}")
  21. return True
  22. return False
  23. def _check_down(self, input):
  24. if self.line == len(input)-1:
  25. return False
  26. cur_line = input[self.line + 1]
  27. for i in range(max(0, self.start_pos-1), min(len(cur_line)-1, self.end_pos+2)):
  28. char = cur_line[i]
  29. if self._is_symbol(char):
  30. debug(f"Found symbol next to {self.number} at line {self.line+1}: {i}")
  31. return True
  32. return False
  33. def _check_left(self, input):
  34. if self.start_pos == 0:
  35. debug("Already at the left-hand side of the line")
  36. return False
  37. if self._is_symbol(input[self.line][self.start_pos-1]):
  38. debug(f"Found symbol next to {self.number} at line {self.line}: {self.start_pos-1}")
  39. return True
  40. return False
  41. def _check_right(self, input):
  42. if self.end_pos == len(input[0]) - 1:
  43. debug("Already at the right-hand side of the line")
  44. return False
  45. if self._is_symbol(input[self.line][self.end_pos+1]):
  46. debug(f"Found symbol next to {self.number} at line {self.line}: {self.end_pos+1}")
  47. return True
  48. return False
  49. def is_part_number(self, input):
  50. return (
  51. self._check_up(input)
  52. or self._check_down(input)
  53. or self._check_left(input)
  54. or self._check_right(input)
  55. )
  56. def main():
  57. lines = load_input(3)
  58. # Input is lines of periods (.), numbers (0-9), and symbols
  59. # (anything that isn't a period or number)
  60. # Any number adjacent (horizontally, vertically, diagonally)
  61. # to a symbol is a part number. Get the sum of the part numbers.
  62. max_len = len(lines[0]) # all lines are the same length
  63. positions = []
  64. for j, line in enumerate(lines):
  65. i = 0
  66. while i < max_len:
  67. if line[i].isdigit():
  68. current_number = ""
  69. start_pos = i
  70. while i < max_len and line[i].isdigit():
  71. current_number += f"{line[i]}"
  72. i += 1
  73. end_pos = i
  74. input_number = InputNumber(
  75. number = int(current_number),
  76. start_pos = start_pos,
  77. end_pos = end_pos-1, # i is one greater than the end of the number
  78. line = j
  79. )
  80. positions.append(input_number)
  81. debug(f"Found {input_number.number} at line {input_number.line} ({input_number.start_pos}, {input_number.end_pos})")
  82. i += 1
  83. # Now I have a list of the positions of all the numbers in the input.
  84. part_numbers = []
  85. for p in positions:
  86. if p.is_part_number(lines):
  87. part_numbers.append(p.number)
  88. print(sum(part_numbers))
  89. if __name__ == "__main__":
  90. main()