Code for the Advent of Code event
aoc advent-of-code
at rust 76 lines 2.1 kB view raw
1replacements = {} 2 3sequence = {} 4 5copy = (tbl) -> 6 return tbl unless type(tbl) == 'table' 7 {k, copy v for k, v in pairs tbl} 8 9parse = (line) -> 10 source, replace = line\match '(%a+) => (%a+)' 11 12 if source and replace 13 replacements[source] = {} unless replacements[source] 14 replacements[source][#replacements[source] + 1] = replace 15 elseif line\match '%a+' 16 sequence = [element for element in line\gmatch '[A-Z][a-z]?'] 17 18count_molecules = -> 19 generated = {} 20 count = 0 21 for source, targets in pairs replacements 22 for i = 1, #sequence 23 continue unless sequence[i] == source 24 for target in *targets 25 seq = copy sequence 26 seq[i] = target 27 str = table.concat seq, '' 28 count += 1 unless generated[str] 29 generated[str] = true 30 count 31 32parse_sequence = (str) -> 33 [element for element in str\gmatch '[A-Z][a-z]?'] 34 35reformat = (sequence using nil) -> 36 new_seq = {} 37 for elements in *sequence 38 for element in elements\gmatch '[A-Z][a-z]?' 39 new_seq[#new_seq + 1] = element 40 new_seq 41 42reduce = (current, counter, target, mapping) -> 43 --coroutine.yield -1 if counter > 1 44 coroutine.yield counter if str == target 45 46 for source, replace in pairs mapping 47 --for i = 1, #current 48 new, num = current\gsub(source, replace, 1) 49 coroutine.yield -1 if num == 0 or #new > #current 50 reduce new, counter + 1, target, mapping 51 52get_counts = (current, target, mapping) -> 53 coroutine.wrap -> reduce current, 1, target, mapping 54 55get_reverse_mapping = -> 56 mapping = {} 57 58 for k, v in pairs replacements 59 for key in *v 60 mapping[key] = k 61 62 mapping 63 64make_molecule = -> 65 reverse = get_reverse_mapping! 66 67 molecule = table.concat sequence, '' 68 69 counts = {} 70 71 for count in get_counts molecule, 'e', reverse 72 continue if count == -1 73 print count 74 counts[#counts + 1] = count 75 76{ :parse, :count_molecules, :make_molecule }