127 lines
3.0 KiB
Go
127 lines
3.0 KiB
Go
package main
|
|
|
|
import (
|
|
"AOC2021/src/helper"
|
|
"fmt"
|
|
"os"
|
|
)
|
|
|
|
type snailNumber struct {
|
|
pair [2]*snailNumber
|
|
val int
|
|
nested int
|
|
}
|
|
|
|
func main() {
|
|
args := os.Args[1:]
|
|
input, err := helper.GetInput(args[0])
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
}
|
|
var snailNumberArray []snailNumber
|
|
for _, row := range input {
|
|
number, _ := parseSnailNumber(row[1:], 0)
|
|
snailNumberArray = append(snailNumberArray, number)
|
|
}
|
|
fmt.Println(addSnailNumberStrings(input[0], input[1]))
|
|
fmt.Println(checkExplode("[[[[[9,8],1],2],3],4]"))
|
|
fmt.Println(checkExplode("[7,[6,[5,[4,[3,2]]]]]"))
|
|
fmt.Println(checkExplode("[[6,[5,[4,[3,2]]]],1]"))
|
|
|
|
}
|
|
|
|
func addSnailNumberStrings(left string, right string) string {
|
|
return "[" + left + "," + right + "]"
|
|
}
|
|
|
|
func checkExplode(snailNumberString string) (string, bool) {
|
|
index := 0
|
|
openBracketCounter := 0
|
|
for index < len(snailNumberString) {
|
|
char := snailNumberString[index]
|
|
index++
|
|
if char == '[' {
|
|
openBracketCounter++
|
|
}
|
|
if char == ']' {
|
|
openBracketCounter--
|
|
}
|
|
if runeIsNumber(rune(char)) && openBracketCounter >= 5 {
|
|
return explode(snailNumberString, index), true
|
|
}
|
|
}
|
|
return snailNumberString, false
|
|
}
|
|
|
|
func explode(snailNumberString string, location int) string {
|
|
returnString := snailNumberString[:location-2] + snailNumberString[location+3:]
|
|
addedLeft := false
|
|
positionLeft := location - 2
|
|
index := positionLeft - 1
|
|
for !addedLeft {
|
|
if returnString[index] == ',' {
|
|
tmpRuneArray := []rune(returnString)
|
|
tmpInt := snailNumberString[location-1] + returnString[index-1] - '0'
|
|
tmpRuneArray[index-1] = rune(tmpInt)
|
|
returnString = string(tmpRuneArray)
|
|
addedLeft = true
|
|
if positionLeft-1 == index {
|
|
positionLeft = index - 1
|
|
}
|
|
}
|
|
index--
|
|
if index == 0 {
|
|
returnString = returnString[:positionLeft] + string(rune(48)) + returnString[positionLeft:]
|
|
addedLeft = true
|
|
}
|
|
}
|
|
addedRight := false
|
|
positionRight := positionLeft + 2
|
|
index = positionLeft + 1
|
|
for !addedRight {
|
|
if returnString[index] == ',' {
|
|
tmpRuneArray := []rune(returnString)
|
|
tmpInt := snailNumberString[location+1] + returnString[index+1] - '0'
|
|
tmpRuneArray[index+1] = rune(tmpInt)
|
|
returnString = string(tmpRuneArray)
|
|
addedRight = true
|
|
}
|
|
index++
|
|
if index == len(returnString) {
|
|
returnString = returnString[:positionRight] + "," + string(rune(48)) + returnString[positionRight:]
|
|
addedRight = true
|
|
index = location - 1
|
|
}
|
|
}
|
|
return returnString
|
|
}
|
|
|
|
func parseSnailNumber(input string, nested int) (number snailNumber, index int) {
|
|
index = 0
|
|
number.nested = nested
|
|
currentPairToFill := &number.pair[0]
|
|
for index < len(input) {
|
|
char := input[index]
|
|
index++
|
|
if char == '[' {
|
|
tmpNumber, tmpIndex := parseSnailNumber(input[index:], nested+1)
|
|
index += tmpIndex
|
|
*currentPairToFill = &tmpNumber
|
|
}
|
|
if char == ',' {
|
|
currentPairToFill = &number.pair[1]
|
|
}
|
|
if runeIsNumber(rune(char)) {
|
|
(*currentPairToFill) = &snailNumber{[2]*snailNumber{}, int(char - '0'), nested + 1}
|
|
}
|
|
if char == ']' {
|
|
return
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func runeIsNumber(char rune) bool {
|
|
return char >= 48 && char <= 57
|
|
}
|