|
| 1 | +symbols = ['!', '§', '$', '%', '&', '/', '{', '}', '(', ')', '[', ']', '=', '?', '*', '+', '~', '#', '-', '_', ',', ';', ':', '\\', '@', '^', '°'] |
| 2 | + |
| 3 | +def get_symbol_positions(schematic, symbols_list=symbols): |
| 4 | + positions = [] |
| 5 | + |
| 6 | + r = len(schematic) |
| 7 | + c = len(schematic[0]) |
| 8 | + for i in range(r): |
| 9 | + for j in range(c): |
| 10 | + if schematic[i][j] in symbols_list: |
| 11 | + positions.append((i,j)) |
| 12 | + return positions |
| 13 | + |
| 14 | + |
| 15 | +def get_number_positions(schematic): |
| 16 | + # Structure: (row, col, num_as_string) |
| 17 | + number_positions = [] |
| 18 | + |
| 19 | + r = len(schematic) |
| 20 | + c = len(schematic[0]) |
| 21 | + for i in range(r): |
| 22 | + j = 0 |
| 23 | + while j < c: |
| 24 | + if schematic[i][j].isdigit(): |
| 25 | + k = 1 |
| 26 | + while(j+k < c and schematic[i][j+k].isdigit()): |
| 27 | + k += 1 |
| 28 | + num = schematic[i][j:j+k] |
| 29 | + number_positions.append((i, j, num)) |
| 30 | + j += k-1 |
| 31 | + j += 1 |
| 32 | + return number_positions |
| 33 | + |
| 34 | + |
| 35 | +def is_number_part_number(num_pos_info, schematic): |
| 36 | + i, j, num_string = num_pos_info |
| 37 | + r = len(schematic) |
| 38 | + c = len(schematic[0]) |
| 39 | + |
| 40 | + for k in range(j, j + len(num_string)): |
| 41 | + potential_indices = [(i-1, k), (i+1, k), (i, k-1), (i, k+1), (i-1, k-1), (i-1, k+1), (i+1, k-1), (i+1, k+1)] |
| 42 | + for pot_i, pot_j in potential_indices: |
| 43 | + if pot_i < 0 or pot_i >= r or pot_j < 0 or pot_j >= c: |
| 44 | + continue |
| 45 | + if schematic[pot_i][pot_j] in symbols: |
| 46 | + return True |
| 47 | + return False |
| 48 | + |
| 49 | + |
| 50 | +def is_number_adjacent_to(num_pos_info, star_i, star_j, schematic): |
| 51 | + i, j, num_string = num_pos_info |
| 52 | + r = len(schematic) |
| 53 | + c = len(schematic[0]) |
| 54 | + |
| 55 | + for k in range(j, j + len(num_string)): |
| 56 | + potential_indices = [(i-1, k), (i+1, k), (i, k-1), (i, k+1), (i-1, k-1), (i-1, k+1), (i+1, k-1), (i+1, k+1)] |
| 57 | + for pot_i, pot_j in potential_indices: |
| 58 | + if pot_i < 0 or pot_i >= r or pot_j < 0 or pot_j >= c: |
| 59 | + continue |
| 60 | + if pot_i == star_i and pot_j == star_j: |
| 61 | + return True |
| 62 | + return False |
| 63 | + |
| 64 | +def get_gear_ratios(schematic): |
| 65 | + gear_ratios = [] |
| 66 | + star_positions = get_symbol_positions(schematic, ['*']) |
| 67 | + number_positions = get_number_positions(schematic) |
| 68 | + for star_i, star_j in star_positions: |
| 69 | + adjacent_numbers = [] |
| 70 | + for num_pos in number_positions: |
| 71 | + if is_number_adjacent_to(num_pos, star_i, star_j, schematic): |
| 72 | + adjacent_numbers.append(int(num_pos[2])) |
| 73 | + if len(adjacent_numbers) == 2: |
| 74 | + gear_ratios.append(adjacent_numbers[0] * adjacent_numbers[1]) |
| 75 | + return gear_ratios |
| 76 | + |
| 77 | + |
| 78 | +def get_part_numbers(schematic): |
| 79 | + all_number_positions = get_number_positions(schematic) |
| 80 | + part_number_positions = filter(lambda num_pos : is_number_part_number(num_pos, schematic), all_number_positions) |
| 81 | + part_numbers = list(map(lambda part_number_pos : int(part_number_pos[2]), part_number_positions)) |
| 82 | + return part_numbers |
| 83 | + |
| 84 | + |
| 85 | +def read_data_from_file(filename): |
| 86 | + schematic = [] |
| 87 | + with open(filename) as file: |
| 88 | + for line in file: |
| 89 | + line_string = line.rstrip() |
| 90 | + schematic.append(line_string) |
| 91 | + return schematic |
| 92 | + |
| 93 | + |
| 94 | +schematic = read_data_from_file("input.txt") |
| 95 | +# schematic = read_data_from_file("testinput.txt") |
| 96 | + |
| 97 | +# print(schematic) |
| 98 | +# print(schematic[0][3]) |
| 99 | + |
| 100 | +# symbol_positions = get_symbol_positions(schematic) |
| 101 | +# print(symbol_positions) |
| 102 | +# number_positions = get_number_positions(schematic) |
| 103 | +# print(number_positions) |
| 104 | + |
| 105 | +# print(is_number_part_number((0, 4, '224'), schematic)) |
| 106 | +# print(is_number_part_number((0, 12, '487'), schematic)) |
| 107 | +# print(is_number_part_number((1, 89, '439'), schematic)) |
| 108 | +# print(is_number_part_number((3, 118, '464'), schematic)) |
| 109 | + |
| 110 | +# part_numbers = get_part_numbers(schematic) |
| 111 | +# print(part_numbers) |
| 112 | +# print(f"Sum: {sum(part_numbers)}") |
| 113 | + |
| 114 | +gear_ratios = get_gear_ratios(schematic) |
| 115 | +print(gear_ratios) |
| 116 | +print(f'Sum: {sum(gear_ratios)}') |
0 commit comments