computer screen of code

Advent Of Code Day 2

Advent of Code is a fun holiday coding challenge. This text links to their page if you are interested in trying your luck.

    Unfortunately for me, I am one of those people that knows a little about everything, but master of nothing.  I was smart enough to choose python as my language to try and tackle these coding challenges (if you want to know why that is smart, learn another language and then learn Python and you will see) because Python is a very user friendly although powerful language, great for doing scripts, not so great a game programming.  

I will reorganize this later, because I did the first two but they were simple enough that I didn’t keep my work, I just did it and put in my answer and moved on.  The 2nd Challenges as more difficult for me, and I actually kept my code which I will show you and explain my methodology (even though there is probably a 12 year old that did a one-liner)

Advent Of Code Day 2 (Part One)

Day 2: Password Philosophy

Your flight departs in a few days from the coastal airport; the easiest way down to the coast from here is via toboggan.

The shopkeeper at the North Pole Toboggan Rental Shop is having a bad day. “Something’s wrong with our computers; we can’t log in!” You ask if you can take a look.

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.

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.

For example, suppose you have the following list:

1-3 a: abcde
1-3 b: cdefg
2-9 c: ccccccccc

Each line gives the password policy and then the password. 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.

In the above example, 2 passwords are valid. The middle password, cdefg, is not; it contains no instances of b, but needs at least 1. The first and third passwords are valid: they contain one a or nine c, both within the limits of their respective policies.

How many passwords are valid according to their policies?

(Again if this is something you want to participate in, it is still ongoing, and you can get your own list and own points by going to https://adventofcode.com/

        <h3>My Solution:</h3>       
        <code><pre style = "background:#2E282A; color:#EF3E36">
import re
totalTrue =0
list = ['list that they provide which I am keeping a secre incase it is reused, also it is really long]
for each in list:
num = re.findall('^[0-9]{1,2}|[0-9]{1,2}',each)
low = num[0]
high = num[1]
char = re.search('[a-z]',each)
char = char.group(0)
occurences = 0
occurences = int(each.count(char)) -1
if int(low) <= int(occurences) and int(high) >= int(occurences):
    totalTrue = totalTrue + 1
    print(low, high, occurences)
    print (totalTrue, 'true')
else:
    print(low, high, occurences)
    print('false')
</pre>

This may have been a stupid way to solve the problem, but it solved the problem which is the goal.  Let’s go line by line on what I did, if you have a better solution, please share in the comments, that would be rad I think for everyone, including myself who is trying to learn.

Importing re, setting Variables

import re

This line is particularly easy to explain, it imports the regular expression module to allow use of regex

totalTrue = 0

The questions asks how many are true, so this just checks and incriminates if a case turns out to be true

 list = ['example','example]

This might need some explanation because I removed the list. What I actually did, instead of trying to parse the list in python, I used the site to make it into a list for me using the, as a delimiter. I could have probably used Pythons splice method with ‘,’ as a delimiter which I believe would have given me the same results but it might also take another step.

 for each in list:

Starts a for each loop, iterating through each item of the list provided.

The RegEx Used To Get The Data

    <code></code>
num = re.findall('^[0-9]{1,2}|[0-9]{1,2}', each)

So this is the regex, and this is a very simple one that I didn’t have to wrap my head around. If you know what the strings look like in the example, it is something like ’12-15 g: gffgfgfggfgf’
so this first expression looks for any two-digit number from the beginning, then it has a or so that it looks for another one to two-digit number, the each is from the ‘for each’ loop, making each a keyword for every one line. So it finds the first two two-digit numbers, and they are put into the variable num. Num has 2 indexes, one for the first number which is the lowest amount of occurrences the string can have to be true, and high is the 1st index (second technically, but computers normally start indexing at 0 so this is normal)

low = num[0] 
high = num[1]

I then needed to get the char

char = re.search('[a-z]',each)
char = char.group(0)

so now char has the variable that is the character we are searching for in the string.

occurrences = 0
occurrences = int(each.count(char)) - 1

Now, we still have the string that we have to check for how many times that char shows up in that string. I didn’t make another variable and parse out the string. What I did instead is just subtracted 1, because it would count the character we just grabbed as an occurrence, and if you understand what I mean, then obviously all my answers would be plus 1.
for example, if I was told to find how many of a character appears in the string, and the string is ‘find how many Gs are in GGGGGGGGGG’ and I use that single quote string, then I would also count that first G that told me what I was looking for, but if I subtract one, then it gives the correct answer

The Loop Inside The Loops That Checks the Condition

if int(low) <= int(occurences) and int(high) >= int(occurences):
        totalTrue = totalTrue + 1
        print(low, high, occurences)
        print (totalTrue, 'true')
    else:
        print(low, high, occurences)
        print('false')

This is the loop where the magic happens. This is very simple, but let’s go over it in case someone thinks I am smarter than I am, or if someone wants to teach me a smarter way, they can know how my mind thinks.
This is a conditional If statement, that checks to see if the number of occurrences is more than or equal to the low number, and less than or equal to the high number. If it passes the test it will increment the totalTrue variable with 1. The totalTrue variable is the actual answer, and when this runs, it will finish with the number being true. The other other print statements that are now

 print(totalTrue, 'true')

Are only there for me, to debug and make sure my logic was sound. I needed to make sure everything was not coming up true because I messed up my logic. That was not the case and I submitted my answer and got it correct.

Advent Of Code, Day 2 – Part One Conclussion

    <p>I personally do not care if someone uses this to get their own answer, it kind of defeats the point, but I do not fair bad about sharing my answer because if you found this page for it, then you would have been able to find the reddit page that has the solutions as well.  Anyway, happy coding, feel free to share with me your experiences in this fun event.</p>        
        <h2>Part Two </h2>      
    <article><p>While it appears you validated the passwords correctly, they don't seem to be what the Official Toboggan Corporate Authentication System is expecting.

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.

Each policy actually describes two positions in the password, where 1 means the first character, 2 means the second character, and so on. (Be careful; Toboggan Corporate Policies have no concept of “index zero”!) Exactly one of these positions must contain the given letter. Other occurrences of the letter are irrelevant for the purposes of policy enforcement.

Given the same example list from above:

  • 1-3 a: abcde is valid: position 1 contains a and position 3 does not.
  • 1-3 b: cdefg is invalid: neither position 1 nor position 3 contains b.
  • 2-9 c: ccccccccc is invalid: both position 2 and position 9 contain c.

How many passwords are valid according to the new interpretation of the policies?

My Solution


>import re
totalTrue =0
occurences = 0
list =['']
for each in list:
    num = re.findall('^[0-9]{1,2}|[0-9]{1,2}',each)
    low = num[0]
    high = num[1]
    char = re.search('[a-z]',each)
    char = char.group(0)
    password = each.split(': ')
    if char == password[1][int(low)-1] or char == password[1][int(high)-1]:
        if (password[1][int(low)-1] != password[1][int(high)-1]):
            occurences = occurences +1
print (occurences)

It is not pretty, but it works.  Again, if you have done it an easier way with less code, please comment and let me know, I am always down to learn.  My solutions do complete the objective though.  I am going to go over this is in less detail because we have most of the variables from part 1.

What we needed for this one to work as we needed the string of characters

 password = each.split(': ')

which that line has done for us (there was almost a better way to get exactly what I needed, but this also does, it just also has the char listed again as index 0, so we have to use index[1] to get the string that we want.

if char == password[1][int(low)-1] or char == password[1][int(high)-1]):

So that is the conditional statement. As I said, my string that I am checking the indexes off is at password[1], the numbers I have were chars, so I use int() to convert them to ints so they could be used as indices. Then I subtracted one because computers count at 0 and the instructions specifically say do not count zero, so that was kind of atypical.

        <h2>The Last Trick</h2>     
    <p>Okay, so that statement will run if either one of those indices match, but that is not what the questions/problem/test wants, it wants either or.  There is a thing in programming language called an exclusive or, and that would have been perfect, but I do not know how to do that in Python.  What we did instead is followed up with a comparison, if the low and the how indexes match, then it is a failure.  This does the exact same thing as an exclusive or, it means only 1 can be true or the whole thing is false.  If both those conditions are met, then the answer is true and the variable occurrences gets incremented.  The answer is the final amount of occurrences that occur in the list provided.</p>      
        <h2>Final Words</h2>        
    <p>I hoped I helped some one, because writing these is actually about as difficult if not more so than solving these puzzles.  If you follow this guide or just still my rough code, you too can have 4 stars.</p>      
                                    <img width="640" height="96" src="https://ganstapenguin.com/wp-content/uploads/2020/12/adventofcode.png" alt="Advent of Code Score" loading="lazy" srcset="https://i0.wp.com/ganstapenguin.com/wp-content/uploads/2020/12/adventofcode.png?w=869&amp;ssl=1 869w, https://i0.wp.com/ganstapenguin.com/wp-content/uploads/2020/12/adventofcode.png?resize=300%2C45&amp;ssl=1 300w, https://i0.wp.com/ganstapenguin.com/wp-content/uploads/2020/12/adventofcode.png?resize=768%2C115&amp;ssl=1 768w, https://i0.wp.com/ganstapenguin.com/wp-content/uploads/2020/12/adventofcode.png?resize=500%2C75&amp;ssl=1 500w, https://i0.wp.com/ganstapenguin.com/wp-content/uploads/2020/12/adventofcode.png?resize=800%2C120&amp;ssl=1 800w" sizes="(max-width: 640px) 100vw, 640px" />