DEV Community

Cover image for Matchsticks
Robert Mion
Robert Mion

Posted on

Matchsticks

Advent of Code 2015 Day 8

Part 1

  1. An escape room, eh?
  2. reduce(), replaceAll() and eval() for the win!

An escape room, eh?

  • Strings full of escaped characters
  • Gotta process 'em all
  • And compare raw length to processed length

reduce(), replaceAll() and eval() for the win!

Counting the characters in the raw text is simple enough:

  • The input file is one long string containing all the characters
  • I just need to remove newline characters
input.replaceAll('\n','').length
Enter fullscreen mode Exit fullscreen mode

Counting the in-memory characters is easy with eval():

  • Any string
  • When passed into eval()
  • Takes on it's in-memory form

So, a string like "aaa\"aaa"...

...after being evaluated like this:

eval("aaa\"aaa")
Enter fullscreen mode Exit fullscreen mode

...becomes aaa"aaa

From there, I just need it's length.

When wrapped inside a reduce(), my in-memory character counting algorithm in JavaScript looks like this:

input.split('\n')
  .reduce(
    (sum, str) => sum += eval(str).length
  , 0)
Enter fullscreen mode Exit fullscreen mode

After subtracting the latter sum from the former sum, I generated the correct answer!

Part 2

  1. Enter: regex and math

Enter: regex and math

  • regex to count all occurrences of \ and " in each string
  • Math to calculate each encoded strings total character count

The regex looks like this:

/\\|\"/g
Enter fullscreen mode Exit fullscreen mode
  • \\ matches all backslash characters
  • | matches either one
  • \" matches all double-quote characters

The math looks like this:

Set specials to the count of all \ and " characters
Set others to the difference between all characters and specials
Set total to 2 + others + specials times 2
Enter fullscreen mode Exit fullscreen mode
  • The additional 2 accounts for the appended enclosing double-quotes

An example:

"aaa\"aaa"

specials = ",\,"," -> 4
others = a,a,a,a,a,a -> 6
total = 2 + 6 + (4 * 2) => 16
Enter fullscreen mode Exit fullscreen mode

When wrapped inside a reduce(), my encoded character counting algorithm in JavaScript looks like this:

input.split('\n')
  .reduce(
    (sum, str) => {
      let specials = [...str.matchAll(/\\|\"/g)].length
      let others = str.length - specials
      return sum + 2 + others + specials * 2
    }
  , 0)
Enter fullscreen mode Exit fullscreen mode

After subtracting the new sum from the original sum, I generated the correct answer!

My full algorithm for both parts in JavaScript:

let codeChars = input.replaceAll('\n','').length
let memoryChars = input.split('\n')
  .reduce(
    (sum, str) => sum += eval(str).length
  , 0)
let encodedChars = input.split('\n')
  .reduce(
    (sum, str) => {
      let extra = [...str.matchAll(/\\|\"/g)].length
      let others = str.length - extra
      return sum + 2 + others + extra * 2
    }
  , 0)
console.log("Part 1", codeChars - memoryChars)
console.log("Part 2", encodedChars - codeChars)
Enter fullscreen mode Exit fullscreen mode

My algorithm, animated:
Animation of algorithm

I did it!!

  • I solved both parts!
  • Using reduce(), regex, replaceAll(), eval(), and a little arithmetic!

That felt like a softball puzzle.

Though, it is the first year of the series and I'm into the first 10 Days.

Here's to hoping it's two-star-earning days thru to the end!

Top comments (0)