Day 3: Mull It Over

Megathread guidelines

  • Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
  • You can send code in code blocks by using three backticks, the code, and then three backticks or use something such as https://topaz.github.io/paste/ if you prefer sending it through a URL

FAQ

  • ystael@beehaw.org
    link
    fedilink
    arrow-up
    3
    ·
    20 days ago

    J

    We can take advantage of the manageable size of the input to avoid explicit looping and mutable state; instead, construct vectors which give, for each character position in the input, the position of the most recent do() and most recent don't(); for part 2 a multiplication is enabled if the position of the most recent do() (counting start of input as 0) is greater than that of the most recent don't() (counting start of input as minus infinity).

    load 'regex'
    
    raw =: fread '3.data'
    mul_matches =: 'mul\(([[:digit:]]{1,3}),([[:digit:]]{1,3})\)' rxmatches raw
    
    NB. a b sublist y gives elements [a..b) of y
    sublist =: ({~(+i.)/)~"1 _
    
    NB. ". is number parsing
    mul_results =: */"1 ". (}."2 mul_matches) sublist raw
    result1 =: +/ mul_results
    
    do_matches =: 'do\(\)' rxmatches raw
    dont_matches =: 'don''t\(\)' rxmatches raw
    match_indices =: (<0 0) & {"2
    do_indices =: 0 , match_indices do_matches  NB. start in do mode
    dont_indices =: match_indices dont_matches
    NB. take successive diffs, then append length from last index to end of string
    run_lengths =: (}. - }:) , (((#raw) & -) @: {:)
    do_map =: (run_lengths do_indices) # do_indices
    dont_map =: (({. , run_lengths) dont_indices) # __ , dont_indices
    enabled =: do_map > dont_map
    result2 =: +/ ((match_indices mul_matches) { enabled) * mul_results