git

My personal website source code
Log | Files | Refs | Submodules | README | LICENSE

zet-5-aoc-2021-04.md (4000B)


      1 ---
      2 title: 'Zettelkasten #5: Solution in D for Advent of Code 2021, Day 4'
      3 date: '2021-12-17T22:04:00+01:00'
      4 tags: ['zettelkasten', 'zet', 'dlang', 'aoc', 'aoc2021', 'adventofcode']
      5 description: "This post describes my solution in the D programming language for
      6 the 4th puzzle of the Advent of Code 2021."
      7 ---
      8 
      9 ## The challenge
     10 
     11 > You're already almost 1.5km (almost a mile) below the surface of the ocean,
     12 > already so deep that you can't see any sunlight. What you can see, however,
     13 > is a giant squid that has attached itself to the outside of your submarine.
     14 >
     15 > Maybe it wants to play bingo?
     16 >
     17 > Bingo is played on a set of boards each consisting of a 5x5 grid of numbers.
     18 > Numbers are chosen at random, and the chosen number is marked on all boards
     19 > on which it appears. (Numbers may not appear on all boards.) If all numbers
     20 > in any row or any column of a board are marked, that board wins. (Diagonals
     21 > don't count.)
     22 >
     23 > [...]
     24 >
     25 > To guarantee victory against the giant squid, figure out which board will win
     26 > first. What will your final score be if you choose that board?
     27 
     28 You can read the challenge more in depth,
     29 [here](https://adventofcode.com/2021/day/4).
     30 
     31 ## Part 1
     32 
     33 ### Full solution
     34 
     35 ```d
     36 auto input = [stdin.byLineCopy().array].map!(a => [                         // input
     37     a.front.splitter(",").map!(to!long).array,                              // parse numbers
     38     a[1..$].map!`a.splitter(" ").filter!"!a.empty".map!(to!long)`           // parse cards
     39     .joiner.array]).front;
     40 immutable ncards = input[1].length / 25;                                    // calc number of cards
     41 foreach(pos, i; input[0]) foreach(c; 0..ncards) {                           // for each number & card
     42     foreach(n; 0..25) if(input[1][c*25 + n] == i) input[1][c*25 + n] = -1;  // set matching numbers
     43     auto e = evenChunks(input[1][c*25..c*25+25],5).array;                   // construct card RoR
     44     foreach(el; zip(e, e.dup.transposed)) if(findSkip(el[0], repeat(-1L,5)) // find row
     45             || findSkip(el[1], repeat(-1L,5))) {                            // find column
     46         writeln(input[1][c*25..c*25+25].filter!"a != -1".sum * i);          // calculate result
     47         return;                                                             // hang
     48     }
     49 }
     50 ```
     51 
     52 ## Part 2
     53 
     54 > On the other hand, it might be wise to try a different strategy: let the
     55 > giant squid win.
     56 >
     57 > You aren't sure how many bingo boards a giant squid could play at once, so
     58 > rather than waste time counting its arms, the safe thing to do is to figure
     59 > out which board will win last and choose that one. That way, no matter which
     60 > boards it picks, it will win for sure.
     61 >
     62 > [...]
     63 >
     64 > Figure out which board will win last. Once it wins, what would its final
     65 > score be?
     66 
     67 ### Full solution
     68 
     69 ```d
     70 auto input = [stdin.byLineCopy().array].map!(a => [                         // input
     71     a.front.splitter(",").map!(to!long).array,                              // parse numbers
     72     a[1..$].map!`a.splitter(" ").filter!"!a.empty".map!(to!long)`           // parse cards
     73     .joiner.array]).front;
     74 immutable ncards = input[1].length / 25;                                    // calc number of cards
     75 bool[] winners = new bool[ncards];
     76 foreach(pos, i; input[0]) foreach(c; 0..ncards) {                           // for each number & card
     77     foreach(n; 0..25) if(input[1][c*25 + n] == i) input[1][c*25 + n] = -1;  // set matching numbers
     78     auto e = evenChunks(input[1][c*25..c*25+25],5).array;                   // construct card RoR
     79     foreach(el; zip(e, e.dup.transposed)) if(findSkip(el[0], repeat(-1L,5)) // find row
     80             || findSkip(el[1], repeat(-1L,5))) {                            // find column
     81         winners[c] = true; if(winners.all) {                                // fill winners list & check
     82             writeln(input[1][c*25..c*25+25].filter!"a != -1".sum * i);      // calculate result
     83             return;                                                         // hang
     84         }
     85     }
     86 }
     87 ```