Big update: Adding all advent of codes to same repo
This commit is contained in:
115
AdventOfCode2020/day19/day19.go
Normal file
115
AdventOfCode2020/day19/day19.go
Normal file
@@ -0,0 +1,115 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func GetRule(rules *map[string]string, r string) string {
|
||||
rule := (*rules)[r]
|
||||
|
||||
if strings.Contains(rule, `"`) {
|
||||
// Base case
|
||||
matchLetter := rule[1 : len(rule)-1]
|
||||
return matchLetter
|
||||
}
|
||||
|
||||
alternates := strings.Split(rule, " | ")
|
||||
|
||||
if len(alternates) == 1 {
|
||||
ruleNumbers := strings.Split(alternates[0], " ")
|
||||
str := ""
|
||||
for _, n := range ruleNumbers {
|
||||
str += GetRule(rules, n)
|
||||
}
|
||||
return str
|
||||
}
|
||||
|
||||
if len(alternates) > 1 {
|
||||
ruleNumbers := strings.Split(alternates[0], " ")
|
||||
firstAlternate := ""
|
||||
for _, n := range ruleNumbers {
|
||||
firstAlternate += GetRule(rules, n)
|
||||
}
|
||||
|
||||
ruleNumbers = strings.Split(alternates[1], " ")
|
||||
secondAlternate := ""
|
||||
for _, n := range ruleNumbers {
|
||||
secondAlternate += GetRule(rules, n)
|
||||
}
|
||||
|
||||
return fmt.Sprintf("(%s|%s)", firstAlternate, secondAlternate)
|
||||
}
|
||||
|
||||
panic("should never be here")
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
content, err := os.ReadFile("./input.txt")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
splitInput := strings.Split(string(content), "\n\n")
|
||||
rules := strings.Split(splitInput[0], "\n")
|
||||
|
||||
ruleMap := make(map[string]string)
|
||||
|
||||
for _, rule := range rules {
|
||||
splitRule := strings.Split(rule, ": ")
|
||||
ruleNumber := splitRule[0]
|
||||
|
||||
ruleMap[ruleNumber] = splitRule[1]
|
||||
}
|
||||
|
||||
tests := splitInput[1]
|
||||
tests = tests[0 : len(tests)-1]
|
||||
|
||||
zeroRule := regexp.MustCompile("^" + GetRule(&ruleMap, "0") + "$")
|
||||
|
||||
matches := 0
|
||||
for _, t := range strings.Split(tests, "\n") {
|
||||
if zeroRule.Match([]byte(t)) {
|
||||
matches++
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf("Part 1: %d\n", matches)
|
||||
|
||||
fRule := regexp.MustCompile(GetRule(&ruleMap, "42"))
|
||||
tRule := regexp.MustCompile(GetRule(&ruleMap, "31"))
|
||||
|
||||
matches = 0
|
||||
for _, t := range strings.Split(tests, "\n") {
|
||||
|
||||
// rule 0 = 8 11
|
||||
// 8 = 42+
|
||||
// 11 = 42{n} 31{n}
|
||||
// Therefore: 0 = 42 {n*2} 31{n}
|
||||
|
||||
fortyTwoMatch := fRule.FindStringIndex(t)
|
||||
fortyTwoCount := 0
|
||||
for fortyTwoMatch != nil && fortyTwoMatch[0] == 0 {
|
||||
t = t[fortyTwoMatch[1]:]
|
||||
fortyTwoMatch = fRule.FindStringIndex(t)
|
||||
fortyTwoCount++
|
||||
}
|
||||
|
||||
thirtyMatch := tRule.FindStringIndex(t)
|
||||
thirtyCount := 0
|
||||
for thirtyMatch != nil && thirtyMatch[0] == 0 {
|
||||
t = t[thirtyMatch[1]:]
|
||||
thirtyMatch = tRule.FindStringIndex(t)
|
||||
thirtyCount++
|
||||
}
|
||||
|
||||
if len(t) == 0 && thirtyCount > 0 && fortyTwoCount > thirtyCount {
|
||||
matches++
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf("Part 2: %d\n", matches)
|
||||
}
|
||||
253
AdventOfCode2020/day19/main.go
Normal file
253
AdventOfCode2020/day19/main.go
Normal file
@@ -0,0 +1,253 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var THREE_SIMPLE_RULE = `
|
||||
func Rule%s(message string, index *int) error {
|
||||
err := Rule%s(message, index)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = Rule%s(message, index)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = Rule%s(message, index)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
`
|
||||
|
||||
var SIMPLE_RULE = `
|
||||
func Rule%s(message string, index *int) error {
|
||||
err := Rule%s(message, index)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = Rule%s(message, index)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
`
|
||||
|
||||
var ONE_SIMPLE_RULE = `
|
||||
func Rule%s(message string, index *int) error {
|
||||
err := Rule%s(message, index)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
`
|
||||
|
||||
var ALTERNATE_RULE = `
|
||||
func Rule%s(message string, index *int) error {
|
||||
indexCopy := *index
|
||||
err := Rule%sFirst(message, &indexCopy)
|
||||
|
||||
if err == nil {
|
||||
*index = indexCopy
|
||||
return nil
|
||||
}
|
||||
|
||||
err = Rule%sSecond(message, index)
|
||||
return err
|
||||
}
|
||||
%s
|
||||
%s
|
||||
`
|
||||
|
||||
var LITERAL_RULE = `
|
||||
func Rule%s(message string, index *int) error {
|
||||
if len(message) <= *index {
|
||||
return errors.New("out of bounds")
|
||||
}
|
||||
|
||||
if string(message[*index]) == "%c" {
|
||||
*index++
|
||||
return nil
|
||||
}
|
||||
return errors.New("Could not match")
|
||||
}
|
||||
`
|
||||
|
||||
func main() {
|
||||
content, err := os.ReadFile("./input.txt")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
splitInput := strings.Split(string(content), "\n\n")
|
||||
|
||||
program := `
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func main() {
|
||||
content, err := os.ReadFile("./input.txt")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
splitInput := strings.Split(string(content), "\n\n")
|
||||
toTry := splitInput[1]
|
||||
counter := 0
|
||||
|
||||
toTrySplit := strings.Split(toTry, "\n")
|
||||
|
||||
for _, v := range toTrySplit[0: len(toTrySplit) - 1] {
|
||||
index := 0
|
||||
err := Rule0(v, &index)
|
||||
if err == nil && index == len(v) {
|
||||
counter++
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println(counter)
|
||||
}
|
||||
`
|
||||
|
||||
rules := strings.Split(splitInput[0], "\n")
|
||||
for _, v := range rules {
|
||||
|
||||
/*
|
||||
if v == "8: 42" {
|
||||
v = "8: 42 | 42 8"
|
||||
} else if v == "11: 42 31" {
|
||||
v = "11: 42 31 | 42 11 31"
|
||||
}
|
||||
*/
|
||||
|
||||
program += CreateRule(v)
|
||||
}
|
||||
|
||||
err = os.WriteFile("./parser.go", []byte(program), 0777)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func CreateRule(rule string) (string) {
|
||||
splitRule := strings.Split(rule, ": ")
|
||||
ruleNumber := splitRule[0]
|
||||
|
||||
rules := strings.Split(splitRule[1], " | ")
|
||||
|
||||
if (len(rules) == 1) {
|
||||
return CreateSingleRule(ruleNumber, rules[0])
|
||||
}
|
||||
|
||||
return fmt.Sprintf(ALTERNATE_RULE, ruleNumber, ruleNumber, ruleNumber, CreateSingleRule(ruleNumber + "First", rules[0]), CreateSingleRule(ruleNumber + "Second", rules[1]))
|
||||
}
|
||||
|
||||
// Single rule (4 5) or ("a")
|
||||
func CreateSingleRule(ruleNumber string, rule string) string {
|
||||
if string(rule[0]) == string('"') {
|
||||
return fmt.Sprintf(LITERAL_RULE, ruleNumber, rule[1])
|
||||
}
|
||||
|
||||
nums := strings.Split(rule, " ")
|
||||
|
||||
if len(nums) == 3 {
|
||||
return fmt.Sprintf(THREE_SIMPLE_RULE, ruleNumber, nums[0], nums[1], nums[2])
|
||||
} else if (len(nums) == 2) {
|
||||
return fmt.Sprintf(SIMPLE_RULE, ruleNumber, nums[0], nums[1])
|
||||
}
|
||||
|
||||
return fmt.Sprintf(ONE_SIMPLE_RULE, ruleNumber, nums[0])
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
func Rule0(message string, index *int) error {
|
||||
err := Rule1(message, index)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err := Rule2(message, index)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func Rule2(message string, index *int) error {
|
||||
indexCopy := *index
|
||||
err := Rule2First(message, &indexCopy)
|
||||
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
err = Rule2Second(message, index)
|
||||
return err
|
||||
}
|
||||
|
||||
func Rule2First(message string, index *int) error {
|
||||
err := Rule1(message, index)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err := Rule3(message, index)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func Rule2Second(message string, index *int) error {
|
||||
err := Rule3(message, index)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err := Rule1(message, index)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func Rule3(message string, index *int) errro {
|
||||
if message[*index] == "b" {
|
||||
x := 5
|
||||
y := &x
|
||||
*y = *y + 1
|
||||
fmt.Println(x)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func Rule3(message string, index *int) error {
|
||||
if string(message[*index]) == "b" {
|
||||
*index++
|
||||
return nil
|
||||
}
|
||||
return errors.New("Could not match")
|
||||
}
|
||||
*/
|
||||
1056
AdventOfCode2020/day19/parser.go
Executable file
1056
AdventOfCode2020/day19/parser.go
Executable file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user