Advent of Code 2022 - Day 13: Distress Signal Solution

Handle conditional statements carefully

Part 1

Three cases:

  • all is number
  • all is array
  • one is array

For each case, there are 3 possibilities of

true, false, undetermined
. But in the end there is only
true, false
. So keep in mind about that

Implementation

1const fs = require("fs")
2
3const readData = () => {
4 const data = fs
5 .readFileSync("./input", "utf-8")
6 .split(/\r?\n\r?\n/)
7 .map(line => line.split(/\r?\n/).map(part => JSON.parse(part)))
8
9 return data
10}
11
12const main = () => {
13 const pairs = readData()
14
15 const compare = ([left, right]) => {
16 if ([left, right].every(Number.isInteger)) {
17 if (left < right) return true
18 if (left > right) return false
19 return
20 }
21
22 if ([left, right].every(Array.isArray)) {
23 for (let i = 0; i < Math.min(left.length, right.length); i++) {
24 const res = compare([left[i], right[i]])
25 if (res != null) return res
26 }
27
28 return compare([left.length, right.length])
29 }
30
31 return compare([[left].flat(), [right].flat()])
32 }
33
34 const res = pairs.reduce(
35 (acc, el, index) => acc + (compare(el) ? index + 1 : 0),
36 0
37 )
38
39 console.log(res)
40}
41
42main()

Part 2

Flatten the

pairs
, add 2 dividers and sort the list of packets ascending

Implementation

1const fs = require("fs")
2
3const readData = () => {
4 const data = fs
5 .readFileSync("./input", "utf-8")
6 .split(/\r?\n\r?\n/)
7 .map(line => line.split(/\r?\n/).map(part => JSON.parse(part)))
8
9 return data
10}
11
12const main = () => {
13 const pairs = readData()
14
15 const compare = ([left, right]) => {
16 if ([left, right].every(Number.isInteger)) {
17 if (left < right) return true
18 if (left > right) return false
19 return
20 }
21
22 if ([left, right].every(Array.isArray)) {
23 for (let i = 0; i < Math.min(left.length, right.length); i++) {
24 const res = compare([left[i], right[i]])
25 if (res != null) return res
26 }
27
28 return compare([left.length, right.length])
29 }
30
31 return compare([[left].flat(), [right].flat()])
32 }
33
34 const dividers = [[[2]], [[6]]]
35
36 const res = [...pairs.flat(), ...dividers]
37 .sort((left, right) => compare([right, left]) - compare([left, right]))
38 .reduce(
39 (acc, el, index) => (dividers.includes(el) ? acc * (index + 1) : acc),
40 1
41 )
42
43 console.log(res)
44}
45
46main()

Trick

For the case that one of left or right is an array, instead of using ternary operator like

1Number.isInteger(left) ? compare([[left], right]) : compare([left, [right]])

we could make use of

.flat

1compare([[left].flat(), [right].flat()])

References

Original problem

Array.prototype.flat()

Comments

Loading comments...

Tags

adventofcode

recursion

sorting

Next Post

Advent of Code 2022 - Day 14: Regolith Reservoir

Dec 14, 2022

Move and tackle obstacles

HoningJS

Search Posts