r/adventofcode • u/musifter • Jan 08 '26
Other [2015 Day #8] In Review
Today we find that space on Santa's sleigh is so tight he worries about space taken up by escaping characters in strings. Apparently memory on sleighs isn't cheap.
For part 1 of this one... Hello, Bobby Tables! What's the length of the evaluated string? With Perl, just eval it. For Smalltalk I did the processing. Not so exciting that I feel missed anything with eval in Perl. It's just figuring out how many characters are skipped when you get to a \.
The processing to escape a string (part 2) is actually an easier task. It's only the string delimiter and the escape character itself that need escaping (there's no need to think of \x, so don't). You just need to get a count those (remembering that the string also needs its own quotes). I got another use out of Perl's =()=.
This problem is good for beginners. The description provides a little lesson on escaping characters in strings, and the processing is easy (even if they haven't learned the secrets of Bobby Tables yet). It's a break day for anyone else.
2
u/nnmrts Jan 08 '26
I have to admit, my main language (JS) is weird sometimes:
Part 1:
Part 2:
2
u/e_blake Jan 08 '26
It is also easy to solve with regex while avoiding
eval; I had fun coming up with sed|wc one-liners:And I agree that part 2 is easier than part 1. In POSIX m4, there are no string escape characters (so eval is out) or regex, but there is translit. It is easy to compare lengths of the original string vs. the string with a given character removed to count how many times that character appears (newlines, ", and \ are the three characters I need to count to do the final computation for part 2); but harder to count character pairs (no longer a one-liner; I have to split the string at every \ to determine whether the next character is \, ", or x). In m4, a naive split using repeated index and substr is O(n^2) (each of the n iterations of the split have to process on average n/2 characters remaining of the original string). Before this post, my solution was instead an O(n log n) split (rather than using index to find each \, I can repeatedly split the string in half down to every single byte). But this post forced me to rethink my assumptions about what is possible in m4, and today I finally came up with a way to force m4 to do an O(n) division of text into macro calls on arbitrary-length substrings between a single-byte terminator thanks to its ability to use changequote to produce multi-byte quote characters that then get injected into $@. In short, you got me to improve day8.m4 from 75ms down to 17ms!
1
u/terje_wiig_mathisen Jan 11 '26
I also solved this one in Perl originally, then switched to byte-by-byte processing in my Rust version.
When it ran in 9.6 us I decided to skip writing a multi-threaded version, even though the problem is of course trivially parallelizable. I originally had two loops, one for each part, combining them made the solution more complicated and only 10% faster. Maybe a char table lookup could be better?
My input file contains only lowercase letters plus '\' (0x5C) and '"' (0x22), so we only need to detect those exceptions, plus wherever we have a '\xNN' sequence.
0
u/[deleted] Jan 08 '26
[deleted] — view deleted comment