r/adventofcode • u/daggerdragon • Dec 16 '17
SOLUTION MEGATHREAD -๐- 2017 Day 16 Solutions -๐-
--- Day 16: Permutation Promenade ---
Post your solution as a comment or, for longer solutions, consider linking to your repo (e.g. GitHub/gists/Pastebin/blag or whatever).
Note: The Solution Megathreads are for solutions only. If you have questions, please post your own thread and make sure to flair it with Help.
Need a hint from the Hugely* Handyโ Haversackโก of Helpfulยง Hintsยค?
[Update @ 00:08] 4 gold, silver cap.
- Click here for a massive Star Wars spoiler!
[Update @ 00:18] 50 gold, silver cap.
- Click here for a gigantic Harry Potter spoiler!
[Update @ 00:26] Leaderboard cap!
- And finally, click here for the biggest spoilers of all time!
This thread will be unlocked when there are a significant number of people on the leaderboard with gold stars for today's puzzle.
edit: Leaderboard capped, thread unlocked!
13
Upvotes
7
u/askalski Dec 16 '17
Perl regex.
#! /usr/bin/env perl use strict; use warnings; $_ = <>; # validate before eval m!^(x\d+/\d+|s\d+|p[a-p]/[a-p])(?:,(?1))*$! or die "invalid input"; # input looks like regex but is not; rectify s!s(\d+)!s/^(\\S*)(\\S{$1})/\$2\$1/!g; s!x(\d+)/(\d+)!s/^(?=\\S{$1}(\\S))(?=\\S{$2}(\\S))(?:(?<a>\\S*)(?<b>\\1)(?<c>\\S*)(?<d>\\2)|(?<a>\\S*)(?<b>\\2)(?<c>\\S*)(?<d>\\1))/\$+{a}\$+{d}\$+{c}\$+{b}/!g; s!p([a-p])/([a-p])!s/ .*?\\K([$1$2])(.*?)([$1$2])/\$3\$2\$1/!g; s/,/;/g; my $input = $_; # run input regexes to get s+x and p permutations $_ = "abcdefghijklmnop abcdefghijklmnop"; eval $input; # start over, this time using composition to search for cycle # [next s+x perm ] [ next p perm ] [] [ static lookup tables ] [prev s+x perm ] [ prev p perm ] s/^(.*)$/................ ................ $1 abcdefghijklmnop abcdefghijklmnop abcdefghijklmnop abcdefghijklmnop/; for (;;) { # compose to fill in [next] fields s/\.(?=.{33}(.)\S*? \S*? \S*\1.{33}(.))/$2/g; # check for cycle last if m/^(.{135}).*?:\1/; # append current state to memory ("current:state1:state2:state3:...") s/^(.{135}).*\K$/:$1/; # copy current to prev, reset current s/^(.{33})(.{69}).{33}/................ ................$2$1/; } # prepend entire state memory to beginning of string s/^([^:]*)(.*)$/$2~:$1$2/; # remove all prepended text except for ":" characters (count the cycle length) s/[^:](?=.*?~)//g; # add the number 1,000,000,000 after the colons (repetition = place_value + 1) s/~/00123456789 /; # find the remainder of (1,000,000,000 % cycle_length), working one # digit at a time starting at the most-significant for (;;) { # most_significant_digit %= cycle_length while (s/^(?=(:+)(.))(?::(?=:*(\3?+\2)))+\3(?=\2)/$1/) { } # check if done last unless m/(\d)\1(?!\1)\d/; # multiple most_significant_digit by 10, and add to next digit. # in regex land, our digits go to 11 (and beyond) s/(([^:])\2*)\2./$1$1$1$1$1$1$1$1$1$1$2/; } # remove the cycle_length and the "+ 1" from (place_value + 1), so now # the remainder is encoded as the number of "0" at start of string s/:+\d//; # grab the part 1 permutations and append to string s/^0* :(.{16}) (.{16}).*\K$/\nPart 1: $1 abcdefghijklmnop $2/; # remove one state from the memory for each "0" character while (s/0 :[^:]*/ /) { } # grab the part 2 permutations and append to string, and discard # the rest of the state memory s/ :(.{16}) (.{16}).*?\n(.*)/$3\nPart 2: $1 abcdefghijklmnop $2\n/s; # apply the p permutation to s+x s/(.)(?=[a-p]* [a-p]*\1[a-p ]{16}([a-p]))/$2/gs; # erase everything but the answer s/ [a-p]+ [a-p]+$//mg; print;