Advent of Code 2016 Day 7 (Javascript)

Previous:

Advent of Code 2016 – Day 6 (Julia)
Advent of Code 2016 – Day 5( Java 8)

Advent of Code 2016 – Day 4 (Perl 6)

Advent of Code 2016 – Day 3 (Clojure)
Advent of Code – Day 2 (Python 3)
Advent Of Code 2016 – Day 1(Haskell)

Day 7

Start: 12/7/2016

Finish 12/8/2016

Language: Javascript

SPOILER ALERT: If you have any inkling, any whatsoever, to work on the Advent of Code…. DO NOT READ THIS BLOG POST.  DO NOT LOOK AT MY GITHUB PROJECT.  It is no fun if you’re not solving it yourself, and you’ll feel so much better about yourself if you can figure it out without looking up an answer.  This blog post is not to give away the answer, but instead, is there for people to learn from.

As always, the following code is in my GitHub: https://github.com/pviafore/AdventOfCode2016

The Challenge

This time around, the goal was to take strings that were  sequences of characters, with some enclosed in square brackets, like so: ioxxoj[asdfgh]zxcvbn.

With those strings, we had to find ones where an ABBA pattern existed outside of the square bracketed enclosed sequence (it could be any two letters, not just A and B, but they had to be different).  It also could not have an ABBA sequence insidde the square bracket enclosed sequence.

I figured out I could use Javascript and regexes for this one, especially after learning about backreferences to solve http://jimbly.github.io/regex-crossword/.  Let’s look at the code:


const fs = require('fs')

function hasABBA(str){
    return str.match(/(\S)((?!\1).)\2\1/);
}

function splitOutSections(str){
    return str.split(/\[.*?\]/)
}

function getHypertext(str){
    return str.match(/\[(.*?)\]/g)
}

function isValid(str){
    return splitOutSections(str).some(hasABBA) &&
           getHypertext(str).every((str) => !hasABBA(str));

}

lines = fs.readFileSync("../day7.txt", "utf8").split("\n");
console.log(lines.filter(isValid).length);

This is pretty short.  I had a misstep with the regex, but a negative lookahead assertion helped me out.


function hasABBA(str){
    return str.match(/(\S)((?!\1).)\2\1/);
}

Then it was simple to split out what was in square brackets (Called “hypertext” in our example):


function isValid(str){
    return splitOutSections(str).some(hasABBA) &&
           getHypertext(str).every((str) => !hasABBA(str));

}

 

And that was really it to it.

 

 

Part 2

So now, the goal was to find an ABA sequence outside of the hypertext with a BAB in the hypertext.  I thought I could use a regular expression as well, but I could not get it to match a string like ABACA to match.  Instead, I had to write a normal for loop to do it.  (I even messed this up because I forgot about some of the global variable scoping in Javascript).

Let’s look at what was needed :


function isABA(substring) {
   
    return substring[0] === substring[2] && substring[1] !== substring[0]
}
function getABA(str){
    var abas = []
    for(let i = 0; i < str.length; i++){
        const substring = str.substring(i, i+3);
        if (substring.length == 3 && isABA(substring)) {
            abas.push(substring);
        } 
    }
    return abas;
}

I also had to change out the isValid function to check these.  Here, I get each section, get the ABA’s out of them, take out any empty strings and reduce the ABA sections to one list.  Then its a simple check to see if any of the ABA sequences are represented in BAB sections



function flip(str){
    return str[1] + str[0] + str[1];
}

function isValid(str){
    var abas = splitOutSections(str).map(getABA)
                                .filter((x) => {return x;})
                                .reduce((a,b) => { return a.concat(b)}, []);
    var babs = getHypertext(str).map(getABA)
                            .filter((x) => {return x;})
                            .reduce((a,b) => { return a.concat(b)}, []);

    return abas.some((aba) => {return babs.includes(flip(aba));});
}

 

Wrap-up

I had quite a few missteps in here.  I understood the Javascript part, but the Regexes fooled me a bit, and I should have really tested against the known input.  Overall I give myself a B-.  I did the first half great, but the second one had stupid mistakes in them, and I took too long to do it.

Next up, I’m going to use C++ to work on Day 8. Let’s hope it goes a lot better than this time around.