Add 2020-02

Signed-off-by: AKU <tom@tdpain.net>
This commit is contained in:
akp 2021-11-27 19:56:01 +00:00
parent 2413554b24
commit c8fd7ad9ba
No known key found for this signature in database
GPG key ID: AA5726202C8879B7
5 changed files with 266 additions and 0 deletions

View file

@ -0,0 +1,31 @@
# [Day 2: Password Philosophy](https://adventofcode.com/2020/day/2)
<details><summary>Script output</summary>
```
python .\python\
AoC 2020: day 2 - Password Philosophy
Python 3.8.5
Test cases
1.1 pass
2.1 pass
Answers
Part 1: 500
Part 2: 313
go run .\go\
AoC 2020: day 2 - Password Philosophy
Go go1.15.2
Test cases
1.1 pass
2.1 pass
Answers
Part 1: 500
Part 2: 313
```
</details>

View file

@ -0,0 +1,23 @@
Day 2 (Password Philosophy) benchmark
Dir: challenges/2020/02-passwordPhilosophy
Runs per part: 50
--------------------------------------------------------------------------------
Golang
benchmark.part.1.avg: 0.001280 seconds
benchmark.part.1.min: 0.000806 seconds
benchmark.part.1.max: 0.002234 seconds
benchmark.part.2.avg: 0.001383 seconds
benchmark.part.2.min: 0.000786 seconds
benchmark.part.2.max: 0.005438 seconds
--------------------------------------------------------------------------------
Python
benchmark.part.1.avg: 0.005367 seconds
benchmark.part.1.min: 0.002311 seconds
benchmark.part.1.max: 0.010500 seconds
benchmark.part.2.avg: 0.004618 seconds
benchmark.part.2.min: 0.001737 seconds
benchmark.part.2.max: 0.011591 seconds
--------------------------------------------------------------------------------

View file

@ -0,0 +1,97 @@
package challenge
import (
"regexp"
"strconv"
"strings"
"github.com/codemicro/adventOfCode/lib/aocgo"
)
type Challenge struct {
aocgo.BaseChallenge
}
func (c Challenge) One(instr string) (interface{}, error) {
inputSlice := parse(instr)
type Password struct {
plaintext string
targetLetter rune
minRepeats int
maxRepeats int
}
var passwords []Password
for _, line := range inputSlice {
matches := parserRegex.FindAllStringSubmatch(line, -1)
miR, _ := strconv.Atoi(matches[0][1])
maR, _ := strconv.Atoi(matches[0][2])
passwords = append(passwords, Password{
plaintext: matches[0][4],
targetLetter: rune(matches[0][3][0]),
minRepeats: miR,
maxRepeats: maR,
})
}
var num_valid_passwords int
for _, password := range passwords {
var target_letter_count int
for _, char := range password.plaintext {
if char == password.targetLetter {
target_letter_count += 1
}
}
if (target_letter_count >= password.minRepeats) && (target_letter_count <= password.maxRepeats) {
num_valid_passwords += 1
}
}
return num_valid_passwords, nil
}
func (c Challenge) Two(instr string) (interface{}, error) {
inputSlice := parse(instr)
type Password struct {
plaintext string
targetLetter rune
positionOne int
positionTwo int
}
var passwords []Password
for _, line := range inputSlice {
matches := parserRegex.FindAllStringSubmatch(line, -1)
miR, _ := strconv.Atoi(matches[0][1])
maR, _ := strconv.Atoi(matches[0][2])
passwords = append(passwords, Password{
plaintext: matches[0][4],
targetLetter: rune(matches[0][3][0]),
positionOne: miR - 1,
positionTwo: maR - 1,
})
}
var num_valid_passwords int
for _, password := range passwords {
positionOneMatches := rune(password.plaintext[password.positionOne]) == password.targetLetter
positionTwoMatches := rune(password.plaintext[password.positionTwo]) == password.targetLetter
if positionOneMatches != positionTwoMatches {
num_valid_passwords += 1
}
}
return num_valid_passwords, nil
}
func parse(instr string) []string {
return strings.Split(strings.TrimSpace(string(instr)), "\n")
}
var parserRegex = regexp.MustCompile(`(?m)(\d+)-(\d+) ([a-z]): (.+)`)

View file

@ -0,0 +1,17 @@
{
"inputFile": "input.txt",
"testCases": {
"one": [
{
"input": "1-3 a: abcde\n1-3 b: cdefg\n2-9 c: ccccccccc",
"expected": "2"
}
],
"two": [
{
"input": "1-3 a: abcde\n1-3 b: cdefg\n2-9 c: ccccccccc",
"expected": "1"
}
]
}
}

View file

@ -0,0 +1,98 @@
import re
from typing import List
from aocpy import BaseChallenge
class Challenge(BaseChallenge):
@staticmethod
def one(instr: str) -> int:
input_string = parse(instr)
class Password:
plaintext: str
target_letter: str
min_repeats: int
max_repeats: int
def __init__(
self, plaintext: str, target_letter: str, min_repeats: int, max_repeats: int
) -> None:
self.plaintext = plaintext
self.target_letter = target_letter
self.min_repeats = min_repeats
self.max_repeats = max_repeats
parser_regex = r"(\d+)-(\d+) ([a-z]): (.+)"
passwords = []
for line in input_string:
m = re.match(parser_regex, line)
passwords.append(
Password(m.group(4), m.group(3), int(m.group(1)), int(m.group(2)))
)
num_valid_passwords = 0
for password in passwords:
target_letter_count = 0
for char in password.plaintext:
if char == password.target_letter:
target_letter_count += 1
if password.min_repeats <= target_letter_count <= password.max_repeats:
num_valid_passwords += 1
return num_valid_passwords
@staticmethod
def two(instr: str) -> int:
input_string = parse(instr)
class Password:
plaintext: str
target_letter: str
position_one: int
position_two: int
def __init__(
self,
plaintext: str,
target_letter: str,
position_one: int,
position_two: int,
) -> None:
self.plaintext = plaintext
self.target_letter = target_letter
self.position_one = position_one - 1 # No concept of index zero... eurgh
self.position_two = position_two - 1
parser_regex = r"(\d+)-(\d+) ([a-z]): (.+)"
passwords = []
for line in input_string:
m = re.match(parser_regex, line)
passwords.append(
Password(m.group(4), m.group(3), int(m.group(1)), int(m.group(2)))
)
num_valid_passwords = 0
for password in passwords:
position_one_matches = (
password.plaintext[password.position_one] == password.target_letter
)
position_two_matches = (
password.plaintext[password.position_two] == password.target_letter
)
if position_one_matches ^ position_two_matches:
num_valid_passwords += 1
return num_valid_passwords
def parse(instr: str) -> List:
return instr.strip().split("\n")