Solving this seems simple:
Parse the input into two equal lists of numbers Sort each list in ascending order Compare both values at each index Determine the absolute value after calculating the difference Increment a tally by the absolute value
First, I'll make a list of 2-item lists where each item is a number:
input.split('\n').split(' ').map(Number)
Then, I'll extract the items into separate lists based on their index:
let [list1, list2] = [ input.map((_,i) => i == 0), input.map((_,i) => i == 1) ]
First mistake: chaining split.
I can't call split on an array.
I have to split inside an iterating method, like map:
input.split("\n").map(...);
Second mistake: not enough spaces.
The input contains several spaces between each number, not one:
input.split("\n").map((el) => el.split(" ").map(Number));
Third mistake: overthinking list access.
My code acted as if each nested list was one element, and returned boolean values based on whether the element was first or second in the list.
What???!!!
This code recognizes each list and keeps the first or second item:
let [list1, list2] = [ input.map(list => list[0]), input.map(list => list[1]), ];
Alas, my algorithm now generates two lists of numbers!
Whew, I got a little rusty not having done these for ten months.
This should be short and sweet.
In fact, I'll just append to the code directly above:
let [list1, list2] = [ input.map(list => list[0]).sort((a,b) => a - b), input.map(list => list[1]).sort((a,b) => a - b), ];
Worked like a charm on the example input:
[ 1, 2, 3, 3, 3, 4 ] [ 3, 3, 3, 4, 5, 9 ]
let answer = 0; for (let i = 0; i < list1.length; i++) { answer += Math.abs(list1[i] - list2[i]); }
It works on the example: 11
Will it work on my puzzle input, though?
It does!
Woohoo! One gold star!
The instructions would have me believe:
For each number in list 1 For each number in list 2 If there's a match Increment a tally by 1
That means list 2 will be checked list 2 length times list 1 length...times.
1000 items in each: 1 million checks
That's not bad. But that seems unnecessary.
All I care about are the counts of each number in list 2.
So, I can check all 1000 numbers once, and build up a map of numbers to their counts. Then, check that list 1000 times.
2000 < 1 million
I like this approach better. To the code!
The example list looks like:
4, 3, 5, 3, 9, 3
So I want an object that looks like:
{ 4: 1, 3: 3, 5: 1, 9: 1 }
With my list2 from my Part 1 algorithm, I need to perform a reduce to build this object:
let counts = list2.reduce((obj, num) => { if (!(num in obj)) { obj[num] = 1 } else { obj[num] += 1 } return obj }, {})
To my surprise, that snippet works exactly as expected!
I thought I forgot the correct syntax for num in obj, but that's it!
Another reduce with a condition checking for the existence and value associated with a number:
Parse the input into two equal lists of numbers Sort each list in ascending order Compare both values at each index Determine the absolute value after calculating the difference Increment a tally by the absolute value
I kept seeing the wrong score.
I kept wondering why.
I kept adding console.log() statements with more and more values to print.
I kept seeing values that I didn't expect.
Then, I saw it.
I was comparing to list2 and not my custom counts object!
Huge punch to the ego. But just what I needed on Day 1.
Here's the working code:
input.split('\n').split(' ').map(Number)
That generates the correct answer for the example input.
Let's hope it does the same for my puzzle input.
And hopefully it runs lightning fast!
It does!
Yeeeehawwww!!!
Two gold stars to kick things off.
Along with a few beginner mistakes that keep me grounded.
It's all why I love these puzzles.
Onward too Day 2!
The above is the detailed content of Historian Hysteria. For more information, please follow other related articles on the PHP Chinese website!