Merge remote-tracking branch 'origin/master'

This commit is contained in:
Stefan Harmuth 2022-08-10 23:35:01 +02:00
commit c254bb8643
7 changed files with 48 additions and 46 deletions

View File

@ -28,17 +28,17 @@ class AOCDay:
self.part_func = [self.part1, self.part2]
def part1(self) -> Any:
pass
raise NotImplementedError()
def part2(self) -> Any:
pass
raise NotImplementedError()
def runPart(self, part: int, verbose: bool = False, measure_runtime: bool = False, timeit_number: int = 50):
def run_part(self, part: int, verbose: bool = False, measure_runtime: bool = False, timeit_number: int = 50):
case_count = 0
for solution, input_file in self.inputs[part]:
exec_time = None
answer = None
self._loadInput(input_file)
self._load_input(input_file)
if not measure_runtime or case_count < len(self.inputs[part]) - 1:
answer = self.part_func[part]()
@ -50,35 +50,35 @@ class AOCDay:
exec_time = stopwatch.avg_string(timeit_number)
if solution is None:
printSolution(self.day, part + 1, answer, solution, case_count, exec_time)
print_solution(self.day, part + 1, answer, solution, case_count, exec_time)
if answer not in {u"", b"", None, b"None", u"None"}:
self._submit(part + 1, answer)
else:
if verbose or answer != solution:
printSolution(self.day, part + 1, answer, solution, case_count, exec_time)
print_solution(self.day, part + 1, answer, solution, case_count, exec_time)
if answer != solution:
return False
case_count += 1
if case_count == len(self.inputs[part]) and not verbose:
printSolution(self.day, part + 1, answer, exec_time=exec_time)
print_solution(self.day, part + 1, answer, exec_time=exec_time)
def run(self, parts: int = 3, verbose: bool = False, measure_runtime: bool = False, timeit_number: int = 50):
if parts & 1:
self.runPart(0, verbose, measure_runtime, timeit_number)
self.run_part(0, verbose, measure_runtime, timeit_number)
if parts & 2:
self.runPart(1, verbose, measure_runtime, timeit_number)
self.run_part(1, verbose, measure_runtime, timeit_number)
def _loadInput(self, filename):
def _load_input(self, filename):
file_path = os.path.join(INPUTS_PATH, filename)
if not os.path.exists(file_path):
self._downloadInput(file_path)
self._download_input(file_path)
with open(os.path.join(INPUTS_PATH, filename)) as f:
self.input = f.read().splitlines()
def _downloadInput(self, filename: str):
def _download_input(self, filename: str):
# FIXME: implement wait time for current day before 06:00:00 ?
session_id = open(".session", "r").readlines()[0].strip()
response = requests.get(
@ -212,16 +212,16 @@ class AOCDay:
if input has multiple lines, returns a 2d array (a[line][values])
"""
if len(self.input) == 1:
return splitLine(line=self.input[0], split_char=split_char, return_type=return_type)
return split_line(line=self.input[0], split_char=split_char, return_type=return_type)
else:
return_array = []
for line in self.input:
return_array.append(splitLine(line=line, split_char=split_char, return_type=return_type))
return_array.append(split_line(line=line, split_char=split_char, return_type=return_type))
return return_array
def printSolution(day: int, part: int, solution: Any, test: Any = None, test_case: int = 0, exec_time: str = None):
def print_solution(day: int, part: int, solution: Any, test: Any = None, test_case: int = 0, exec_time: str = None):
if test is not None:
print(
"%s (TEST day%d/part%d/case%d): got '%s'; expected '%s'"
@ -241,7 +241,7 @@ def printSolution(day: int, part: int, solution: Any, test: Any = None, test_cas
print("Day %s, Part %s - Average run time: %s" % (day, part, exec_time))
def splitLine(line, split_char: str = ',', return_type: Union[Type, List[Type]] = None):
def split_line(line, split_char: str = ',', return_type: Union[Type, List[Type]] = None):
if split_char:
line = line.split(split_char)

View File

@ -18,6 +18,7 @@ import sys
import time
from signal import SIGTERM, signal
DEV_NULL = "/dev/null"
class Daemon:
"""
@ -26,7 +27,7 @@ class Daemon:
Usage: subclass the Daemon class and override the run() method
"""
def __init__(self, pidfile='_.pid', stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):
def __init__(self, pidfile='_.pid', stdin=DEV_NULL, stdout=DEV_NULL, stderr=DEV_NULL):
self.stdin = stdin
self.stdout = stdout
self.stderr = stderr

View File

@ -19,10 +19,10 @@ class DataFile(dict):
self.load()
def load(self):
pass
raise NotImplementedError()
def save(self):
pass
raise NotImplementedError()
class JSONFile(DataFile):

View File

@ -2,6 +2,7 @@ from time import sleep
from .schedule import Scheduler
from .simplesocket import ClientSocket
from .types import StrOrNone
from datetime import timedelta
from enum import Enum
from typing import Callable, Dict, List, Union
@ -166,24 +167,24 @@ class ServerMessage(str, Enum):
class User:
user: str
identifier: str
nickname: str
username: str
hostname: str
def __init__(self, user: str):
self.user = user
if "@" not in self.user:
self.nickname = self.hostname = self.user
def __init__(self, identifier: str):
self.identifier = identifier
if "@" not in self.identifier:
self.nickname = self.hostname = self.identifier
else:
user, self.hostname = self.user.split("@")
if "!" in user:
self.nickname, self.username = user.split("!")
identifier, self.hostname = self.identifier.split("@")
if "!" in identifier:
self.nickname, self.username = identifier.split("!")
else:
self.nickname = self.username = user
self.nickname = self.username = identifier
def nick(self, new_nick: str):
self.user.replace("%s!" % self.nickname, "%s!" % new_nick)
self.identifier.replace("%s!" % self.nickname, "%s!" % new_nick)
self.nickname = new_nick
@ -198,12 +199,12 @@ class Channel:
self.userlist = {}
def join(self, user: User):
if user.user not in self.userlist:
self.userlist[user.user] = user
if user.identifier not in self.userlist:
self.userlist[user.identifier] = user
def quit(self, user: User):
if user.user in self.userlist:
del self.userlist[user.user]
if user.identifier in self.userlist:
del self.userlist[user.identifier]
class Client:
@ -212,8 +213,7 @@ class Client:
__server_caps: Dict[str, Union[str, int]]
__userlist: Dict[str, User]
__channellist: Dict[str, Channel]
__server_name: str = None
__my_user: str = None
__my_user: StrOrNone
def __init__(self, server: str, port: int, nick: str, username: str, realname: str = "Python Bot"):
self.__userlist = {}
@ -276,7 +276,6 @@ class Client:
self.__function_register[msg_type] = [func]
def on_rpl_welcome(self, msg_from: str, msg_to: str, message: str):
self.__server_name = msg_from
self.__my_user = message.split()[-1]
self.__userlist[self.__my_user] = User(self.__my_user)
@ -302,7 +301,7 @@ class Client:
def on_nick(self, msg_from: str, msg_to: str, message: str):
self.__userlist[msg_from].nick(msg_to)
self.__userlist[self.__userlist[msg_from].user] = self.__userlist[msg_from]
self.__userlist[self.__userlist[msg_from].identifier] = self.__userlist[msg_from]
del self.__userlist[msg_from]
def on_join(self, msg_from: str, msg_to: str, message: str):

View File

@ -163,9 +163,6 @@ class Stack(LinkedList):
def push(self, obj: Any):
self._append(obj)
def pop(self) -> Any:
return self._pop()
def peek(self) -> Any:
return self._tail.value

View File

@ -1,7 +1,7 @@
from dataclasses import dataclass
from dataclasses import dataclass, field
from enum import Enum
from tools.lists import Queue, Stack
from typing import Any, Union
from typing import Any, List, Union
class Rotate(Enum):
@ -29,6 +29,12 @@ class TreeNode:
return str(self)
class TrieNode:
value: str
parent: Union['TrieNode', None] = None
children: List['TrieNode'] = field(default_factory=list)
def update_node(node: TreeNode):
left_depth = node.left.height if node.left is not None else -1
right_depth = node.right.height if node.right is not None else -1
@ -112,10 +118,8 @@ class BinaryTree:
while node is not None:
if obj < node.value:
node = node.left
continue
elif obj > node.value:
node = node.right
continue
else:
return node
@ -266,7 +270,7 @@ class Heap(BinarySearchTree):
c_node = c_node.left
ret = c_node.value
self.remove(ret, c_node.parent)
self._remove(c_node)
return ret
def popMax(self):
@ -278,7 +282,7 @@ class Heap(BinarySearchTree):
c_node = c_node.right
ret = c_node.value
self.remove(ret, c_node.parent)
self._remove(c_node)
return ret

View File

@ -1,6 +1,7 @@
from typing import Union
Numeric = Union[int, float]
StrOrNone = Union[str, None]
IntOrNone = Union[int, None]
FloatOrNone = Union[float, None]
NumericOrNone = Union[Numeric, None]