Code formatting
Signed-off-by: AKP <tom@tdpain.net>
This commit is contained in:
parent
4d3b3fd231
commit
ae703f98aa
5 changed files with 61 additions and 33 deletions
|
@ -10,11 +10,7 @@ import re
|
||||||
OUTPUT_FILE = sys.argv[1]
|
OUTPUT_FILE = sys.argv[1]
|
||||||
YEAR = sys.argv[2]
|
YEAR = sys.argv[2]
|
||||||
|
|
||||||
COLOURS = {
|
COLOURS = {"Golang": "#00ADD8", "Python": "#3572A5", "Nim": "#ffc200"}
|
||||||
"Golang": "#00ADD8",
|
|
||||||
"Python": "#3572A5",
|
|
||||||
"Nim": "#ffc200"
|
|
||||||
}
|
|
||||||
|
|
||||||
MAX_Y_VALUE = 1
|
MAX_Y_VALUE = 1
|
||||||
|
|
||||||
|
@ -23,12 +19,18 @@ challenge_dir_regex = re.compile("""(?m)^(\d{2})-([a-zA-Z]+)$""")
|
||||||
directories = []
|
directories = []
|
||||||
path = os.path.join("challenges", YEAR)
|
path = os.path.join("challenges", YEAR)
|
||||||
for filename in os.listdir(path):
|
for filename in os.listdir(path):
|
||||||
if os.path.isdir(os.path.join(path, filename)) and challenge_dir_regex.match(filename):
|
if os.path.isdir(os.path.join(path, filename)) and challenge_dir_regex.match(
|
||||||
|
filename
|
||||||
|
):
|
||||||
directories.append(filename)
|
directories.append(filename)
|
||||||
|
|
||||||
files = [os.path.join(x, "benchmark.json") for x in directories]
|
files = [os.path.join(x, "benchmark.json") for x in directories]
|
||||||
|
|
||||||
benchmark_data = {"Python": {}, "Golang": {}, "Nim": {}} # adding dicts here sets the order of points being plotted
|
benchmark_data = {
|
||||||
|
"Python": {},
|
||||||
|
"Golang": {},
|
||||||
|
"Nim": {},
|
||||||
|
} # adding dicts here sets the order of points being plotted
|
||||||
|
|
||||||
for filename in files:
|
for filename in files:
|
||||||
fpath = os.path.join(path, filename)
|
fpath = os.path.join(path, filename)
|
||||||
|
@ -37,7 +39,7 @@ for filename in files:
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
print(f"Warning: missing file {fpath}")
|
print(f"Warning: missing file {fpath}")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
data = json.load(f)
|
data = json.load(f)
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
|
@ -54,7 +56,7 @@ for lang in benchmark_data:
|
||||||
day = int(key.split(".", 1)[0])
|
day = int(key.split(".", 1)[0])
|
||||||
all_days.add(day)
|
all_days.add(day)
|
||||||
|
|
||||||
figure = plt.figure(figsize=(25/2, 5))
|
figure = plt.figure(figsize=(25 / 2, 5))
|
||||||
axp1 = figure.add_subplot(1, 2, 1)
|
axp1 = figure.add_subplot(1, 2, 1)
|
||||||
axp2 = figure.add_subplot(1, 2, 2, sharey=axp1)
|
axp2 = figure.add_subplot(1, 2, 2, sharey=axp1)
|
||||||
|
|
||||||
|
@ -69,7 +71,7 @@ for i, language in enumerate(benchmark_data):
|
||||||
days = []
|
days = []
|
||||||
|
|
||||||
for key in data:
|
for key in data:
|
||||||
|
|
||||||
day = int(key.split(".", 1)[0])
|
day = int(key.split(".", 1)[0])
|
||||||
if day not in days:
|
if day not in days:
|
||||||
days.append(day)
|
days.append(day)
|
||||||
|
@ -78,7 +80,7 @@ for i, language in enumerate(benchmark_data):
|
||||||
part_one_times.append(data[key])
|
part_one_times.append(data[key])
|
||||||
if key.endswith(".2"):
|
if key.endswith(".2"):
|
||||||
part_two_times.append(data[key])
|
part_two_times.append(data[key])
|
||||||
|
|
||||||
colour = COLOURS.get(language)
|
colour = COLOURS.get(language)
|
||||||
|
|
||||||
p1 = axp1.scatter(days, part_one_times, color=colour)
|
p1 = axp1.scatter(days, part_one_times, color=colour)
|
||||||
|
@ -87,26 +89,40 @@ for i, language in enumerate(benchmark_data):
|
||||||
for i, day in enumerate(days):
|
for i, day in enumerate(days):
|
||||||
if i + 1 >= len(days):
|
if i + 1 >= len(days):
|
||||||
continue
|
continue
|
||||||
if days[i+1] == day+1:
|
if days[i + 1] == day + 1:
|
||||||
axp1.plot((day, days[i+1]), (part_one_times[i], part_one_times[i+1]), "-", color=colour)
|
axp1.plot(
|
||||||
axp2.plot((day, days[i+1]), (part_two_times[i], part_two_times[i+1]), "-", color=colour)
|
(day, days[i + 1]),
|
||||||
|
(part_one_times[i], part_one_times[i + 1]),
|
||||||
|
"-",
|
||||||
|
color=colour,
|
||||||
|
)
|
||||||
|
axp2.plot(
|
||||||
|
(day, days[i + 1]),
|
||||||
|
(part_two_times[i], part_two_times[i + 1]),
|
||||||
|
"-",
|
||||||
|
color=colour,
|
||||||
|
)
|
||||||
|
|
||||||
figure.suptitle(f"Average {YEAR} challenge running time")
|
figure.suptitle(f"Average {YEAR} challenge running time")
|
||||||
axp1.set_title("Part one")
|
axp1.set_title("Part one")
|
||||||
axp2.set_title("Part two")
|
axp2.set_title("Part two")
|
||||||
|
|
||||||
|
|
||||||
def do_auxillary_parts(axis):
|
def do_auxillary_parts(axis):
|
||||||
plt.sca(axis)
|
plt.sca(axis)
|
||||||
plt.xticks(list(all_days), [str(y) for y in all_days])
|
plt.xticks(list(all_days), [str(y) for y in all_days])
|
||||||
plt.ylabel("Running time (log seconds)")
|
plt.ylabel("Running time (log seconds)")
|
||||||
plt.yscale("log")
|
plt.yscale("log")
|
||||||
plt.xlabel("Day")
|
plt.xlabel("Day")
|
||||||
plt.legend(handles=[patches.Patch(color=COLOURS[label], label=label) for label in COLOURS])
|
plt.legend(
|
||||||
|
handles=[patches.Patch(color=COLOURS[label], label=label) for label in COLOURS]
|
||||||
|
)
|
||||||
# plt.ylim([0, MAX_Y_VALUE])
|
# plt.ylim([0, MAX_Y_VALUE])
|
||||||
# plt.legend(legends)
|
# plt.legend(legends)
|
||||||
|
|
||||||
|
|
||||||
do_auxillary_parts(axp1)
|
do_auxillary_parts(axp1)
|
||||||
do_auxillary_parts(axp2)
|
do_auxillary_parts(axp2)
|
||||||
|
|
||||||
plt.tight_layout()
|
plt.tight_layout()
|
||||||
plt.savefig(OUTPUT_FILE)
|
plt.savefig(OUTPUT_FILE)
|
||||||
|
|
|
@ -4,7 +4,6 @@ from collections.abc import Sequence
|
||||||
|
|
||||||
|
|
||||||
class BaseChallenge:
|
class BaseChallenge:
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def one(instr: str) -> Any:
|
def one(instr: str) -> Any:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
@ -21,12 +20,14 @@ class BaseChallenge:
|
||||||
T = TypeVar("T")
|
T = TypeVar("T")
|
||||||
U = TypeVar("U")
|
U = TypeVar("U")
|
||||||
|
|
||||||
|
|
||||||
def foldl(p: Callable[[U, T], U], i: Iterable[T], start: U) -> U:
|
def foldl(p: Callable[[U, T], U], i: Iterable[T], start: U) -> U:
|
||||||
res = start
|
res = start
|
||||||
for item in i:
|
for item in i:
|
||||||
res = p(res, item)
|
res = p(res, item)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
def foldr(p: Callable[[U, T], U], i: Iterable[T], start: U) -> U:
|
def foldr(p: Callable[[U, T], U], i: Iterable[T], start: U) -> U:
|
||||||
return foldl(p, reversed(i), start)
|
return foldl(p, reversed(i), start)
|
||||||
|
|
||||||
|
@ -42,13 +43,15 @@ class Vector:
|
||||||
return ValueError("expected integer tuple or pair of integers")
|
return ValueError("expected integer tuple or pair of integers")
|
||||||
else:
|
else:
|
||||||
x, y = args
|
x, y = args
|
||||||
|
|
||||||
self.x = int(x)
|
self.x = int(x)
|
||||||
self.y = int(y)
|
self.y = int(y)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _is_vector_tuple(o: Any) -> bool:
|
def _is_vector_tuple(o: Any) -> bool:
|
||||||
return type(o) == tuple and len(o) == 2 and type(o[0]) == int and type(o[1]) == int
|
return (
|
||||||
|
type(o) == tuple and len(o) == 2 and type(o[0]) == int and type(o[1]) == int
|
||||||
|
)
|
||||||
|
|
||||||
def manhattan_distance(self, o: Vector) -> int:
|
def manhattan_distance(self, o: Vector) -> int:
|
||||||
return abs(self.x - o.x) + abs(self.y - o.y)
|
return abs(self.x - o.x) + abs(self.y - o.y)
|
||||||
|
@ -84,6 +87,7 @@ class Vector:
|
||||||
def __hash__(self):
|
def __hash__(self):
|
||||||
return hash((self.x, self.y))
|
return hash((self.x, self.y))
|
||||||
|
|
||||||
|
|
||||||
class Consumer:
|
class Consumer:
|
||||||
x: Sequence[T]
|
x: Sequence[T]
|
||||||
i: int
|
i: int
|
||||||
|
@ -91,14 +95,15 @@ class Consumer:
|
||||||
def __init__(self, x: Sequence[T]):
|
def __init__(self, x: Sequence[T]):
|
||||||
self.x = x
|
self.x = x
|
||||||
self.i = 0
|
self.i = 0
|
||||||
|
|
||||||
def take(self) -> T:
|
def take(self) -> T:
|
||||||
self.i += 1
|
self.i += 1
|
||||||
return self.x[self.i-1]
|
return self.x[self.i - 1]
|
||||||
|
|
||||||
def undo(self):
|
def undo(self):
|
||||||
self.i -= 1
|
self.i -= 1
|
||||||
|
|
||||||
|
|
||||||
class RepeatingConsumer(Consumer):
|
class RepeatingConsumer(Consumer):
|
||||||
def take(self) -> T:
|
def take(self) -> T:
|
||||||
val = super().take()
|
val = super().take()
|
||||||
|
@ -108,4 +113,4 @@ class RepeatingConsumer(Consumer):
|
||||||
def undo(self):
|
def undo(self):
|
||||||
super().undo()
|
super().undo()
|
||||||
if self.i < 0:
|
if self.i < 0:
|
||||||
self.i += len(self.x)
|
self.i += len(self.x)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import os.path
|
import os.path
|
||||||
|
|
||||||
class SaveManager():
|
|
||||||
|
class SaveManager:
|
||||||
def __init__(self, d):
|
def __init__(self, d):
|
||||||
self.dir = d
|
self.dir = d
|
||||||
self.current_n = 0
|
self.current_n = 0
|
||||||
|
@ -8,5 +9,3 @@ class SaveManager():
|
||||||
def save(self, im):
|
def save(self, im):
|
||||||
im.save(os.path.join(self.dir, f"frame_{str(self.current_n).zfill(4)}.png"))
|
im.save(os.path.join(self.dir, f"frame_{str(self.current_n).zfill(4)}.png"))
|
||||||
self.current_n += 1
|
self.current_n += 1
|
||||||
|
|
||||||
|
|
|
@ -6,13 +6,20 @@ import json
|
||||||
# TASKS_STR = input()
|
# TASKS_STR = input()
|
||||||
# TASKS = json.loads(TASKS_STR)
|
# TASKS = json.loads(TASKS_STR)
|
||||||
|
|
||||||
|
|
||||||
def send_result(task_id, ok, output, duration):
|
def send_result(task_id, ok, output, duration):
|
||||||
print(json.dumps({
|
print(
|
||||||
"task_id": task_id,
|
json.dumps(
|
||||||
"ok": ok,
|
{
|
||||||
"output": str(output) if output is not None else "",
|
"task_id": task_id,
|
||||||
"duration": float(duration),
|
"ok": ok,
|
||||||
}), flush=True)
|
"output": str(output) if output is not None else "",
|
||||||
|
"duration": float(duration),
|
||||||
|
}
|
||||||
|
),
|
||||||
|
flush=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
task = json.loads(input())
|
task = json.loads(input())
|
||||||
|
@ -39,10 +46,11 @@ while True:
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
err = f"{type(e)}: {e}"
|
err = f"{type(e)}: {e}"
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
err = f"{type(e)}: {e}\n{''.join(traceback.format_tb(e.__traceback__))}"
|
err = f"{type(e)}: {e}\n{''.join(traceback.format_tb(e.__traceback__))}"
|
||||||
end_time = time.time()
|
end_time = time.time()
|
||||||
|
|
||||||
running_time = end_time-start_time
|
running_time = end_time - start_time
|
||||||
|
|
||||||
if err is not None:
|
if err is not None:
|
||||||
send_result(task_id, False, err, running_time)
|
send_result(task_id, False, err, running_time)
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
from typing import *
|
from typing import *
|
||||||
from aocpy import BaseChallenge
|
from aocpy import BaseChallenge
|
||||||
|
|
||||||
class Challenge(BaseChallenge):
|
|
||||||
|
|
||||||
|
class Challenge(BaseChallenge):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def one(instr: str) -> int:
|
def one(instr: str) -> int:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue