mirror of
https://github.com/cupcakearmy/advent-of-code.git
synced 2025-09-03 13:50:40 +00:00
move to 2020 fodler
This commit is contained in:
14
2020/solutions/4/README.md
Normal file
14
2020/solutions/4/README.md
Normal file
@@ -0,0 +1,14 @@
|
||||
# 4
|
||||
|
||||
This one was a lot of parsing, but nothing regexp can't do.
|
||||
The first is quite straight forward, just check that all but `cid` are present.
|
||||
|
||||
The second was a bit of validation for each field, but again some simple regexp and number checking and the job is done 🙂
|
||||
|
||||
<details>
|
||||
<summary>Solutions</summary>
|
||||
<ol>
|
||||
<li>206</li>
|
||||
<li>123</li>
|
||||
</ol>
|
||||
</details>
|
103
2020/solutions/4/go/main.go
Normal file
103
2020/solutions/4/go/main.go
Normal file
@@ -0,0 +1,103 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
k "github.com/wesovilabs/koazee"
|
||||
)
|
||||
|
||||
type tPassport = map[string]string
|
||||
|
||||
func stringBetween(s string, min, max int) bool {
|
||||
num, _ := strconv.Atoi(s)
|
||||
return min <= num && num <= max
|
||||
}
|
||||
|
||||
func verifyPassport(passport tPassport) (bool, bool) {
|
||||
requiredKeys := k.StreamOf([]string{"byr", "iyr", "eyr", "hgt", "hcl", "ecl", "pid"})
|
||||
eyeColors := k.StreamOf([]string{"amb", "blu", "brn", "gry", "grn", "hzl", "oth"})
|
||||
|
||||
// Simple
|
||||
counted := 0
|
||||
for k := range passport {
|
||||
if k == "cid" {
|
||||
continue
|
||||
}
|
||||
included, _ := requiredKeys.Contains(k)
|
||||
if !included {
|
||||
return false, false
|
||||
}
|
||||
counted++
|
||||
}
|
||||
if counted < 7 {
|
||||
return false, false
|
||||
}
|
||||
|
||||
// Complex
|
||||
if !stringBetween(passport["byr"], 1920, 2002) || !stringBetween(passport["iyr"], 2010, 2020) || !stringBetween(passport["eyr"], 2020, 2030) {
|
||||
return true, false
|
||||
}
|
||||
|
||||
tmp := []rune(passport["hgt"])
|
||||
hgtLen := len(tmp)
|
||||
hgt, _ := strconv.Atoi(string(tmp[0 : hgtLen-2]))
|
||||
unit := string(tmp[hgtLen-2:])
|
||||
if unit != "cm" && unit != "in" {
|
||||
return true, false
|
||||
}
|
||||
if unit == "cm" && (hgt < 150 || hgt > 193) {
|
||||
return true, false
|
||||
}
|
||||
if unit == "in" && (hgt < 59 || hgt > 76) {
|
||||
return true, false
|
||||
}
|
||||
|
||||
if !regexp.MustCompile(`^#[\dabdcdef]{6}$`).MatchString(passport["hcl"]) {
|
||||
return true, false
|
||||
}
|
||||
if !regexp.MustCompile(`^\d{9}$`).MatchString(passport["pid"]) {
|
||||
return true, false
|
||||
}
|
||||
|
||||
ecl, _ := eyeColors.Contains(passport["ecl"])
|
||||
if !ecl {
|
||||
return true, false
|
||||
}
|
||||
|
||||
return true, true
|
||||
}
|
||||
|
||||
func main() {
|
||||
data, _ := ioutil.ReadFile("./solutions/4/data.txt")
|
||||
passportsRaw := strings.Split(strings.TrimSpace(string(data)), "\n\n")
|
||||
passports := []tPassport{}
|
||||
|
||||
re := regexp.MustCompile(`\n|\s`)
|
||||
for _, passportRaw := range passportsRaw {
|
||||
passport := tPassport{}
|
||||
entries := re.Split(passportRaw, -1)
|
||||
for _, entry := range entries {
|
||||
split := strings.Split(entry, ":")
|
||||
passport[split[0]] = split[1]
|
||||
}
|
||||
passports = append(passports, passport)
|
||||
}
|
||||
|
||||
validSimple := 0
|
||||
validComplex := 0
|
||||
for _, passport := range passports {
|
||||
simple, complex := verifyPassport(passport)
|
||||
if simple {
|
||||
validSimple++
|
||||
}
|
||||
if complex {
|
||||
validComplex++
|
||||
}
|
||||
}
|
||||
fmt.Println("Simple Validation:\t", validSimple)
|
||||
fmt.Println("Extended Validation:\t", validComplex)
|
||||
}
|
52
2020/solutions/4/python/main.py
Normal file
52
2020/solutions/4/python/main.py
Normal file
@@ -0,0 +1,52 @@
|
||||
from os.path import join, dirname
|
||||
import re
|
||||
|
||||
|
||||
def validate_chunk(chunk, extended=False):
|
||||
parts = re.split(' |\n', chunk.strip())
|
||||
password = dict(map(lambda p: p.split(":"), parts))
|
||||
|
||||
required = ['byr', 'iyr', 'eyr', 'hgt', 'hcl', 'ecl', 'pid']
|
||||
if not all(item in password.keys() for item in required):
|
||||
return False
|
||||
|
||||
if not extended:
|
||||
return True
|
||||
|
||||
if not 1920 <= int(password['byr']) <= 2002:
|
||||
return False
|
||||
if not 2010 <= int(password['iyr']) <= 2020:
|
||||
return False
|
||||
if not 2020 <= int(password['eyr']) <= 2030:
|
||||
return False
|
||||
|
||||
tmp = password['hgt']
|
||||
hgt = int(tmp[:-2])
|
||||
unit = tmp[-2:]
|
||||
if not unit in ['cm', 'in']:
|
||||
return False
|
||||
if unit == 'cm' and not 150 <= hgt <= 193:
|
||||
return False
|
||||
if unit == 'in' and not 59 <= hgt <= 76:
|
||||
return False
|
||||
|
||||
if not re.match(r'^#[\dabcdef]{6}$', password['hcl']):
|
||||
return False
|
||||
if not re.match(r'^\d{9}$', password['pid']):
|
||||
return False
|
||||
|
||||
if password['ecl'] not in ['amb', 'blu', 'brn', 'gry', 'grn', 'hzl', 'oth']:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
data = join(dirname(__file__), '../data.txt')
|
||||
with open(data) as f:
|
||||
chunks = re.split('\n\n+', f.read().strip())
|
||||
total_simple = 0
|
||||
total_extended = 0
|
||||
for chunk in chunks:
|
||||
total_simple += int(validate_chunk(chunk))
|
||||
total_extended += int(validate_chunk(chunk, extended=True))
|
||||
print(f'Simple Validation:\t{total_simple}')
|
||||
print(f'Extended Validation:\t{total_extended}')
|
Reference in New Issue
Block a user