Thursday, December 27, 2018

Advent of Code 2015 - Day 23: Opening the Turing Lock

Part 1

Description

Little Jane Marie just got her very first computer for Christmas from some unknown benefactor. It comes with instructions and an example program, but the computer itself seems to be malfunctioning. She's curious what the program does, and would like you to help her run it.
The manual explains that the computer supports two registers and six instructions (truly, it goes on to remind the reader, a state-of-the-art technology). The registers are named a and b, can hold any non-negative integer, and begin with a value of 0. The instructions are as follows:
  • hlf r sets register r to half its current value, then continues with the next instruction.
  • tpl r sets register r to triple its current value, then continues with the next instruction.
  • inc r increments register r, adding 1 to it, then continues with the next instruction.
  • jmp offset is a jump; it continues with the instruction offset away relative to itself.
  • jie r, offset is like jmp, but only jumps if register r is even ("jump if even").
  • jio r, offset is like jmp, but only jumps if register r is 1 ("jump if one", not odd).
All three jump instructions work with an offset relative to that instruction. The offset is always written with a prefix + or - to indicate the direction of the jump (forward or backward, respectively). For example, jmp +1 would simply continue with the next instruction, while jmp +0 would continuously jump back to itself forever.
The program exits when it tries to run an instruction beyond the ones defined.
For example, this program sets a to 2, because the jio instruction causes it to skip the tpl instruction:
inc a
jio a, +2
tpl a
inc a
What is the value in register b when the program in your puzzle input is finished executing?

Input


Solution

This problem involves a sequence known as look and say sequence. And I found a ready to use VBA code here. I modified a bit into this:

Sub LookAndSay()
Dim s, news, curdigit, newdigit As String
Dim curlength, p, L As Long
 
ActiveSheet.Range("a4").Select
s = Selection.Value
For i = 1 To 40
  L = Len(s)
  p = 1
  curdigit = Left$(s, 1)
  curlength = 1
  news = ""
  For p = 2 To L
    newdigit = Mid$(s, p, 1)
    If curdigit = newdigit Then
      curlength = curlength + 1
    Else
      news = news & CStr(curlength) & curdigit
      curdigit = newdigit
      curlength = 1
    End If
  Next p
  news = news & CStr(curlength) & curdigit
  Debug.Print news
  s = news
  ActiveCell.Offset(1, 0).Select
  ActiveCell.Value = Len(s)
Next i
Exit Sub
End Sub

I modified the code so it will accommodate larger number (I change Integer into Long) and read input from and write output into the sheet. Then all I need is running the code and wait for the result.

Part 2

Description

Neat, right? You might also enjoy hearing John Conway talking about this sequence (that's Conway of Conway's Game of Life fame).
Now, starting again with the digits in your puzzle input, apply this process 50 times. What is the length of the new result?

Solution

For the part 2, I just need to modify the code to run 50 times.

Share:

Wednesday, December 26, 2018

Advent of Code 2015 - Day 18: Like a GIF For Your Yard

Part 1

Description

After the million lights incident, the fire code has gotten stricter: now, at most ten thousand lights are allowed. You arrange them in a 100x100 grid.
Never one to let you down, Santa again mails you instructions on the ideal lighting configuration. With so few lights, he says, you'll have to resort to animation.
Start by setting your lights to the included initial configuration (your puzzle input). A # means "on", and a . means "off".
Then, animate your grid in steps, where each step decides the next configuration based on the current one. Each light's next state (either on or off) depends on its current state and the current states of the eight lights adjacent to it (including diagonals). Lights on the edge of the grid might have fewer than eight neighbors; the missing ones always count as "off".
For example, in a simplified 6x6 grid, the light marked A has the neighbors numbered 1 through 8, and the light marked B, which is on an edge, only has the neighbors marked 1 through 5:
1B5...
234...
......
..123.
..8A4.
..765.
The state a light should have next is based on its current state (on or off) plus the number of neighbors that are on:
  • A light which is on stays on when 2 or 3 neighbors are on, and turns off otherwise.
  • A light which is off turns on if exactly 3 neighbors are on, and stays off otherwise.
All of the lights update simultaneously; they all consider the same current state before moving to the next.
Here's a few steps from an example configuration of another 6x6 grid:
Initial state:
.#.#.#
...##.
#....#
..#...
#.#..#
####..

After 1 step:
..##..
..##.#
...##.
......
#.....
#.##..

After 2 steps:
..###.
......
..###.
......
.#....
.#....

After 3 steps:
...#..
......
...#..
..##..
......
......

After 4 steps:
......
......
..##..
..##..
......
......
After 4 steps, this example has four lights on.
In your grid of 100×100 lights, given your initial configuration, how many lights are on after 100 steps?

Input


Solution

In order to simplify calculation, I decided to replace # with 1 and . with 0. Then, I pasted those input into a 100×100 grid square in Excel. Next, I generated 100 100×100 grid squares, each of which representing each step. In the end, I counted the sum of the numbers in the last square (the numbers of lights that are on). Here is my Excel sheet:


In CZ4, my formula is:

=IF(B4=1,IF(OR(SUM(A3:C5)=3,SUM(A3:C5)=4),1,0),IF(SUM(A3:C5)=3,1,0))

I had to modified the sum conditions for the first if (when the lights are on) to be either 4 or 3 because they include the middle number (which is 1).

Part 2

Description

You flip the instructions over; Santa goes on to point out that this is all just an implementation of Conway's Game of Life. At least, it was, until you notice that something's wrong with the grid of lights you bought: four lights, one in each corner, are stuck on and can't be turned off. The example above will actually run like this:
Initial state:
##.#.#
...##.
#....#
..#...
#.#..#
####.#

After 1 step:
#.##.#
####.#
...##.
......
#...#.
#.####

After 2 steps:
#..#.#
#....#
.#.##.
...##.
.#..##
##.###

After 3 steps:
#...##
####.#
..##.#
......
##....
####.#

After 4 steps:
#.####
#....#
...#..
.##...
#.....
#.#..#

After 5 steps:
##.###
.##..#
.##...
.##...
#.#...
##...#
After 5 steps, this example now has 17 lights on.
In your grid of 100x100 lights, given your initial configuration, but with the four corners always in the on state, how many lights are on after 100 steps?

Solution

For the part 2, I had to change the number in the four corners in my initial configuration (because not all of them are # or 1). Then, in a new sheet, I pasted those input numbers. Next, similarly, I generated 100 100×100 grid squares. I changed the formula into

=IF(OR(AND(ISBLANK(A1),ISBLANK(B1),ISBLANK(A2)),AND(ISBLANK(B1),ISBLANK(C1),ISBLANK(C2)),AND(ISBLANK(A2),ISBLANK(A3),ISBLANK(B3)),AND(ISBLANK(C2),ISBLANK(B3),ISBLANK(C3))),1,IF(B2=1,IF(OR(SUM(A1:C3)=4,SUM(A1:C3)=3),1,0),IF(SUM(A1:C3)=3,1,0)))

so that it will detect if the corresponding cell is a corner or not, and set the value to 1 if it is.
Share:

Advent of Code 2015 - Day 17: No Such Thing as Too Much

Part 1

Description

The elves bought too much eggnog again - 150 liters this time. To fit it all into your refrigerator, you'll need to move it into smaller containers. You take an inventory of the capacities of the available containers.
For example, suppose you have containers of size 20, 15, 10, 5, and 5 liters. If you need to store 25 liters, there are four ways to do it:
  • 15 and 10
  • 20 and 5 (the first 5)
  • 20 and 5 (the second 5)
  • 15, 5, and 5
Filling all containers entirely, how many different combinations of containers can exactly fit all 150 liters of eggnog?

Input


Solution

For this problem, I decided to put all possible combinations and filtered them out. And, since there are 20 containers (my input), there are 2^20 = 1048576 possible combinations. Here is my Excel sheet:


I put this formula in AO1:

=SUMPRODUCT(U1:AN1,A$3:T$3)

and the similar formula for the rest of the cells. For solution, I counted only cells with sum of 150.

Part 2

Description

While playing with all the containers in the kitchen, another load of eggnog arrives! The shipping and receiving department is requesting as many containers as you can spare.
Find the minimum number of containers that can exactly fit all 150 liters of eggnog. How many different ways can you fill that number of containers and still hold exactly 150 litres?
In the example above, the minimum number of containers was two. There were three ways to use that many containers, and so the answer there would be 3.

Solution

To find the solution for part 2, I put this formula in AP1:

=IF(AO1=150,SUM(U1:AN1),"")

and count the smallest number among them using:

=SMALL(AP:AP,1)

and finally, another formula to find how many times it appeared:

=COUNTIF(AP:AP,4)

Share:

Advent of Code 2015 - Day 16: Aunt Sue

Part 1

Description

Your Aunt Sue has given you a wonderful gift, and you'd like to send her a thank you card. However, there's a small problem: she signed it "From, Aunt Sue".
You have 500 Aunts named "Sue".
So, to avoid sending the card to the wrong person, you need to figure out which Aunt Sue (which you conveniently number 1 to 500, for sanity) gave you the gift. You open the present and, as luck would have it, good ol' Aunt Sue got you a My First Crime Scene Analysis Machine! Just what you wanted. Or needed, as the case may be.
The My First Crime Scene Analysis Machine (MFCSAM for short) can detect a few specific compounds in a given sample, as well as how many distinct kinds of those compounds there are. According to the instructions, these are what the MFCSAM can detect:
  • children, by human DNA age analysis.
  • cats. It doesn't differentiate individual breeds.
  • Several seemingly random breeds of dog: samoyeds, pomeranians, akitas, and vizslas.
  • goldfish. No other kinds of fish.
  • trees, all in one group.
  • cars, presumably by exhaust or gasoline or something.
  • perfumes, which is handy, since many of your Aunts Sue wear a few kinds.
In fact, many of your Aunts Sue have many of these. You put the wrapping from the gift into the MFCSAM. It beeps inquisitively at you a few times and then prints out a message on ticker tape:
children: 3
cats: 7
samoyeds: 2
pomeranians: 3
akitas: 0
vizslas: 0
goldfish: 5
trees: 3
cars: 2
perfumes: 1
You make a list of the things you can remember about each Aunt Sue. Things missing from your list aren't zero - you simply don't remember the value.
What is the number of the Sue that got you the gift?

Input


Solution

This problem can be solved without VBA and only using formulas. Here is my Excel sheet:

 

In A3:A12, are the detectable compounds. Detected values from sample are in the next column (B3:B12).I put my split input in E3:K502. My array formula in M3, for example, is

{=SUMPRODUCT(IF(F3=$A$3:$A$12,1,0),IF(G3=$B$3:$B$12,1,0))}

While in P3, i just simply added up the values in M3:O3. Next, to find the right Aunt Sue, I just had to find the one whose sum is 3.

Part 2

Description

As you're about to send the thank you note, something in the MFCSAM's instructions catches your eye. Apparently, it has an outdated retroencabulator, and so the output from the machine isn't exact values - some of them indicate ranges.
In particular, the cats and trees readings indicates that there are greater than that many (due to the unpredictable nuclear decay of cat dander and tree pollen), while the pomeranians and goldfish readings indicate that there are fewer than that many (due to the modial interaction of magnetoreluctance).
What is the number of the real Aunt Sue?

Solution

For the part 2, I just needed to add these operator nest to the detected values: > next to cats and trees, < next to pomeranians and goldfish. Then, modifying my formula into:


{=SUMPRODUCT(IF(F3=$A$3:$A$12,1,0),IF(NOT(ISERROR(FIND($C$3:$C$12,MID("<=>",2+SIGN(G3-$B$3:$B$12),1),1))),1,0))}

I get my expected result.
Share:

Advent of Code 2015 - Day 15: Science for Hungry People

Part 1

Description

Today, you set out on the task of perfecting your milk-dunking cookie recipe. All you have to do is find the right balance of ingredients.
Your recipe leaves room for exactly 100 teaspoons of ingredients. You make a list of the remaining ingredients you could use to finish the recipe (your puzzle input) and their properties per teaspoon:
  • capacity (how well it helps the cookie absorb milk)
  • durability (how well it keeps the cookie intact when full of milk)
  • flavor (how tasty it makes the cookie)
  • texture (how it improves the feel of the cookie)
  • calories (how many calories it adds to the cookie)
You can only measure ingredients in whole-teaspoon amounts accurately, and you have to be accurate so you can reproduce your results in the future. The total score of a cookie can be found by adding up each of the properties (negative totals become 0) and then multiplying together everything except calories.
For instance, suppose you have these two ingredients:
Butterscotch: capacity -1, durability -2, flavor 6, texture 3, calories 8
Cinnamon: capacity 2, durability 3, flavor -2, texture -1, calories 3
Then, choosing to use 44 teaspoons of butterscotch and 56 teaspoons of cinnamon (because the amounts of each ingredient must add up to 100) would result in a cookie with the following properties:
  • A capacity of 44*-1 + 56*2 = 68
  • A durability of 44*-2 + 56*3 = 80
  • A flavor of 44*6 + 56*-2 = 152
  • A texture of 44*3 + 56*-1 = 76
Multiplying these together (68 * 80 * 152 * 76, ignoring calories for now) results in a total score of 62842880, which happens to be the best score possible given these ingredients. If any properties had produced a negative total, it would have instead become zero, causing the whole score to multiply to zero.
Given the ingredients in your kitchen and their properties, what is the total score of the highest-scoring cookie you can make?

Input


Solution

At first, I thought of using VBA. But then, there is way solving this without involving VBA. So, Here is my Excel sheet:


As usual, I split the input into each property: capacity, durability, flavor, texture and calories. Next, I generate all possible combinations of the amount of the four ingredients, from 0 teaspoon to 100. So, there will be 101 numbers in the combination. Actually, I can just omit the 0, because it will make the score (and also the total score) 0. But, I decided to do it anyway. According to my calculation, the number of the combinations is governed by Tetrahedral number. So in our case, it will be (101×102×103)/3! = 176851. All I need to do is then multiplying those numbers (amounts with their properties) and multiply them up, with the exception of negative number, which I replaced with 0. Then, I need only to find the largest product. I don't think I need to tell what formula to use.

Part 2

Description

Your cookie recipe becomes wildly popular! Someone asks if you can make another recipe that has exactly 500 calories per cookie (so they can use it as a meal replacement). Keep the rest of your award-winning process the same (100 teaspoons, same ingredients, same scoring system).
For example, given the ingredients above, if you had instead selected 40 teaspoons of butterscotch and 60 teaspoons of cinnamon (which still adds to 100), the total calorie count would be 40*8 + 60*3 = 500. The total score would go down, though: only 57600000, the best you can do in such trying circumstances.
Given the ingredients in your kitchen and their properties, what is the total score of the highest-scoring cookie you can make with a calorie total of 500?

Solution

For the part 2, I just need to filter out the total scores that has calorie score of 500.

Share:

Advent of Code 2015 - Day 14: Reindeer Olympics

Part 1

Description

This year is the Reindeer Olympics! Reindeer can fly at high speeds, but must rest occasionally to recover their energy. Santa would like to know which of his reindeer is fastest, and so he has them race.
Reindeer can only either be flying (always at their top speed) or resting (not moving at all), and always spend whole seconds in either state.
For example, suppose you have the following Reindeer:
  • Comet can fly 14 km/s for 10 seconds, but then must rest for 127 seconds.
  • Dancer can fly 16 km/s for 11 seconds, but then must rest for 162 seconds.
After one second, Comet has gone 14 km, while Dancer has gone 16 km. After ten seconds, Comet has gone 140 km, while Dancer has gone 160 km. On the eleventh second, Comet begins resting (staying at 140 km), and Dancer continues on for a total distance of 176 km. On the 12th second, both reindeer are resting. They continue to rest until the 138th second, when Comet flies for another ten seconds. On the 174th second, Dancer flies for another 11 seconds.
In this example, after the 1000th second, both reindeer are resting, and Comet is in the lead at 1120 km (poor Dancer has only gotten 1056 km by that point). So, in this situation, Comet would win (if the race ended at 1000 seconds).
Given the descriptions of each reindeer (in your puzzle input), after exactly 2503 seconds, what distance has the winning reindeer traveled?

Input


Solution

Here is my attempt to solve this problem.


As you can see, I split the input into for columns: name, speed, bursting time, and resting time. For counting the distance these reindeer covered in the 2503th seconds (cell E2), I use this formula:

=IF(MOD($E$2,D3+C3)>C3,(1+ROUNDDOWN($E$2/(C3+D3),0))
*B3*C3,ROUNDDOWN($E$2/(C3+D3),0)*B3*C3+MOD($E$2,D3+C3)*B3)

The code determine whether those reindeer are resting or bursting. If the time (2503) mod the time needed for the reindeer to burst again (bursting time + resting time) is greater than burst time, then the reindeer is resting. Then the code calculate the distance covered. and simply get the largest value of those distances.

Part 2

Description

Seeing how reindeer move in bursts, Santa decides he's not pleased with the old scoring system.
Instead, at the end of each second, he awards one point to the reindeer currently in the lead. (If there are multiple reindeer tied for the lead, they each get one point.) He keeps the traditional 2503 second time limit, of course, as doing otherwise would be entirely ridiculous.
Given the example reindeer from above, after the first second, Dancer is in the lead and gets one point. He stays in the lead until several seconds into Comet's second burst: after the 140th second, Comet pulls into the lead and gets his first point. Of course, since Dancer had been in the lead for the 139 seconds before that, he has accumulated 139 points by the 140th second.
After the 1000th second, Dancer has accumulated 689 points, while poor Comet, our old champion, only has 312. So, with the new scoring system, Dancer would win (if the race ended at 1000 seconds).
Again given the descriptions of each reindeer (in your puzzle input), after exactly 2503 seconds, how many points does the winning reindeer have?

Solution

For the part 2, I have to calculate the distance each reindeer covered in every second up to the 2503th and determine which one is leading. Now in column G, I put an array formula to counts how many those reindeer are in the lead, and therefore the point they get. And finally find the largest of those numbers. Here is my array formula:

=SUM(IF(H3:CRN3=H$13:CRN$13,1,0))

Share:

Advent of Code 2015 - Day 13: Knights of the Dinner Table

Part 1

Description

In years past, the holiday feast with your family hasn't gone so well. Not everyone gets along! This year, you resolve, will be different. You're going to find the optimal seating arrangement and avoid all those awkward conversations.
You start by writing up a list of everyone invited and the amount their happiness would increase or decrease if they were to find themselves sitting next to each other person. You have a circular table that will be just big enough to fit everyone comfortably, and so each person will have exactly two neighbors.
For example, suppose you have only four attendees planned, and you calculate their potential happiness as follows:
Alice would gain 54 happiness units by sitting next to Bob.
Alice would lose 79 happiness units by sitting next to Carol.
Alice would lose 2 happiness units by sitting next to David.
Bob would gain 83 happiness units by sitting next to Alice.
Bob would lose 7 happiness units by sitting next to Carol.
Bob would lose 63 happiness units by sitting next to David.
Carol would lose 62 happiness units by sitting next to Alice.
Carol would gain 60 happiness units by sitting next to Bob.
Carol would gain 55 happiness units by sitting next to David.
David would gain 46 happiness units by sitting next to Alice.
David would lose 7 happiness units by sitting next to Bob.
David would gain 41 happiness units by sitting next to Carol.
Then, if you seat Alice next to David, Alice would lose 2 happiness units (because David talks so much), but David would gain 46 happiness units (because Alice is such a good listener), for a total change of 44.
If you continue around the table, you could then seat Bob next to Alice (Bob gains 83, Alice gains 54). Finally, seat Carol, who sits next to Bob (Carol gains 60, Bob loses 7) and David (Carol gains 55, David gains 41). The arrangement looks like this:
     +41 +46
+55   David    -2
Carol       Alice
+60    Bob    +54
     -7  +83
After trying every other seating arrangement in this hypothetical scenario, you find that this one is the most optimal, with a total change in happiness of 330.
What is the total change in happiness for the optimal seating arrangement of the actual guest list?

Input


Solution

The problem is similar to the traveling salesman problem, or the problem in day 9. Only in today's problem, it wraps around. So, I used the similar approach. Here is my Excel sheet:


I split the input into for different parts: Name, gain/lose, happiness, and neighbor. Then, I put those into a 8×8 table, associating with each name and happiness point they get when sitting next to others. then, I make a permutations of 8 numbers, according to the seating arrangements possible, and counts the accumulated happiness point. Columns titled left are for points gained with neighbor in the left, and columns titled right are for points gained from neighbor in the right. And then, I just added them up and find the largest number.

Part 2

Description

In all the commotion, you realize that you forgot to seat yourself. At this point, you're pretty apathetic toward the whole thing, and your happiness wouldn't really go up or down regardless of who you sit next to. You assume everyone else would be just as ambivalent about sitting next to you, too.
So, add yourself to the list, and give all happiness relationships that involve you a score of 0.
What is the total change in happiness for the optimal seating arrangement that actually includes yourself?

Solution

For the part 2, I just have to modify my table into 9×9 table and make another permutation (now of 9) and do the rest as in part 1.


Share:

Advent of Code 2015 - Day 12: JSAbacusFramework.io

Part 1

Description

Santa's Accounting-Elves need help balancing the books after a recent order. Unfortunately, their accounting software uses a peculiar storage format. That's where you come in.
They have a JSON document which contains a variety of things: arrays ([1,2,3]), objects ({"a":1, "b":2}), numbers, and strings. Your first job is to simply find all of the numbers throughout the document and add them together.
For example:
  • [1,2,3] and {"a":2,"b":4} both have a sum of 6.
  • [[[3]]] and {"a":{"b":4},"c":-1} both have a sum of 3.
  • {"a":[-1,1]} and [-1,{"a":1}] both have a sum of 0.
  • [] and {} both have a sum of 0.
You will not encounter any strings containing numbers.
What is the sum of all numbers in the document?

Input


Solution

I succeeded solving this problem without using VBA. First, I split the input into values separated by commas. This can be done by pasting the input in Notepad and save it as a CSV (Comma Separated Values) file and open it in Excel. It will look like this:


The input is split into cells in rows 4. In row 5, I put this formula:

=IFERROR(VALUE(LEFT(RIGHT(B4,LEN(B4)-MIN(FIND({"-",0,1,2,3,4,5,6,7,8,9},B4&
"-0123456789"))+1),SUM(LEN(RIGHT(B4,LEN(B4)-MIN(FIND({"-",0,1,2,3,4,5,6,7,8,9},B4&
"-0123456789"))+1))-LEN(SUBSTITUTE(RIGHT(B4,LEN(B4)-MIN(FIND({"-",0,1,2,3,4,5,6,7,8,9},
B4&"-0123456789"))+1),{"-","0","1","2","3","4","5","6","7","8","9"},""))))),0)

What does this formula do? First, it separate the number (including negative ones, note the "-" sign) and non-number character after that from the string. For example, a string "a:[2]" becomes "2]". Then, it separates the number for any non-number character. VALUE() is needed to convert those number string cells into their values. While IFERROR() is needed to avoid error of conversion of empty strings.

Part 2

Description

Uh oh - the Accounting-Elves have realized that they double-counted everything red.
Ignore any object (and all of its children) which has any property with the value "red". Do this only for objects ({...}), not arrays ([...]).
  • [1,2,3] still has a sum of 6.
  • [1,{"c":"red","b":2},3] now has a sum of 4, because the middle object is ignored.
  • {"d":"red","e":[1,2,3,4],"f":5} now has a sum of 0, because the entire structure is ignored.
  • [1,"red",5] has a sum of 6, because "red" in an array has no effect.

Solution

For the part 2, I have to use JSON editor to remove all objects containing "red". After that it's just the same with the part 1.

Share:

Advent of Code 2015 - Day 11: Corporate Policy

Part 1

Description

Santa's previous password expired, and he needs help choosing a new one.
To help him remember his new password after the old one expires, Santa has devised a method of coming up with a password based on the previous one. Corporate policy dictates that passwords must be exactly eight lowercase letters (for security reasons), so he finds his new password by incrementing his old password string repeatedly until it is valid.
Incrementing is just like counting with numbers: xx, xy, xz, ya, yb, and so on. Increase the rightmost letter one step; if it was z, it wraps around to a, and repeat with the next letter to the left until one doesn't wrap around.
Unfortunately for Santa, a new Security-Elf recently started, and he has imposed some additional password requirements:
  • Passwords must include one increasing straight of at least three letters, like abc, bcd, cde, and so on, up to xyz. They cannot skip letters; abd doesn't count.
  • Passwords may not contain the letters i, o, or l, as these letters can be mistaken for other characters and are therefore confusing.
  • Passwords must contain at least two different, non-overlapping pairs of letters, like aa, bb, or zz.
For example:
  • hijklmmn meets the first requirement (because it contains the straight hij) but fails the second requirement requirement (because it contains i and l).
  • abbceffg meets the third requirement (because it repeats bb and ff) but fails the first requirement.
  • abbcegjk fails the third requirement, because it only has one double letter (bb).
  • The next password after abcdefgh is abcdffaa.
  • The next password after ghijklmn is ghjaabcc, because you eventually skip all the passwords that start with ghi..., since i is not allowed.
Given Santa's current password (your puzzle input), what should his next password be?

Input


Solution

It might be possible to solve this problem without using VBA. But, I guess it will require a lot of space. So, I decided to use VBA. My code was not that neat. It was too wordy. So, any suggestion to make it more concise and efficient is much more appreciated. Here is my code, with two sub function:

Sub CorporatePolicy()
    Dim input11 As String
    Dim p1, p2, p3, p4, p5, p6, p7, p8 As String
    Dim amazon(1 To 26) As Variant
    Dim i, j, k, l, m, n, o, p As Integer
    
    input11 = "hxbxwxba"
    For i = (Asc(Mid(input11, 1, 1)) - 96) To 26
        p1 = Mid(input11, 1, 1)
        For j = (Asc(Mid(input11, 2, 1)) - 96) To 26
            p2 = Mid(input11, 2, 1)
            For k = (Asc(Mid(input11, 3, 1)) - 96) To 26
                p3 = Mid(input11, 3, 1)
                For l = (Asc(Mid(input11, 4, 1)) - 96) To 26
                    p4 = Mid(input11, 4, 1)
                    For m = (Asc(Mid(input11, 5, 1)) - 96) To 26
                        p5 = Mid(input11, 5, 1)
                        For n = (Asc(Mid(input11, 6, 1)) - 96) To 26
                            p6 = Mid(input11, 6, 1)
                            For o = (Asc(Mid(input11, 7, 1)) - 96) To 26
                                p7 = Mid(input11, 7, 1)
                                For p = (Asc(Mid(input11, 8, 1)) - 96) To 26
                                    p8 = nextchar(Mid(input11, 8, 1))
                                    input11 = Left(input11, 7) & p8
                                    If isvalid(p1, p2, p3, p4, p5, p6, p7, p8, input11) Then
                                    Debug.Print input11
                                    Exit Sub
                                    End If
                                Next p
                                p7 = nextchar(p7)
                                input11 = Left(input11, 6) & p7 & p8
                                If isvalid(p1, p2, p3, p4, p5, p6, p7, p8, input11) Then
                                Debug.Print input11
                                Exit Sub
                                End If
                            Next o
                            p6 = nextchar(p6)
                            input11 = Left(input11, 5) & p6 & p7 & p8
                            If isvalid(p1, p2, p3, p4, p5, p6, p7, p8, input11) Then
                            Debug.Print input11
                            Exit Sub
                            End If
                        Next n
                        p5 = nextchar(p5)
                        input11 = Left(input11, 4) & p5 & p6 & p7 & p8
                        If isvalid(p1, p2, p3, p4, p5, p6, p7, p8, input11) Then
                        Debug.Print input11
                        Exit Sub
                        End If
                    Next m
                    p4 = nextchar(p4)
                    input11 = Left(input11, 3) & p4 & p5 & p6 & p7 & p8
                    If isvalid(p1, p2, p3, p4, p5, p6, p7, p8, input11) Then
                    Debug.Print input11
                    Exit Sub
                    End If
                Next l
                p3 = nextchar(p3)
                input11 = Left(input11, 2) & p3 & p4 & p5 & p6 & p7 & p8
                If isvalid(p1, p2, p3, p4, p5, p6, p7, p8, input11) Then
                Debug.Print input11
                Exit Sub
                End If
            Next k
            p2 = nextchar(p2)
            input11 = Left(input11, 1) & p2 & p3 & p4 & p5 & p6 & p7 & p8
            If isvalid(p1, p2, p3, p4, p5, p6, p7, p8, input11) Then
            Debug.Print input11
            Exit Sub
            End If
        Next j
        p1 = nextchar(p1)
        input11 = p1 & p2 & p3 & p4 & p5 & p6 & p7 & p8
        If isvalid(p1, p2, p3, p4, p5, p6, p7, p8, input11) Then
        Debug.Print input11
        Exit Sub
        End If
    Next i
End Sub

Function nextchar(ini) As String
    If ini = "z" Then
        nextchar = "a"
    Else
        nextchar = Chr(1 + Asc(ini))
    End If
End Function

Function isvalid(ByVal p1, p2, p3, p4, p5, p6, p7, p8 As String, pass As String) As Boolean
    If ((Asc(p1) + 1 = Asc(p2) And Asc(p2) + 1 = Asc(p3)) Or (Asc(p2) + 1 = Asc(p3) And Asc(p3) + 1 = Asc(p4)) Or _
        (Asc(p3) + 1 = Asc(p4) And Asc(p4) + 1 = Asc(p5)) Or (Asc(p4) + 1 = Asc(p5) And Asc(p5) + 1 = Asc(p6)) Or _
        (Asc(p5) + 1 = Asc(p6) And Asc(p6) + 1 = Asc(p7)) Or (Asc(p6) + 1 = Asc(p7) And Asc(p7) + 1 = Asc(p8))) And _
        (Len(Replace(Replace(Replace(pass, "i", ""), "o", ""), "l", "")) = 8) And _
        ((p1 = p2 And (p3 = p4 Or p4 = p5 Or p5 = p6 Or p6 = p7 Or p7 = p8)) Or (p2 = p3 And (p4 = p5 Or p5 = p6 Or p6 = p7 Or p7 = p8)) Or _
        (p3 = p4 And (p5 = p6 Or p6 = p7 Or p7 = p8)) Or (p4 = p5 And (p6 = p7 Or p7 = p8)) Or (p5 = p6 And p7 = p8)) _
    Then
        isvalid = True
    End If
End Function

Part 2

Description

Santa's password expired again. What's the next one?

Solution

For the part 2, I just need to modify the input in the code with output of the part 1.

Share:

Advent of Code 2015 - Day 10: Elves Look, Elves Say

Part 1

Description

Today, the Elves are playing a game called look-and-say. They take turns making sequences by reading aloud the previous sequence and using that reading as the next sequence. For example, 211 is read as "one two, two ones", which becomes 1221 (1 2, 2 1s).
Look-and-say sequences are generated iteratively, using the previous value as input for the next step. For each step, take the previous value, and replace each run of digits (like 111) with the number of digits (3) followed by the digit itself (1).
For example:
  • 1 becomes 11 (1 copy of digit 1).
  • 11 becomes 21 (2 copies of digit 1).
  • 21 becomes 1211 (one 2 followed by one 1).
  • 1211 becomes 111221 (one 1, one 2, and two 1s).
  • 111221 becomes 312211 (three 1s, two 2s, and one 1).
Starting with the digits in your puzzle input, apply this process 40 times. What is the length of the result?

Input


Solution

This problem involves a sequence known as look and say sequence. And I found a ready to use VBA code here. I modified a bit into this:

Sub LookAndSay()
Dim s, news, curdigit, newdigit As String
Dim curlength, p, L As Long
 
ActiveSheet.Range("a4").Select
s = Selection.Value
For i = 1 To 40
  L = Len(s)
  p = 1
  curdigit = Left$(s, 1)
  curlength = 1
  news = ""
  For p = 2 To L
    newdigit = Mid$(s, p, 1)
    If curdigit = newdigit Then
      curlength = curlength + 1
    Else
      news = news & CStr(curlength) & curdigit
      curdigit = newdigit
      curlength = 1
    End If
  Next p
  news = news & CStr(curlength) & curdigit
  Debug.Print news
  s = news
  ActiveCell.Offset(1, 0).Select
  ActiveCell.Value = Len(s)
Next i
Exit Sub
End Sub

I modified the code so it will accommodate larger number (I change Integer into Long) and read input from and write output into the sheet. Then all I need is running the code and wait for the result.

Part 2

Description

Neat, right? You might also enjoy hearing John Conway talking about this sequence (that's Conway of Conway's Game of Life fame).
Now, starting again with the digits in your puzzle input, apply this process 50 times. What is the length of the new result?

Solution

For the part 2, I just need to modify the code to run 50 times.

Share:

Recent Posts

Categories

Blog Archive