• Home
  • About
    • Marion Pang photo

      Marion Pang

      Marion's personal website.

    • Learn More
    • Email
    • Twitter
    • LinkedIn
    • Github
    • Steam
  • Posts
    • All Posts
    • All Tags
  • Projects
  • Github

Advent of Code 2020 (Day 2)

02 Dec 2020

Reading time ~4 minutes

Day 2

Password Philosophy

Wow, Santa sure likes to travel stylishly. Remind me to buy a toboggan for the next time I want to sled my way to the airport. But of course, the toboggan rental shop is having some trouble too - this time with their corrupted password database.

To try to debug the problem, they have created a list (your puzzle input) of passwords (according to the corrupted database) and the corporate policy when that password was set.

    1-3 a: abcde
    1-3 b: cdefg
    1-3 b: cdefg

First, we do a little bit of string manipulation to extract the necessary information from our given dataset.

import pandas as pd
import numpy as np

# import from given input
df1 = pd.read_csv("input.txt", header=None)
arr=np.ndarray.flatten(df1.values)

df = pd.DataFrame(arr,columns=['password'])

# formatting strings
df[['num','letter','password']] = df['password'].str.split(' ',expand=True)
df[['num1','num2']] = df['num'].str.split('-',expand=True)
df['letter'] = df['letter'].map(lambda x: x.strip(':'))

# as an example, show top 3 formatted entries
df.head(3)
password num letter num1 num2
0 qllllqllklhlvtl 8-11 l 8 11
1 wmmmmmttm 1-3 m 1 3
2 pgppp 2-4 p 2 4

Part 1

Their password database seems to be a little corrupted: some of the passwords wouldn’t have been allowed by the Official Toboggan Corporate Policy that was in effect when they were chosen. The password policy indicates the lowest and highest number of times a given letter must appear for the password to be valid. For example, 1-3 a means that the password must contain a at least 1 time and at most 3 times.

Tl;dr Frequency of the specified character in the password needs to be within the specified range!

Seems pretty simple - we can use the count() method to count the frequency of the letter in the password, and check if its within our desired range.


def isValidPassword_p1(password, num1, num2, letter):
    # counting frequency of letter in password
    freq=password.count(letter)
    # check if letter in specified range
    return (freq >= int(num1) and freq <= int(num2))

df['valid_p1']=df.apply(lambda x: isValidPassword_p1(x['password'], x['num1'], x['num2'], x['letter']), axis=1)
df['valid_p1'].value_counts()
False    584
True     416
Name: valid_p1, dtype: int64

Ans: 416

Part 2

The shopkeeper suddenly realizes that he just accidentally explained the password policy rules from his old job at the sled rental place down the street! The Official Toboggan Corporate Policy actually works a little differently. I’m a little worried about the cybersecurity of this toboggan shop ngl.

Tl;dr Letters at the positions of the two numbers should match the given character only once.

Alrighty! This one is a bit more of a challenge. I’ll take the opportunity to explain a little bit about logic, and logic gates! In this problem, we want only one of the letters to match with our specified character. Let’s arbitrarily define 2 intputs: whether the left character matches, and whether the right character matches. Placed into a truth table (where 1: True, 0: False), we have:

Left Right Output
1 1 0
1 0 1
0 1 1
0 0 0

This is a logic gate at its core - specifically, finding the relationship between one or more inputs (Left and Right in our case) and its single output. In our case, this is the equivalent to a XOR gate! There are other logic gates as well, as listed here:

  • AND,&: Sets each bit to 1 if both bits are 1
  • OR,|: Sets each bit to 1 if one of two bits is 1
  • XOR, ^: Sets each bit to 1 if only one of two bits is 1
  • NOT, ~: Inverts all the bits

Of course, you can also have a combination of these, such as a XNOR or NAND gate. In real life applicatins, these logic gates are built using diodes or transistors (a really cool exercise, if you’re ever bored!) that essentially act as electronic switches. Of course, anything can be used to make logic gates, from electromagnetic relays1, mechanical parts2,fluidics3 and even optics4!

Thankfully, in python, the XOR gate is easy enough to find - we simply use the bitwise operator ^. So, we pass in our two inputs and voila!

def isValidPassword_p2(password, num1, num2, letter):
    # function is essentially an XNOR gate!
    l1 = (password[int(num1)-1]==letter) # check if 1st character matches
    l2 = (password[int(num2)-1]==letter) # check if 2nd character matches
    return (l1^l2)

df['valid_p2']=df.apply(lambda x: isValidPassword_p2(x['password'], x['num1'], x['num2'], x['letter']), axis=1)
df['valid_p2'].value_counts()
True     688
False    312
Name: valid_p2, dtype: int64

Ans: 688

Thoughts after day 2: we love pandas! but also, logic ❤️

  1. Pott, V. et al. Mechanical Computing Redux: Relays for Integrated Circuit Applications. Proceedings of the IEEE 98, 2076–2094 (2010). ↩

  2. Song, Y. et al. Additively manufacturable micro-mechanical logic gates. Nature Communications 10, 882 (2019) ↩

  3. Cheow, L. F., Yobas, L. & Kwong, D.-L. Digital microfluidics: Droplet based logic gates. Appl. Phys. Lett. 90, 054107 (2007). ↩

  4. Min Zhang, Ling Wang & Peida Ye. All optical XOR logic gates: technologies and experiment demonstrations. IEEE Communications Magazine 43, S19-S24 (2005). ↩



codingfun Share Tweet +1