day nineteen checkpoint. Doesn't work yet.
This commit is contained in:
parent
9821836b6c
commit
d2b4bc2921
175
19/main.go
Normal file
175
19/main.go
Normal file
@ -0,0 +1,175 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
start := time.Now()
|
||||
partOne()
|
||||
duration := time.Since(start)
|
||||
partTwo()
|
||||
duration2 := time.Since(start)
|
||||
fmt.Printf("p1: %s, p2: %s\n", duration, duration2-duration)
|
||||
}
|
||||
|
||||
// options: 20 => [][20]; 20 10 => [][20, 10]; 20 | 10 => [][20][10]; 20 10 | 39 12 => [][20, 10][39, 12];
|
||||
// token is only set for the two "bottom" rules of "a" and "b"
|
||||
// options and token will never both be set
|
||||
// ints all point to rule numbers in overall rule list
|
||||
type rule struct {
|
||||
name int
|
||||
options [][]int
|
||||
token rune
|
||||
}
|
||||
|
||||
func parseRule(s string) rule {
|
||||
r := rule{
|
||||
options: make([][]int, 0),
|
||||
}
|
||||
sp := strings.Split(s, ": ")
|
||||
r.name, _ = strconv.Atoi(sp[0])
|
||||
|
||||
// either it's a token rule...
|
||||
if sp[1] == `"a"` || sp[1] == `"b"` {
|
||||
r.token = []rune(strings.Trim(sp[1], `"`))[0]
|
||||
return r
|
||||
}
|
||||
|
||||
// ...or an options rule.
|
||||
opts := strings.Split(sp[1], " | ")
|
||||
for _, o := range opts {
|
||||
opt := []int{}
|
||||
for _, i := range strings.Split(o, " ") {
|
||||
ii, _ := strconv.Atoi(i)
|
||||
opt = append(opt, ii)
|
||||
}
|
||||
r.options = append(r.options, opt)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func validateString(rules []rule, currentRule int, s string) (bool, string) {
|
||||
activeRule := rules[currentRule]
|
||||
// if we're run out of string, the rule obviously cannot match
|
||||
if len(s) == 0 {
|
||||
return false, ""
|
||||
}
|
||||
// we've reached a leaf; check if the current head of the string matches our expected rune
|
||||
if len(activeRule.options) == 0 {
|
||||
return []rune(s)[0] == activeRule.token, s[1:]
|
||||
}
|
||||
// if there's only one option, attempt to apply the rules
|
||||
if len(activeRule.options) == 1 {
|
||||
option := activeRule.options[0]
|
||||
if len(option) == 1 {
|
||||
return validateString(rules, option[0], s)
|
||||
}
|
||||
if len(option) == 2 {
|
||||
ok, remainder := validateString(rules, option[0], s)
|
||||
if ok {
|
||||
return validateString(rules, option[1], remainder)
|
||||
}
|
||||
}
|
||||
if len(option) == 3 {
|
||||
ok, remainder := validateString(rules, option[0], s)
|
||||
if ok {
|
||||
ok, remainder = validateString(rules, option[1], remainder)
|
||||
}
|
||||
if ok {
|
||||
return validateString(rules, option[2], remainder)
|
||||
}
|
||||
}
|
||||
}
|
||||
// otherwise, we need to branch into our options and try and apply their rules
|
||||
if len(activeRule.options) == 2 {
|
||||
ok := false
|
||||
remainder := ""
|
||||
optionOne := activeRule.options[0]
|
||||
if len(optionOne) == 1 {
|
||||
ok, remainder = validateString(rules, optionOne[0], s)
|
||||
}
|
||||
if len(optionOne) == 2 {
|
||||
ok, remainder = validateString(rules, optionOne[0], s)
|
||||
if ok {
|
||||
ok, remainder = validateString(rules, optionOne[1], remainder)
|
||||
}
|
||||
}
|
||||
if len(optionOne) == 3 {
|
||||
ok, remainder = validateString(rules, optionOne[0], s)
|
||||
if ok {
|
||||
ok, remainder = validateString(rules, optionOne[1], remainder)
|
||||
}
|
||||
if ok {
|
||||
ok, remainder = validateString(rules, optionOne[2], remainder)
|
||||
}
|
||||
}
|
||||
if ok {
|
||||
return ok, remainder
|
||||
}
|
||||
optionTwo := activeRule.options[1]
|
||||
if len(optionTwo) == 1 {
|
||||
ok, _ = validateString(rules, optionTwo[0], s)
|
||||
}
|
||||
if len(optionTwo) == 2 {
|
||||
ok, remainder = validateString(rules, optionTwo[0], s)
|
||||
if ok {
|
||||
return validateString(rules, optionTwo[1], remainder)
|
||||
}
|
||||
}
|
||||
if len(optionTwo) == 3 {
|
||||
ok, remainder = validateString(rules, optionTwo[0], s)
|
||||
if ok {
|
||||
ok, remainder = validateString(rules, optionTwo[1], remainder)
|
||||
}
|
||||
if ok {
|
||||
return validateString(rules, optionTwo[2], remainder)
|
||||
}
|
||||
}
|
||||
}
|
||||
return false, s
|
||||
}
|
||||
|
||||
func partOne() {
|
||||
f, _ := os.Open("input")
|
||||
reader := bufio.NewReader(f)
|
||||
scanner := bufio.NewScanner(reader)
|
||||
|
||||
rules := make([]rule, 134)
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
if line == "" {
|
||||
break
|
||||
}
|
||||
rule := parseRule(line)
|
||||
rules[rule.name] = rule
|
||||
}
|
||||
|
||||
total := 0
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
if ok, _ := validateString(rules, 0, line); ok {
|
||||
fmt.Println("VALID:", line)
|
||||
total = total + 1
|
||||
} else {
|
||||
fmt.Println("INVALID:", line)
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println(total)
|
||||
}
|
||||
|
||||
func partTwo() {
|
||||
f, _ := os.Open("input")
|
||||
reader := bufio.NewReader(f)
|
||||
scanner := bufio.NewScanner(reader)
|
||||
|
||||
for scanner.Scan() {
|
||||
// line := scanner.Text()
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user