Advent of Code
Kaverillani tuli netissä vastaan Advent of Code niminen nettisivu jonka hän linkkasi minulle. Kyseessä oli adventtikalenteri joka oli täynnä ohjelmointipulmia. Jokaisesta tehdystä tehtävästä sai yhden tähden. Kalenterissa sitten pikkuhiljaa paljastuu jokin ASCII kuva.
Kiinnostuin heti ja aloin koodaamaan.
Day 1
https://adventofcode.com/2020/day/1
Ensimmäinen tehtävä oli löytää kaksi lukua joiden summa olisi 2020 ja sitten palauttaa niiden tulo.
Nettisivu antoi minulle uniikin 200 luvun listan.
Ihan ensitöikseni halusin päästä listaani käsiksi suoraan koodistani, jotta minun ei tarvitsisi copy pastettaa sitä mihinkään omaan tiedostooni.
Avasin Visual Studio Coden ja aloin kirjoittamaan Pythonia. Käytin requests kirjastoa. Sillä saa helposti tehtyä http get pyyntöjä.
Koska sivulle pitää kirjautua ja kaikilla on jokaiselle päivälle uniikki lista, pelkällä URLllä en voi saada omaa listaani. En ollut ihan varma kuinka pääsisin tästä yli, mutta arvelin, että jos saisin selaimeni evästeet lähetettyä samalla, voisin päästä ehkä omaan listaani käsiksi.
Pikaisesti googlettamalla löysin browser_cookie3 nimisen kirjaston, joka nappaa selaimesi evästeet. Tämä toimi koodissani täydellisesti requestsin kanssa. Nyt pääsin omaan listaani käsiksi suoraan koodistani.
import requests
import browser_cookie3
cj = browser_cookie3.chrome()
r = requests.get("https://adventofcode.com/2020/day/1/input", cookies=cj)
print(r.text)
Ohjelma tulostaa:
1714
1960
1256
1597
1853
jne...
Nyt kun pääsen käsiksi listaani, päästään itse asiaan. Kirjoitin for loopin joka ottaa luvun ja lisää sen toisen luvun kanssa. Jos niiden summa ei ole 2020 valitaan toinen numero. Tämä jatkuu kunnes vastaus löytyy tai luvut loppuvat kesken. Jos vastaus löytyy, kerrotaan luvut ja tulostetaan vastaus. Vastaus sitten laitetaan pulman nettisivulle ja toivotaan että se on oikein.
Tässä vielä koodi:
for i in range(0, len(numbers)):
for j in range(0, len(numbers)):
print(numbers[i], "+", numbers[j], "is", numbers[i]+numbers[j])
if numbers[i]+numbers[j] == 2020:
print("2020 FOUND FROM NUMBERS", numbers[i], "and", numbers[j], "!")
print("Product =", numbers[i]*numbers[j])
Tässä näkyy kyseinen ohjelma in action:
Vastaukseni on siis 482811
Day 1 – lisätehtävä
Listassa on kolme lukua jotka ovat yhteensä 2020. Mikä on näiden lukujen tulo?
for i in range(0, len(numbers)):
if numbers[i] > 2020:
continue
for j in range(0, len(numbers)):
if numbers[i] + numbers[j] > 2020:
continue
for k in range(0, len(numbers)):
print(numbers[i], "+", numbers[j], "+", numbers[k], "is", numbers[i]+numbers[j]+numbers[k])
if numbers[i]+numbers[j]+numbers[k] == 2020:
print("Product =", numbers[i]*numbers[j]*numbers[k])
Ohjelma tulostaa:
...
1067 + 691 + 1164 is 2922
1067 + 691 + 1868 is 3626
1067 + 691 + 1035 is 2793
1067 + 691 + 262 is 2020
Product = 193171814
Vastaukseni on siis 193171814
Copy pastetan loput. Samat perusjutut jokaisessa.
Day 2
https://adventofcode.com/2020/day/2
…
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?
valid = 0
for item in text:
if item == "":
continue
password = item.split(": ")[1]
policy = item.split(": ")[0]
policyFrom = int(policy.split("-")[0])
policyTo = int(policy.split("-")[1].split()[0])
policyLetter = policy[len(policy)-1]
# Count how many letters of policyLetter there are.
policyLetterCount = 0
for letter in password:
if letter == policyLetter:
policyLetterCount = policyLetterCount + 1
if policyFrom <= policyLetterCount <= policyTo:
print("This password is fine!")
valid = valid + 1
else:
print("This password is not ok!")
print("Amount of valid passwords is: ", valid)
Ohjelma tulostaa:
...
This password is fine!
This password is not ok!
This password is not ok!
Amount of valid passwords is: 622
Day 2 – lisätehtävä
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: abcdeis valid: position1containsaand position3does not.1-3 b: cdefgis invalid: neither position1nor position3containsb.2-9 c: cccccccccis invalid: both position2and position9containc.
How many passwords are valid according to the new interpretation of the policies?
valid = 0
for item in text:
if item == "":
continue
password = item.split(": ")[1]
policy = item.split(": ")[0]
policyPos1 = int(policy.split("-")[0])-1
policyPos2 = int(policy.split("-")[1].split()[0])-1
policyLetter = policy[len(policy)-1]
policyPos1Bool = False
policyPos2Bool = False
if password[policyPos1] == policyLetter:
print("Pos1 is true")
policyPos1Bool = True
if password[policyPos2] == policyLetter:
print("Pos2 is true")
policyPos2Bool = True
if policyPos1Bool is True and policyPos2Bool is True:
print("BOTH ARE TRUE SO IS INVALID")
elif policyPos1Bool is False and policyPos2Bool is False:
print("Both are FALSE So INVALID!!")
else:
valid = valid + 1
print("This password is fine!")
print("Amount of valid passwords is: ", valid)
Ohjelma tulostaa:
...
Pos1 is true
This password is fine!
Both are FALSE So INVALID!!
Both are FALSE So INVALID!!
Amount of valid passwords is: 263
Day 3
https://adventofcode.com/2020/day/3
right = 0
down = 0
treecount = 0
for i in range(0, len(text)):
text[i] = text[i] + text[i]
text[i] = text[i] + text[i]
text[i] = text[i] + text[i]
text[i] = text[i] + text[i]
text[i] = text[i] + text[i]
if len(text[i]) > right:
print(text[i][right])
if text[i][right] == "#":
treecount += 1
right = right + 3
print(treecount)
Day 3 – lisätehtävä
for i in range(0, len(text)):
text[i] = text[i] + text[i]
text[i] = text[i] + text[i]
text[i] = text[i] + text[i]
text[i] = text[i] + text[i]
text[i] = text[i] + text[i]
text[i] = text[i] + text[i]
text[i] = text[i] + text[i]
answer = []
right = 0
down = 0
treecount = 0
for i in range(0, len(text)):
if len(text[i]) > right:
if text[i][right] == "#":
treecount += 1
right = right + 3
answer.append(treecount)
right = 0
down = 0
treecount = 0
for i in range(0, len(text)):
if len(text[i]) > right:
if text[i][right] == "#":
treecount += 1
right = right + 1
answer.append(treecount)
right = 0
down = 0
treecount = 0
for i in range(0, len(text)):
if len(text[i]) > right:
if text[i][right] == "#":
treecount += 1
right = right + 5
answer.append(treecount)
right = 0
down = 0
treecount = 0
for i in range(0, len(text)):
if len(text[i]) > right:
if text[i][right] == "#":
treecount += 1
right = right + 7
answer.append(treecount)
right = 0
down = 0
treecount = 0
for i in range(0, len(text)):
if (i % 2) != 0:
continue
if len(text[i]) > right:
if text[i][right] == "#":
treecount += 1
right = right + 1
answer.append(treecount)
print(answer)
print(np.prod(answer, dtype=np.int64))
Day 4
https://adventofcode.com/2020/day/4
required = ["byr", "iyr", "eyr", "hgt", "hcl", "ecl", "pid"]
optional = ["cid"]
valid = 0
for passport in text:
invalid = False
passport = passport.split()
passport = dict(s.split(":") for s in passport)
for req in required:
if req not in passport.keys():
print(f"{req} not in passport therefore INVALID")
invalid = True
break
if invalid == False:
print("VALID")
valid = valid + 1
print(f"Amount of valid passports is {valid}")
Day 4 – lisätehtävä
required = ["byr", "iyr", "eyr", "hgt", "hcl", "ecl", "pid"]
optional = ["cid"]
valid = 0
def check(req, value):
if req == "byr":
value = int(value)
if (len(str(value)) == 4) and (1920 <= value <= 2002):
return True
elif req == "iyr":
value = int(value)
if (len(str(value)) == 4) and (2010 <= value <= 2020):
return True
elif req == "eyr":
value = int(value)
if (len(str(value)) == 4) and (2020 <= value <= 2030):
return True
elif req == "hgt":
if value.endswith("cm"):
value = int(value.strip("cm"))
if 150 <= value <= 193:
return True
elif value.endswith("in"):
value = int(value.strip("in"))
if 59 <= value <= 76:
return True
elif req == "hcl":
nums=["0","1","2","3","4","5","6","7","8","9"]
letters=["a","b","c","d","e","f"]
chars = nums + letters
if (value.startswith("#")) and (len(value) == 7):
invalid = False
for i in range(1, len(value)):
if value[i] not in chars:
print("HAIR COLOR INVALID", value)
invalid = True
break
else:
continue
if invalid == False:
return True
elif req == "ecl":
colors = ["amb", "blu", "brn", "gry", "grn", "hzl", "oth"]
if value in colors:
return True
elif req == "pid":
if len(value) == 9:
return True
return False
for passport in text:
invalid = False
passport = passport.split()
passport = dict(s.split(":") for s in passport)
for req in required:
if req not in passport.keys():
invalid = True
break
else:
if check(req, passport[req]) == False:
invalid = True
break
if invalid == False:
valid = valid + 1
print(f"Amount of valid passports is {valid}")
Day 5
https://adventofcode.com/2020/day/5
answer = 0
for line in text:
first = line[0:7]
second = line[7:len(line)]
rang = [0, 127]
print(first)
for i in range(0, len(first)):
if first[i] == "F":
rang = [rang[0], rang[1] - ((rang[1] - rang[0]) / 2)]
elif first[i] == "B":
rang = [(rang[1] - rang[0]) / 2 + rang[0], rang[1]]
if rang[0] % 2 != 0:
rang[0] += 1
rang[0] = math.floor(rang[0])
rang[1] = math.floor(rang[1])
print(first[i], rang)
row = rang[0]
rang = [0, 7]
for i in range(0, len(second)):
if second[i] == "L":
rang = [rang[0], rang[1] - ((rang[1] - rang[0]) / 2)]
elif second[i] == "R":
rang = [(rang[1] - rang[0]) / 2 + rang[0], rang[1]]
if rang[0] % 2 != 0:
rang[0] += 1
rang[0] = math.floor(rang[0])
rang[1] = math.floor(rang[1])
print(second[i], rang)
column = rang[0]
if (row * 8) + column > answer:
answer = (row * 8) + column
print("Highest answer is", answer)
Day 5 – lisätehtävä
answer = 0
answers = []
for line in text:
if line == None:
continue
first = line[0:7]
second = line[7:len(line)]
rang = [0, 127]
for i in range(0, len(first)):
if first[i] == "F":
rang = [rang[0], rang[1] - ((rang[1] - rang[0]) / 2)]
elif first[i] == "B":
rang = [(rang[1] - rang[0]) / 2 + rang[0], rang[1]]
if rang[0] % 2 != 0:
rang[0] += 1
rang[0] = math.floor(rang[0])
rang[1] = math.floor(rang[1])
row = rang[0]
rang = [0, 7]
for i in range(0, len(second)):
if second[i] == "L":
rang = [rang[0], rang[1] - ((rang[1] - rang[0]) / 2)]
elif second[i] == "R":
rang = [(rang[1] - rang[0]) / 2 + rang[0], rang[1]]
if rang[0] % 2 != 0:
rang[0] += 1
rang[0] = math.floor(rang[0])
rang[1] = math.floor(rang[1])
column = rang[0]
answer = (row * 8) + column
answers.append(answer)
print("ID",answer)
answers.sort()
answers.remove(0)
for i in range(0, len(answers)):
if i+1 < len(answers):
if answers[i+1] - answers[i] != 1:
print("HEYHEYHEY!!")
print(answers[i-1])
print(answers[i], "MISSING AFTER THIS")
print(answers[i+1])
Day 6
https://adventofcode.com/2020/day/6
answer = 0
for group in text:
questions = []
people = group.split("\n")
group = group.replace("\n", "")
for letter in group:
if letter not in questions:
questions.append(letter)
answer += len(questions)
print(answer)
Day 6 – lisätehtävä
Tätä en saanut ratkaistua. Tässä kuitenkin keskeneräinen toimimaton koodi.
answer = 0
for group in text:
questions = []
GroupQuestions = []
people = group.split("\n")
if "" in people:
for i in range(0, len(people)):
if people[i] == "":
people.remove(people[i])
for i in range(0, len(people)):
for letter in people[i]:
if letter not in questions:
questions.append(letter)
j = 0
while j <= len(questions)-1:
print(j)
print(len(questions))
print("people:",people)
print("questions:", questions)
if questions[j] not in people[i]:
questions.remove(letter)
print("removed", letter)
print(questions)
print(j)
j = j+1
answer += len(questions)
print(answer)
Day 7
https://adventofcode.com/2020/day/7
Epäonnistui!
Day 8
https://adventofcode.com/2020/day/8
accumulator = 0
i = -1
beenTo = []
while i <= len(text):
i += 1
line = text[i]
if line == "":
continue
print(line)
if i in beenTo:
while True:
print(accumulator)
quit()
beenTo.append(i)
operation = line.split(" ")[0]
argument = line.split(" ")[1]
argumentPlusMinus = argument[0]
argumentNum = int(argument[1:])
if "acc" in operation:
if argumentPlusMinus == "+":
accumulator += argumentNum
else:
accumulator -= argumentNum
continue
elif "jmp" in operation:
if argumentPlusMinus == "+":
i += argumentNum - 1
else:
i -= argumentNum + 1
continue
elif "nop" in operation:
continue
print(accumulator)
Tästä eteenpäin tehtävistä tuli liian haastavia minulle! Yritin kuitenkin vielä jonkun verran, kunnes kiinnostus loppui ja unohdin koko sivuston.
Adventtikalenterini jäi tämän näköiseksi.
Ajatuksia
Nämä tehtävät olivat erittäin hyvää harjoitusta minunlaiselle aloittelevalle ohjelmoijalle.
