Problem difficulty so far (up to day 16)

  1. Day 15 - Warehouse Woes: 30m00s
  2. Day 12 - Garden Groups: 17m42s
  3. Day 14 - Restroom Redoubt: 15m48s
  4. Day 09 - Disk Fragmenter: 14m05s
  5. Day 16 - Reindeer Maze: 13m47s
  6. Day 13 - Claw Contraption: 11m04s
  7. Day 06 - Guard Gallivant: 08m53s
  8. Day 08 - Resonant Collinearity: 07m12s
  9. Day 11 - Plutonian Pebbles: 06m24s
  10. Day 04 - Ceres Search: 05m41s
  11. Day 02 - Red Nosed Reports: 04m42s
  12. Day 10 - Hoof It: 04m14s
  13. Day 07 - Bridge Repair: 03m47s
  14. Day 05 - Print Queue: 03m43s
  15. Day 03 - Mull It Over: 03m22s
  16. Day 01 - Historian Hysteria: 02m31s
  • zogwarg@awful.systems
    link
    fedilink
    English
    arrow-up
    1
    ·
    edit-2
    5 hours ago
    Hacky Manual parallelization

    22-b.jq

    Massive time gains with parallelization + optimized next function (2x speedup) by doing the 3 xor operation in “one operation”, Maybe I prefer the grids ^^:

    #!/usr/bin/env jq -n -f
    
    #────────────────── Big-endian to_bits ───────────────────#
    def to_bits:
      if . == 0 then [0] else { a: ., b: [] } | until (.a == 0;
          .a /= 2 |
          if .a == (.a|floor) then .b += [0]
                              else .b += [1] end | .a |= floor
      ) | .b end;
    #────────────────── Big-endian from_bits ────────────────────────#
    def from_bits: [ range(length) as $i | .[$i] * pow(2; $i) ] | add;
    
    ( # Get index that contribute to next xor operation.
      def xor_index(a;b): [a, b] | transpose | map(add);
      [ range(24) | [.] ]
      | xor_index([range(6) | [-1]] + .[0:18] ; .[0:24])
      | xor_index(.[5:29] ; .[0:24])
      | xor_index([range(11) | [-1]] + .[0:13]; .[0:24])
      | map(
          sort | . as $indices | map(
            select( . as $i |
              $i >= 0 and ($indices|indices($i)|length) % 2 == 1
            )
          )
        )
    ) as $next_ind |
    
    # Optimized Next, doing XOR of indices simultaneously a 2x speedup #
    def next: . as $in | $next_ind | map( [ $in[.[]] // 0 ] | add % 2 );
    
    #  Still slow, because of from_bits  #
    def to_price($p): $p | from_bits % 10;
    
    # Option to run in parallel using xargs, Eg:
    #
    # seq 0 9 | \
    # xargs -P 10 -n 1 -I {} bash -c './2024/jq/22-b.jq input.txt \
    # --argjson s 10 --argjson i {} > out-{}.json'
    # cat out-*.json | ./2024/jq/22-b.jq --argjson group true
    # rm out-*.json
    #
    # Speedup from naive ~50m -> ~1m
    def parallel: if $ARGS.named.s and $ARGS.named.i  then
       select(.key % $ARGS.named.s == $ARGS.named.i)  else . end;
    
    #════════════════════════════ X-GROUP ═══════════════════════════════#
    if $ARGS.named.group then
    
    # Group results from parallel run #
    reduce inputs as $dic ({}; reduce (
          $dic|to_entries[]
      ) as {key: $k, value: $v} (.; .[$k] += $v )
    )
    
    else
    
    #════════════════════════════ X-BATCH ═══════════════════════════════#
    reduce (
      [ inputs ] | to_entries[] | parallel
    ) as { value: $in } ({};  debug($in) |
      reduce range(2000) as $_ (
        .curr = ($in|to_bits) | .p = to_price(.curr) | .d = [];
        .curr |= next | to_price(.curr) as $p
        | .d = (.d+[$p-.p])[-4:]  | .p = $p # Four differences to price
        | if .a["\($in)"]["\(.d)"]|not then # Record first price
             .a["\($in)"]["\(.d)"] = $p end # For input x 4_diff
      )
    )
    
    # Summarize expected bananas per 4_diff sequence #
    | [ .a[] | to_entries[] ]
    | group_by(.key)
    | map({key: .[0].key, value: ([.[].value]|add)})
    | from_entries
    
    end |
    
    #═══════════════════════════ X-FINALLY ══════════════════════════════#
    if $ARGS.named.s | not then
    
    #     Output maximum expexted bananas      #
    to_entries | max_by(.value) | debug | .value
    
    end