Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
c254bb8643
32
tools/aoc.py
32
tools/aoc.py
@ -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)
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -19,10 +19,10 @@ class DataFile(dict):
|
||||
self.load()
|
||||
|
||||
def load(self):
|
||||
pass
|
||||
raise NotImplementedError()
|
||||
|
||||
def save(self):
|
||||
pass
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
class JSONFile(DataFile):
|
||||
|
||||
35
tools/irc.py
35
tools/irc.py
@ -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):
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
|
||||
@ -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]
|
||||
|
||||
Loading…
Reference in New Issue
Block a user