git

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

zet-3-aoc-2021-02.md (4440B)


      1 ---
      2 title: 'Zettelkasten #3: Solution in D for Advent of Code 2021, Day 2'
      3 date: '2021-12-02T19:02:00+01:00'
      4 tags: ['zettelkasten', 'zet', 'dlang', 'aoc', 'aoc2021', 'adventofcode']
      5 description: "This post describes, in detail, my solution in the D programming
      6 language for the 2nd puzzle of the Advent of Code 2021."
      7 ---
      8 
      9 ## The challenge
     10 
     11 > It seems like the submarine can take a series of commands like forward 1,
     12 > down 2, or up 3:
     13 >
     14 > - forward X increases the horizontal position by X units.
     15 > - down X increases the depth by X units.
     16 > - up X decreases the depth by X units.
     17 >
     18 > Note that since you're on a submarine, down and up affect your depth, and so
     19 > they have the opposite result of what you might expect.
     20 >
     21 > [...]
     22 >
     23 > Calculate the horizontal position and depth you would have after following
     24 > the planned course. What do you get if you multiply your final horizontal
     25 > position by your final depth?
     26 
     27 You can read the challenge more in depth,
     28 [here](https://adventofcode.com/2021/day/2).
     29 
     30 ## Part 1
     31 
     32 The idea here is to fold the values and increment or decrement fields,
     33 depending on the given operations. First, to efficiently recognize the
     34 operations, we can just compare the first byte, since they are unique (`f` for
     35 forward, `d` for down and `u` for up). A simple split and map can do the trick,
     36 easily:
     37 
     38 ```d
     39 auto parsed = input.map!split.map!"tuple(a.front[0], a.back.to!long)";
     40 ```
     41 
     42 To fold the values in D we can use `fold` template. We need seed the fold with a
     43 tuple or a static array, starting at zero. Inside the fold we write the logic
     44 to increment or decrement the accumulator, according to the given rules:
     45 
     46 ```d
     47 auto folded = parsed.fold!((a,b) {        // fold the parsed input
     48         b[0] == 'f' ? a[0] += b[1]        // increment on forward
     49         : b[0] == 'd' ? a[1] += b[1]      // increment on down
     50         : b[0] == 'u' ? a[1] -= b[1] : 0; // decrement on up
     51         return a; })(tuple(0L,0L));       // seed it with zeros
     52 ```
     53 
     54 And that's it, now you just need to multiply the result of the fold:
     55 
     56 ```d
     57 auto res = folded[0] * folded[1];
     58 ```
     59 
     60 ### Full solution
     61 
     62 ```d
     63 [stdin.byLine().map!split.map!"tuple(a.front[0], a.back.to!long)" // parse input
     64     .fold!((a,b) {                                                // fold the input
     65         b[0] == 'f' ? a[0] += b[1]                                // increment on forward
     66         : b[0] == 'd' ? a[1] += b[1]                              // increment on down
     67         : b[0] == 'u' ? a[1] -= b[1] : 0;                         // decrement on up
     68         return a; })(tuple(0L,0L))]                               // seed with zeros
     69     .map!"a[0] * a[1]".front.writeln;                             // multiply result
     70 ```
     71 
     72 ## Part 2
     73 
     74 > Based on your calculations, the planned course doesn't seem to make any
     75 > sense. You find the submarine manual and discover that the process is
     76 > actually slightly more complicated.
     77 >
     78 > In addition to horizontal position and depth, you'll also need to track a
     79 > third value, aim, which also starts at 0. The commands also mean something
     80 > entirely different than you first thought:
     81 >
     82 > - down X increases your aim by X units.
     83 > - up X decreases your aim by X units.
     84 > - forward X does two things:
     85 >     * It increases your horizontal position by X units.
     86 >     * It increases your depth by your aim multiplied by X.
     87 >
     88 > [...]
     89 >
     90 > Using this new interpretation of the commands, calculate the horizontal
     91 > position and depth you would have after following the planned course. What do
     92 > you get if you multiply your final horizontal position by your final depth?
     93 
     94 
     95 The second part is pretty much the same as part one, except it uses an
     96 additional value in the fold and diffferent rules.
     97 
     98 ### Full solution
     99 
    100 ```d
    101 [stdin.byLine().map!split.map!"tuple(a.front[0], a.back.to!long)" // parse input
    102     .fold!((a,b) {                                                // fold the input
    103         b[0] == 'f' ? a[0] += b[1] : 0;                           // increment on forward
    104         b[0] == 'f' ? a[1] += a[2] * b[1]                         // multiply w/ aim on forward
    105         : b[0] == 'd' ? a[2] += b[1]                              // increment aim on down
    106         : b[0] == 'u' ? a[2] -= b[1] : 0;                         // decrement aim on up
    107         return a; })(tuple(0L,0L,0L))]                            // seed with zeros
    108     .map!"a[0] * a[1]".front.writeln;                             // multiply result
    109 ```