-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Automatization for fetching inputs, use nightly, logic simplifications #1
base: main
Are you sure you want to change the base?
Changes from all commits
0a6c286
f59661d
a6d0790
5db9cd8
1903ce4
102265d
e15be54
0498238
4aaa0f0
e0073ce
52897bd
f56bcaf
5814c4d
cea59fd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
|
||
# Netscape HTTP Cookie File | ||
.adventofcode.com TRUE / FALSE 0 session YOUR_SESSION_COOKIE |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
from parser import * | ||
from parser import make_parser | ||
|
||
struct Solution: | ||
var parse: Parser | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
from parser import * | ||
from parser import make_parser | ||
from os.atomic import Atomic | ||
from collections import List | ||
from wrappers import run_multiline_task | ||
|
@@ -23,24 +23,19 @@ struct MultiMatcher: | |
var pfx: List[Int32] | ||
var msk: List[Int32] | ||
|
||
fn __init__(inout self, words: VariadicList[StringLiteral]): | ||
fn __init__(inout self, words: List[String]) raises: | ||
self.fcv = List[UInt8]() | ||
self.pfx = List[Int32]() | ||
self.msk = List[Int32]() | ||
for i in range(len(words)): | ||
self.add(words[i]) | ||
for w in words: | ||
self.add(w[]) | ||
|
||
fn add(inout self, s: String): | ||
l = len(s) | ||
# s._buffer[l - 1] == ord(s[i]); but works faster it seems | ||
# Not sure if accessing _buffer is discouraged? Probably will break one day. | ||
self.fcv.append(s._buffer[l - 1]) | ||
fn add(inout self, s: String) raises: | ||
self.fcv.append(ord(s[-1])) | ||
var r: Int32 = 0 | ||
var m: Int32 = 0 | ||
# While iterators are supported in Mojo, none of the standard library | ||
# types implement them, have to use range(), which does work. | ||
for i in range(l - 1): | ||
r = (r << 8) + int(s._buffer[i]) | ||
for c in s[:-1]: | ||
r = (r << 8) + ord(c) | ||
m = (m << 8) + 0xFF | ||
self.pfx.append(r) | ||
self.msk.append(m) | ||
|
@@ -89,11 +84,11 @@ fn main() raises: | |
a1 += lsum | ||
|
||
# Construct matchers for all words. When looking backwards, the words have to be reversed. | ||
# Fun fact - VariadicList apparently can hold literals, but cannot hold Strings. | ||
# Fun fact - List apparently can hold literals, but cannot hold Strings. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this is no longer true (used to be way back when) -> please remove comment if migrating to List<> works now |
||
# Variadic since other list variants only make sense in some very specific contexts | ||
# like when you only use predetermined list sizes and don't iterate over the list. | ||
m = MultiMatcher(VariadicList[StringLiteral]("zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine")) | ||
r = MultiMatcher(VariadicList[StringLiteral]("orez", "eno", "owt", "eerht", "ruof", "evif", "xis", "neves", "thgie", "enin")) | ||
m = MultiMatcher(List[String]("zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine")) | ||
r = MultiMatcher(List[String]("orez", "eno", "owt", "eerht", "ruof", "evif", "xis", "neves", "thgie", "enin")) | ||
|
||
# Similar to the part 1, this does the digits checks and also uses the multi-matchers | ||
# to find words. | ||
|
@@ -106,8 +101,8 @@ fn main() raises: | |
var d2 = 0 | ||
# last four characters code | ||
var l4: Int32 = 0 | ||
for i in range(s.size): | ||
c = int(s[i]) | ||
for c_ref in s.as_bytes_span(): | ||
c = int(c_ref[]) | ||
var d = -1 | ||
if c >= zero and c <= nine: | ||
d = c - zero | ||
|
@@ -119,8 +114,8 @@ fn main() raises: | |
d1 = d | ||
break | ||
l4 = 0 | ||
for i in range(s.size - 1, -1, -1): | ||
c = int(s[i]) | ||
for c_ref in s.as_bytes_span()[::-1]: | ||
c = int(c_ref[]) | ||
var d = -1 | ||
if c >= zero and c <= nine: | ||
d = c - zero | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,40 +1,26 @@ | ||
from parser import * | ||
from parser import make_parser | ||
from collections import Counter | ||
from os.atomic import Atomic | ||
from wrappers import run_multiline_task | ||
|
||
# Replaces ord('a') | ||
alias ord_a = ord("a") | ||
|
||
|
||
fn maxdict(s: StringSlice) raises -> Tuple[Int, Int, Int]: | ||
fn maxballs(line: String) raises -> Counter[String]: | ||
""" | ||
Parse a single line and return a dictionary with maximum values for each ball color | ||
across all the draws. Internally uses hierarchical parsing to split off the header, | ||
split draws, and then split colors. | ||
""" | ||
# Skip header. Game IDs are sequential, anyway. | ||
alias cOlon = ord(":") | ||
alias cR = ord("r") | ||
alias cG = ord("g") | ||
start = s.find(cOlon) + 2 # ':' | ||
# Top-level parser for draws - semicolon separated | ||
draws = make_parser[";"](s[start:]) | ||
red = green = blue = 0 | ||
for d in range(draws.length()): | ||
# Secondary level parser for comma-separated colors | ||
colors = make_parser[","](draws.get(d)) | ||
for b in range(colors.length()): | ||
# split color name and value | ||
tok = make_parser[" "](colors.get(b)) | ||
v = int(atoi(tok.get(0))) | ||
col = tok.get(1) | ||
if col[0] == cR: | ||
red = max(red, v) | ||
elif col[0] == cG: | ||
green = max(green, v) | ||
else: | ||
blue = max(blue, v) | ||
return (red, green, blue) | ||
var games = line.split(": ")[1].split("; ") | ||
counter = Counter[String]() | ||
for game_ref in games: | ||
game = game_ref[] | ||
game = game.replace(",", "") | ||
toks = game.split(" ") | ||
for i in range(len(toks) // 2): | ||
cnt = int(toks[i * 2]) | ||
col = toks[i * 2 + 1] | ||
counter[col] = max(counter[col], cnt) | ||
return counter | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. While I appreciate the direction, this repo's point is to build fast solutions. While it's nice that Mojo now has some collection builtins, split() was there before and I'm not using it since it's abysmally slow. This task is a perfect example of that problem - with this approach it's about 8 times slower than the 'hacky but fast' solution was (which was on par with PyPy), and it's now ~2.5 times slower than Python. The hand-crafted parsers that work over raw memory are not really easy (or efficient) in Python, so this is still some way in which I was able to squeeze some performance of Mojo. OTOH sure, this approach shows performance gaps in the std library. Perhaps add this code as a _slow variant of this solution to highlight this, but keep this version as-is (or modified to adjust for some QoL improvements in recent Mojo as in other bits. |
||
|
||
|
||
fn main() raises: | ||
|
@@ -48,8 +34,8 @@ fn main() raises: | |
@parameter | ||
fn step1(l: Int): | ||
try: | ||
(r, g, b) = maxdict(lines.get(l)) | ||
if r <= 12 and g <= 13 and b <= 14: | ||
var colors = maxballs(str(lines.get(l))) | ||
if colors["red"] <= 12 and colors["green"] <= 13 and colors["blue"] <= 14: | ||
sum1 += l + 1 | ||
except: | ||
pass | ||
|
@@ -58,8 +44,8 @@ fn main() raises: | |
@parameter | ||
fn step2(l: Int): | ||
try: | ||
(r, g, b) = maxdict(lines.get(l)) | ||
sum2 += r * g * b | ||
var colors = maxballs(str(lines.get(l))) | ||
sum2 += colors["red"] * colors["green"] * colors["blue"] | ||
except: | ||
pass | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,7 +12,10 @@ def find_nums(): | |
r = 0 | ||
q = 0 | ||
for x in range(dimx): | ||
c = ord(lines[y][x]) | ||
try: | ||
c = ord(lines[y][x]) | ||
except IndexError: | ||
c = 0 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So this is probably more of an effect of assumptions on what is contained in lines and how they are loaded - the code in Python is rather simple and does not do the trailing newline check. Rather than a try/catch here you could fix this by removing the last element of lines[] after it's loaded, if it's empty. |
||
if c >= 48 and c <= 57: | ||
d = c - 48 | ||
r = r * 10 + d | ||
|
@@ -56,7 +59,11 @@ def part2(): | |
ly = min(y + 1, dimy - 1) | ||
for gy in range(sy, ly + 1): | ||
for gx in range(sx, lx + 1): | ||
if lines[gy][gx] == "*": | ||
try: | ||
c = lines[gy][gx] | ||
except IndexError: | ||
c = '' | ||
if c == "*": | ||
gk = gy * dimx + gx | ||
if gc[gk] != 0: | ||
s2 += gc[gk] * v | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
from parser import * | ||
from parser import make_parser | ||
from collections import List | ||
from wrappers import minibench | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
from parser import * | ||
from parser import make_parser | ||
from math import sqrt | ||
from wrappers import minibench | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
from parser import * | ||
from parser import make_parser | ||
from wrappers import minibench | ||
from array import Array | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
from parser import * | ||
from parser import make_parser | ||
from wrappers import minibench | ||
from array import Array | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
from parser import * | ||
from parser import make_parser | ||
from wrappers import minibench | ||
from array import Array | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
from parser import * | ||
from parser import make_parser | ||
from wrappers import minibench | ||
from array import Array | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
from parser import * | ||
from parser import make_parser | ||
from wrappers import minibench | ||
from array import Array | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
from parser import * | ||
from parser import make_parser | ||
from wrappers import minibench | ||
from array import Array | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
from parser import * | ||
from parser import make_parser | ||
from wrappers import minibench | ||
from array import Array | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
from parser import * | ||
from parser import make_parser | ||
from wrappers import minibench | ||
from array import Array | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks - I fixed the language problems when upgrading to 24.5 but never got around to removing these relics.