83 lines
2.9 KiB
Python
83 lines
2.9 KiB
Python
from __future__ import annotations
|
|
from dataclasses import dataclass
|
|
import sys
|
|
from typing import List, Self
|
|
|
|
|
|
class color:
|
|
PURPLE = "\033[95m"
|
|
CYAN = "\033[96m"
|
|
DARKCYAN = "\033[36m"
|
|
BLUE = "\033[94m"
|
|
GREEN = "\033[92m"
|
|
YELLOW = "\033[93m"
|
|
RED = "\033[91m"
|
|
BOLD = "\033[1m"
|
|
UNDERLINE = "\033[4m"
|
|
END = "\033[0m"
|
|
|
|
|
|
@dataclass(init=False, eq=False)
|
|
class OASISLine:
|
|
sequence: List[int]
|
|
reduce_map: List[List[int]]
|
|
|
|
def __init__(self, input_line: str):
|
|
self.sequence = list(map(lambda i: int(i), input_line.split(" ")))
|
|
self.reduce_map = [
|
|
self.sequence,
|
|
]
|
|
|
|
def reduce(self) -> Self:
|
|
# sys.stderr.write("=".join(["" for i in range(40)])+"\n")
|
|
line = self.sequence
|
|
# sys.stderr.write(str(line)+"\n")
|
|
while not all(map(lambda i: i == 0, line)):
|
|
new_line = []
|
|
for idx, number in enumerate(line):
|
|
if idx > 0:
|
|
new_line.append(number - line[idx - 1])
|
|
line = new_line
|
|
self.reduce_map.append(line)
|
|
# sys.stderr.write(str(line)+"\n")
|
|
# sys.stderr.write("=".join(["" for i in range(40)])+"\n")
|
|
return self
|
|
|
|
def extrapolate(self):
|
|
# sys.stderr.write("\n" + color.BLUE + "=".join(["" for i in range(40)]) + color.END + "\n")
|
|
next_increment = 0
|
|
for line in reversed(self.reduce_map):
|
|
# sys.stderr.write(str(line))
|
|
if all(map(lambda i: i == line[0], line)):
|
|
next_increment = line[0]
|
|
else:
|
|
next_increment = line[len(line) - 1] + next_increment
|
|
# sys.stderr.write(color.BOLD + f" {next_increment}" + color.END + "\n")
|
|
# sys.stderr.write(color.BLUE + "=".join(["" for i in range(40)]) + color.END + "\n")
|
|
return next_increment
|
|
|
|
def extrapolate_back(self):
|
|
sys.stderr.write("\n" + color.BLUE + "=".join(["" for i in range(40)]) + color.END + "\n")
|
|
next_increment = 0
|
|
for line in reversed(self.reduce_map):
|
|
if all(map(lambda i: i == line[0], line)):
|
|
next_increment = line[0]
|
|
else:
|
|
next_increment = line[0] - next_increment
|
|
sys.stderr.write(color.BOLD + f"{next_increment} " + color.END + str(line) + "\n")
|
|
sys.stderr.write(color.BLUE + "=".join(["" for i in range(40)]) + color.END + "\n")
|
|
return next_increment
|
|
|
|
|
|
@classmethod
|
|
def parse(cls, input_file: str) -> List[OASISLine]:
|
|
# sys.stderr.write("\n")
|
|
the_list = []
|
|
with open(input_file) as input:
|
|
while line := input.readline():
|
|
line = line.rstrip("\n").rstrip()
|
|
# sys.stderr.write(color.RED + f'parsing "{line}"' + color.END + "\n")
|
|
the_list.append(OASISLine(line))
|
|
# sys.stderr.write(color.GREEN + f"parsed {the_list[len(the_list) - 1]}" + color.END + "\n")
|
|
return the_list
|