import itertools def scan_line(line): to_find = "XMAS" return line.count(to_find) def transpose(list_2d): outlist = [] for j in range(max(map(len, list_2d))): outlist.append([]) for i in range(len(list_2d)): # TODO: This is a weird edge case. if j < len(list_2d[i]): outlist[j].append(list_2d[i][j]) outlist[j] = "".join(outlist[j]) return outlist def rotate(list_2d): x_max, y_max = len(list_2d), len(list_2d[0]) diagonal_list = [] # Diagonals starting from (0,0), for the first row. for i in range(x_max): substring = "" x = i y = 0 while x < x_max and y < y_max: #print(x, x_max, y, y_max) substring += list_2d[x][y] x += 1 y += 1 diagonal_list.append(substring) # Reverse diagonal_list = diagonal_list[::-1] # Diagonals starting from (0,1), for the first column. for j in range(1, y_max): substring = "" x = 0 y = j while x < x_max and y < len(list_2d[x]): substring += list_2d[x][y] x += 1 y += 1 diagonal_list.append(substring) return diagonal_list def rotate_neg(list_2d): x_max, y_max = len(list_2d), len(list_2d[0]) diagonal_list = [] # Diagonals starting from (0,0), for the first row. for i in range(x_max): substring = "" x = x_max - 1 - i y = 0 while x >= 0 and y < y_max: #print(x, x_max, y, y_max) substring += list_2d[x][y] x -= 1 y += 1 diagonal_list.append(substring) # Reverse diagonal_list = diagonal_list[::-1] # Diagonals starting from (0,1), for the first column. for j in range(1, y_max): substring = "" x = x_max - 1 y = j while x >= 0 and y < len(list_2d[x]): substring += list_2d[x][y] x -= 1 y += 1 diagonal_list.append(substring) return diagonal_list if __name__ == "__main__": result = 0 with open("input", "r") as fp: # Skip last line as it is empty. full_string = fp.read().split("\n")[:-1] for line in full_string: result += scan_line(line) result += scan_line(line[::-1]) # Transpose for vertical hits. for line in transpose(full_string): result += scan_line(line) result += scan_line(line[::-1]) # Rotate 45 degrees to one side for diagonals. diagonal_list = rotate(full_string) for line in diagonal_list: result += scan_line(line) result += scan_line(line[::-1]) diagonal_list = rotate_neg(full_string) # Rotate the other way round. for line in diagonal_list: result += scan_line(line) result += scan_line(line[::-1]) print(f"The sum of all horizontal XMAS's equals {result}.")