254 lines
4.2 KiB
Go
254 lines
4.2 KiB
Go
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")
|
|
}
|
|
*/
|