Started AOC 2020 - solved the first 4.5 days.
This commit is contained in:
parent
bab5f879b0
commit
04f29cdb4d
1
2020/.gitignore
vendored
Normal file
1
2020/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
build/
|
8
2020/Makefile
Normal file
8
2020/Makefile
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
all:
|
||||||
|
|
||||||
|
%: %.go
|
||||||
|
mkdir -p build/
|
||||||
|
go build -o build/$@ $<
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf build/
|
35
2020/day01.go
Normal file
35
2020/day01.go
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"git.annabunch.es/annabunches/adventofcode/2020/lib/fileutils"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
step := os.Args[1]
|
||||||
|
values := fileutils.InputParserIntMap(os.Args[2])
|
||||||
|
|
||||||
|
switch step {
|
||||||
|
case "1":
|
||||||
|
for x, _ := range values {
|
||||||
|
if _, ok := values[2020-x]; ok {
|
||||||
|
answer := x * (2020 - x)
|
||||||
|
fmt.Println("The answer is:", answer)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case "2":
|
||||||
|
for x, _ := range values {
|
||||||
|
target := 2020 - x
|
||||||
|
for y, _ := range values {
|
||||||
|
if _, ok := values[target-y]; ok {
|
||||||
|
answer := x * y * (target - y)
|
||||||
|
fmt.Println("The answer is:", answer)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
60
2020/day02.go
Normal file
60
2020/day02.go
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"git.annabunch.es/annabunches/adventofcode/2020/lib/fileutils"
|
||||||
|
)
|
||||||
|
|
||||||
|
func checkLine(line string, step string) int {
|
||||||
|
if line == "" {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
data := strings.Split(line, " ")
|
||||||
|
minMaxData := strings.Split(data[0], "-")
|
||||||
|
|
||||||
|
min, err := strconv.Atoi(minMaxData[0])
|
||||||
|
if err != nil {
|
||||||
|
log.Panicf(err.Error())
|
||||||
|
}
|
||||||
|
max, err := strconv.Atoi(minMaxData[1])
|
||||||
|
if err != nil {
|
||||||
|
log.Panicf(err.Error())
|
||||||
|
}
|
||||||
|
char := strings.TrimSuffix(data[1], ":")
|
||||||
|
|
||||||
|
switch step {
|
||||||
|
case "1":
|
||||||
|
count := strings.Count(data[2], char)
|
||||||
|
|
||||||
|
if count >= min && count <= max {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
case "2":
|
||||||
|
bchar := char[0]
|
||||||
|
if (data[2][min-1] == bchar || data[2][max-1] == bchar) &&
|
||||||
|
!(data[2][min-1] == bchar && data[2][max-1] == bchar) {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
step := os.Args[1]
|
||||||
|
values := fileutils.InputParserStrings(os.Args[2])
|
||||||
|
|
||||||
|
total := 0
|
||||||
|
for _, line := range values {
|
||||||
|
total += checkLine(line, step)
|
||||||
|
}
|
||||||
|
fmt.Println("Valid passwords:", total)
|
||||||
|
}
|
44
2020/day03.go
Normal file
44
2020/day03.go
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"git.annabunch.es/annabunches/adventofcode/2020/lib/fileutils"
|
||||||
|
)
|
||||||
|
|
||||||
|
func countTrees(input []string, right, down int) int {
|
||||||
|
x := 0
|
||||||
|
total := 0
|
||||||
|
for y, line := range input {
|
||||||
|
if y == 0 || len(line) == 0 || y%down != 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
x = (x + right) % len(line)
|
||||||
|
if line[x] == '#' {
|
||||||
|
total += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return total
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
step := os.Args[1]
|
||||||
|
values := fileutils.InputParserStrings(os.Args[2])
|
||||||
|
|
||||||
|
switch step {
|
||||||
|
case "1":
|
||||||
|
total := countTrees(values, 3, 1)
|
||||||
|
fmt.Println("Trees:", total)
|
||||||
|
case "2":
|
||||||
|
total := countTrees(values, 1, 1)
|
||||||
|
total *= countTrees(values, 3, 1)
|
||||||
|
total *= countTrees(values, 5, 1)
|
||||||
|
total *= countTrees(values, 7, 1)
|
||||||
|
total *= countTrees(values, 1, 2)
|
||||||
|
fmt.Println("Tree Product:", total)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
153
2020/day04.go
Normal file
153
2020/day04.go
Normal file
|
@ -0,0 +1,153 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"git.annabunch.es/annabunches/adventofcode/2020/lib/fileutils"
|
||||||
|
)
|
||||||
|
|
||||||
|
func splitPassports(input []string) []string {
|
||||||
|
converted := []string{}
|
||||||
|
|
||||||
|
current := ""
|
||||||
|
for _, line := range input {
|
||||||
|
if line == "" {
|
||||||
|
converted = append(converted, current)
|
||||||
|
current = ""
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
current += " " + line
|
||||||
|
}
|
||||||
|
|
||||||
|
return converted
|
||||||
|
}
|
||||||
|
|
||||||
|
func countValidPassports(input []string, step string) int {
|
||||||
|
total := 0
|
||||||
|
for _, line := range input {
|
||||||
|
if strings.Contains(line, "byr:") &&
|
||||||
|
strings.Contains(line, "iyr:") &&
|
||||||
|
strings.Contains(line, "eyr:") &&
|
||||||
|
strings.Contains(line, "hgt:") &&
|
||||||
|
strings.Contains(line, "hcl:") &&
|
||||||
|
strings.Contains(line, "ecl:") &&
|
||||||
|
strings.Contains(line, "pid:") {
|
||||||
|
if step == "1" {
|
||||||
|
total += 1
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
i := validatePassport(line)
|
||||||
|
if i == 0 {
|
||||||
|
log.Printf("Failed: %s", line)
|
||||||
|
} else {
|
||||||
|
log.Printf("Passed: %s", line)
|
||||||
|
}
|
||||||
|
|
||||||
|
total += i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return total
|
||||||
|
}
|
||||||
|
|
||||||
|
func validatePassport(input string) int {
|
||||||
|
fields := strings.Split(input, " ")
|
||||||
|
for _, field := range fields {
|
||||||
|
if field == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
subFields := strings.Split(field, ":")
|
||||||
|
if len(subFields) != 2 {
|
||||||
|
log.Panicf("Failed to split subfields on '%s'", field)
|
||||||
|
}
|
||||||
|
name := subFields[0]
|
||||||
|
value := subFields[1]
|
||||||
|
|
||||||
|
switch name {
|
||||||
|
case "byr":
|
||||||
|
ivalue := makeInt(value)
|
||||||
|
if ivalue < 1920 || ivalue > 2002 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
case "iyr":
|
||||||
|
ivalue := makeInt(value)
|
||||||
|
if ivalue < 2010 || ivalue > 2020 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
case "eyr":
|
||||||
|
ivalue := makeInt(value)
|
||||||
|
if ivalue < 2020 || ivalue > 2030 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
case "hgt":
|
||||||
|
if strings.HasSuffix(value, "cm") {
|
||||||
|
ivalue := makeInt(strings.TrimSuffix(value, "cm"))
|
||||||
|
if ivalue < 150 || ivalue > 193 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
} else if strings.HasSuffix(value, "in") {
|
||||||
|
ivalue := makeInt(strings.TrimSuffix(value, "in"))
|
||||||
|
if ivalue < 59 || ivalue > 76 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
case "hcl":
|
||||||
|
match, err := regexp.MatchString("^#[0-9a-f]{6}$", value)
|
||||||
|
if err != nil {
|
||||||
|
log.Panicf(err.Error())
|
||||||
|
}
|
||||||
|
if !match {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
case "ecl":
|
||||||
|
if value != "amb" &&
|
||||||
|
value != "blu" &&
|
||||||
|
value != "brn" &&
|
||||||
|
value != "gry" &&
|
||||||
|
value != "grn" &&
|
||||||
|
value != "hzl" &&
|
||||||
|
value != "oth" {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
case "pid":
|
||||||
|
match, err := regexp.MatchString("^[0-9]{9}$", value)
|
||||||
|
if err != nil {
|
||||||
|
log.Panicf(err.Error())
|
||||||
|
}
|
||||||
|
if !match {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
case "cid":
|
||||||
|
default:
|
||||||
|
log.Panicf("Got bad field data: ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeInt(input string) int {
|
||||||
|
i, err := strconv.Atoi(input)
|
||||||
|
if err != nil {
|
||||||
|
log.Panicf(err.Error())
|
||||||
|
}
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
step := os.Args[1]
|
||||||
|
values := fileutils.InputParserStrings(os.Args[2])
|
||||||
|
values = splitPassports(values)
|
||||||
|
|
||||||
|
fmt.Println("Valid Passports:", countValidPassports(values, step))
|
||||||
|
}
|
46
2020/day05.go
Normal file
46
2020/day05.go
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"git.annabunch.es/annabunches/adventofcode/2020/lib/fileutils"
|
||||||
|
)
|
||||||
|
|
||||||
|
func calculateSeatNumber(input string) int {
|
||||||
|
if input == "" {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
row, err := strconv.ParseInt(strings.ReplaceAll(strings.ReplaceAll(input[0:7], "F", "0"), "B", "1"), 2, 32)
|
||||||
|
if err != nil {
|
||||||
|
log.Panicf(err.Error())
|
||||||
|
}
|
||||||
|
col, err := strconv.ParseInt(strings.ReplaceAll(strings.ReplaceAll(input[7:10], "L", "0"), "R", "1"), 2, 32)
|
||||||
|
if err != nil {
|
||||||
|
log.Panicf(err.Error())
|
||||||
|
}
|
||||||
|
return int((row * 8) + col)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
step := os.Args[1]
|
||||||
|
values := fileutils.InputParserStrings(os.Args[2])
|
||||||
|
|
||||||
|
switch step {
|
||||||
|
case "1":
|
||||||
|
max := 0
|
||||||
|
for _, line := range values {
|
||||||
|
seatNumber := calculateSeatNumber(line)
|
||||||
|
if seatNumber > max {
|
||||||
|
max = seatNumber
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Println("Highest Seat Number:", max)
|
||||||
|
case "2":
|
||||||
|
// build a map of all seat numbers then just print the ones between 0 and 1024 that don't exist
|
||||||
|
}
|
||||||
|
}
|
3
2020/go.mod
Normal file
3
2020/go.mod
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
module git.annabunch.es/annabunches/adventofcode/2020
|
||||||
|
|
||||||
|
go 1.15
|
39
2020/lib/fileutils/fileutils.go
Normal file
39
2020/lib/fileutils/fileutils.go
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
package fileutils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func InputParserIntMap(filename string) map[int]bool {
|
||||||
|
file, err := os.Open(filename)
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Panicf(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
values := make(map[int]bool)
|
||||||
|
scanner := bufio.NewScanner(file)
|
||||||
|
for scanner.Scan() {
|
||||||
|
x, err := strconv.Atoi(scanner.Text())
|
||||||
|
if err != nil {
|
||||||
|
log.Panicf(err.Error())
|
||||||
|
}
|
||||||
|
values[x] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
return values
|
||||||
|
}
|
||||||
|
|
||||||
|
func InputParserStrings(filename string) []string {
|
||||||
|
data, err := ioutil.ReadFile(filename)
|
||||||
|
if err != nil {
|
||||||
|
log.Panicf(err.Error())
|
||||||
|
}
|
||||||
|
return strings.Split(string(data), "\n")
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user