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