Advent of Code 2022 - Day 20: Grove Positioning System Solution

Handling indexes with care

Part 1

Trick here is to wrap each element into an array so that we could make use of reference. Hence, we could freely swap elements but still be able to keep track of original ones

For moving elements, case of positive value, new place's index is original one plus the value itself. To handle overflow, simply modulo the length of the array

Case of negative value is the same, we only have to reverse the array, do the move like the case of positive value, and reverse back

Implementation

1const fs = require("fs")
2
3const readData = () => {
4 const data = fs.readFileSync("./input", "utf-8").split(/\r?\n/).map(Number)
5
6 return data
7}
8
9const main = () => {
10 const data = readData()
11
12 const mix = arr => {
13 const arrLength = arr.length
14 const refs = arr.map(val => [val])
15 const original = [...refs]
16
17 for (const currentRef of original) {
18 const value = currentRef[0]
19 const isNegative = value < 0
20 if (isNegative) refs.reverse()
21 const currentIndex = refs.findIndex(ref => ref === currentRef)
22 const newIndex = (currentIndex + Math.abs(value)) % (arrLength - 1)
23 refs.splice(currentIndex, 1)
24 refs.splice(newIndex, 0, currentRef)
25 if (isNegative) refs.reverse()
26 }
27
28 return refs.flat()
29 }
30
31 const findValueAt = (index, arr) => {
32 const arrLength = arr.length
33 const indexOfZero = arr.findIndex(val => val === 0)
34 index = (indexOfZero + index) % arrLength
35 return arr[index]
36 }
37
38 const mixedData = mix(data)
39
40 const res = [1000, 2000, 3000]
41 .map(index => findValueAt(index, mixedData))
42 .reduce((acc, el) => acc + el, 0)
43
44 console.log(res)
45}
46
47main()

Part 2

Like part 1, but add decryptionKey and times

Implementation

1const fs = require("fs")
2
3const readData = () => {
4 const data = fs.readFileSync("./input", "utf-8").split(/\r?\n/).map(Number)
5
6 return data
7}
8
9const main = () => {
10 const data = readData()
11
12 const mix = ({ arr, decryptionKey = 1, times = 1 }) => {
13 const arrLength = arr.length
14 const refs = arr.map(val => [val * decryptionKey])
15 const original = [...refs]
16
17 while (times--) {
18 for (const currentRef of original) {
19 const value = currentRef[0]
20 const isNegative = value < 0
21 if (isNegative) refs.reverse()
22 const currentIndex = refs.findIndex(ref => ref === currentRef)
23 const newIndex = (currentIndex + Math.abs(value)) % (arrLength - 1)
24 refs.splice(currentIndex, 1)
25 refs.splice(newIndex, 0, currentRef)
26 if (isNegative) refs.reverse()
27 }
28 }
29
30 return refs.flat()
31 }
32
33 const findValueAt = (index, arr) => {
34 const arrLength = arr.length
35 const indexOfZero = arr.findIndex(val => val === 0)
36 index = (indexOfZero + index) % arrLength
37 return arr[index]
38 }
39
40 const mixedData = mix({ arr: data, decryptionKey: 811589153, times: 10 })
41
42 const res = [1000, 2000, 3000]
43 .map(index => findValueAt(index, mixedData))
44 .reduce((acc, el) => acc + el, 0)
45
46 console.log(res)
47}
48
49main()

References

Original problem

Comments

Loading comments...

Tags

adventofcode

array

Next Post

Advent of Code 2022 - Day 16: Proboscidea Volcanium

Floyd-Warshal and bitmask

Previous Post

Advent of Code 2022 - Day 18: Boiling Boulders

Flooding with breadth-first search

HoningJS

Search Posts