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 ```