RYELL5E4C3USLBBYJGITRHGLLIN4FCU76JUFHVWGYHZNSCKGBT5AC package mainimport ("bufio""log""math""os""regexp""strconv""strings")func main() {if err := myMain(); err != nil {log.Println(err)}}func myMain() error {testExplode := []struct {in stringout string}{{"[[[[[9,8],1],2],3],4]", "[[[[0,9],2],3],4]"},{"[7,[6,[5,[4,[3,2]]]]]", "[7,[6,[5,[7,0]]]]"},{"[[6,[5,[4,[3,2]]]],1]", "[[6,[5,[7,0]]],3]"},{"[[3,[2,[1,[7,3]]]],[6,[5,[4,[3,2]]]]]", "[[3,[2,[8,0]]],[9,[5,[4,[3,2]]]]]"},{"[[3,[2,[8,0]]],[9,[5,[4,[3,2]]]]]", "[[3,[2,[8,0]]],[9,[5,[7,0]]]]"},{"[[[[[4,3],4],4],[7,[[8,4],9]]],[1,1]]", "[[[[0,7],4],[7,[[8,4],9]]],[1,1]]"},{"[[[[0,7],4],[7,[[8,4],9]]],[1,1]]", "[[[[0,7],4],[15,[0,13]]],[1,1]]"},{"[[[[0,7],4],[[7,8],[0,[6,7]]]],[1,1]]", "[[[[0,7],4],[[7,8],[6,0]]],[8,1]]"},}for _, tc := range testExplode {got := explode(tc.in)if got != tc.out {log.Fatalf("\nwant:\t%q\ngot:\t%q", tc.out, got)}}testMagnitude := []struct {in stringout int}{{"[[1,2],[[3,4],5]]", 143},{"[[[[1,1],[2,2]],[3,3]],[4,4]]", 445},{"[[[[0,7],4],[[7,8],[6,0]]],[8,1]]", 1384},{"[[[[8,7],[7,7]],[[8,6],[7,7]]],[[[0,7],[6,6]],[8,7]]]", 3488},}for _, tc := range testMagnitude {got, _ := magnitude(tc.in, 0)if got != tc.out {log.Fatalf("\nwant:\t%d\ngot:\t%d", tc.out, got)}}in, err := parseInput("input.txt")if err != nil {return err}var ret stringfor _, st := range in {if ret == "" {ret = st} else {ret = reduce("[" + ret + "," + st + "]")}}log.Println(magnitude(ret, 0))return nil}func magnitude(in string, pos int) (int, int) {left, right := -1, -1var rght boolvar skip intfor i := pos; i < len(in); i++ {if in[i] == ']' {skip = i - pos + 1break}if in[i] == '[' {var p intif rght {right, p = magnitude(in, i+1)} else {left, p = magnitude(in, i+1)}i += pcontinue}switch in[i] {case ',':rght = truecase '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':tmp, err := strconv.Atoi(string(in[i]))if err != nil {log.Panicln(err)}if rght {right = tmp} else {left = tmp}}}// log.Println("RETURN:", left, right)if left == -1 || right == -1 {return left + right + 1, skip}return 3*left + 2*right, skip}func reduce(in string) string {if next := explode(in); next != in {in = reduce(next)} else if next := split(in); next != in {in = reduce(next)}return in}func explode(in string) string {var count intfor i, ch := range in {if ch == '[' {count++if count == 5 {return doExplode(in, i)}}if ch == ']' {count--}}return in}var number = regexp.MustCompile(`\d+`)func doExplode(in string, pivot int) string {// log.Println(in[:pivot], in[pivot:])lefts := number.FindAllStringSubmatchIndex(in[:pivot+1], -1)rights := number.FindAllStringSubmatchIndex(in[pivot:], 3)// log.Println("L:", lefts, "R:", rights)// Exploding left item: 1st from rightsexpLeft := []int{pivot + rights[0][0], pivot + rights[0][1]}// Exploding right item: 2nd from rightsexpRight := []int{pivot + rights[1][0], pivot + rights[1][1]}var l, r []intif len(lefts) > 0 {l = []int{lefts[len(lefts)-1][0], lefts[len(lefts)-1][1]}// log.Println("left value:", in[l[0]:l[1]])}if len(rights) > 2 { // rights has to be at least 3 longr = []int{pivot + rights[2][0], pivot + rights[2][1]}// log.Println("right value:", in[r[0]:r[1]])}ret := strings.Builder{}if len(l) != 0 {ret.WriteString(in[:l[0]])leftNum, err := strconv.Atoi(in[l[0]:l[1]])if err != nil {log.Panicln(err)}explodeLeftNum, err := strconv.Atoi(in[expLeft[0]:expLeft[1]])if err != nil {log.Panicln(err)}ret.WriteString(strconv.Itoa(leftNum + explodeLeftNum))ret.WriteString(in[l[1] : expLeft[0]-1])} else {ret.WriteString(in[:expLeft[0]-1])}ret.WriteByte('0')if len(r) != 0 {ret.WriteString(in[expRight[1]+1 : r[0]])rightNum, err := strconv.Atoi(in[r[0]:r[1]])if err != nil {log.Panicln(err)}explodeRightNum, err := strconv.Atoi(in[expRight[0]:expRight[1]])if err != nil {log.Panicln(err)}ret.WriteString(strconv.Itoa(rightNum + explodeRightNum))ret.WriteString(in[r[1]:])} else {ret.WriteString(in[expRight[1]+1:])}// log.Println("after doExplode", ret.String())return ret.String()}var twodigit = regexp.MustCompile(`\d\d+`)func split(in string) string {if split := twodigit.FindStringIndex(in); len(split) != 0 {in = doSplit(in, split)}return in}func doSplit(in string, split []int) string {ret := strings.Builder{}ret.WriteString(in[:split[0]])sno, err := strconv.Atoi(in[split[0]:split[1]])if err != nil {log.Panicln(err)}ret.WriteByte('[')ret.WriteString(strconv.Itoa(sno / 2))ret.WriteByte(',')ret.WriteString(strconv.Itoa(int(math.Ceil(float64(sno) / 2))))ret.WriteByte(']')ret.WriteString(in[split[1]:])// log.Println("after doSplit", ret.String())return ret.String()}func parseInput(fileName string) ([]string, error) {ret := []string{}fd, err := os.Open(fileName)if err != nil {return ret, err}defer fd.Close()buf := bufio.NewScanner(fd)for buf.Scan() {ret = append(ret, buf.Text())}return ret, nil}
[[[3,9],[7,2]],[[8,4],[[5,6],0]]][[[1,[4,9]],[[1,8],[1,5]]],[[[2,6],[6,7]],[[4,6],[9,0]]]][[[[9,2],1],[[0,7],[9,6]]],[[5,9],[7,[6,9]]]][8,9][[4,[6,1]],[2,[[6,7],2]]][[6,[[4,1],5]],[4,9]][[[0,6],[8,[8,5]]],[6,9]][[0,[1,0]],[[8,[7,4]],[[1,1],[5,0]]]][[[1,[0,1]],6],[1,9]][[2,[[9,0],[6,1]]],[[8,4],[5,7]]][[[[5,3],[0,9]],[1,[0,7]]],[[9,0],[2,[2,0]]]][[2,[2,[6,8]]],[[9,[5,4]],[4,[3,4]]]][[[[4,0],[7,0]],[[4,8],[5,8]]],[[[7,2],[2,2]],[[3,3],3]]][[5,0],5][[8,[[5,0],2]],[6,[5,1]]][[[9,[8,8]],[8,7]],[[[4,2],4],[[5,1],[4,8]]]][[[[1,1],3],5],9][[[[1,7],[6,5]],5],[[0,6],0]][[9,6],2][[[2,[0,8]],[8,[2,1]]],5][[[9,[3,7]],3],[0,[5,9]]][[[2,[1,7]],6],[[7,[8,2]],[[8,2],8]]][[[[1,2],1],5],2][4,[8,[3,9]]][[[[8,9],[6,0]],[[1,6],7]],8][[2,[8,1]],3][[2,2],[[8,[0,2]],[[5,0],5]]][9,[2,[[6,1],[8,9]]]][[4,[[6,6],4]],[[[9,3],[3,1]],5]][[[7,8],1],0][[[8,8],[[1,0],7]],[4,6]][9,8][[[[4,2],9],[[9,9],7]],[7,[9,[5,8]]]][[4,[4,[3,3]]],8][0,2][[4,[5,5]],[9,[[6,9],4]]][[[7,3],[[1,2],6]],[[[2,4],[6,7]],[[5,0],9]]][[[[2,0],5],[4,5]],[[[6,5],[6,0]],[1,[3,4]]]][[3,[6,8]],[[[3,0],0],[[2,8],7]]][[[4,[6,2]],[9,[4,1]]],[8,[3,4]]][[[6,[6,8]],[7,[2,0]]],[4,[[8,7],[1,6]]]][2,[0,[4,0]]][[[[0,5],1],8],[[9,[0,3]],3]][[[3,[5,2]],[3,[3,2]]],[[[7,3],1],7]][1,[[[1,8],[1,7]],0]][[8,6],[[0,4],4]][[[8,2],[4,6]],3][5,[[[7,5],[4,5]],[0,2]]][[3,[3,6]],6][[[[6,8],[5,7]],[[7,3],5]],[[8,[4,8]],8]][[[[5,8],[3,1]],[[3,7],[7,0]]],[[9,7],0]][[2,[[5,3],8]],0][0,[2,8]][[8,9],[[[2,2],[4,7]],[[4,0],1]]][[[[3,0],8],[[7,3],[6,1]]],[[3,8],[4,2]]][[[[6,7],[4,3]],[[3,9],5]],8][[[7,7],[[3,4],7]],[[[0,4],1],9]][[[7,5],5],[[2,[9,9]],[0,[3,5]]]][[[[3,3],[6,1]],[5,8]],[[4,7],[8,1]]][[[0,[7,3]],[6,[7,2]]],[[0,8],7]][[[2,7],[9,7]],[8,[3,8]]][[[0,2],6],[[9,[6,5]],[[3,9],1]]][[7,[[3,4],[2,8]]],[[[4,1],4],7]][[3,[[3,4],6]],[[3,9],[[4,5],[3,0]]]][[[5,[5,1]],[2,4]],[1,[[1,6],6]]][[[5,6],[[1,3],[5,0]]],[[[4,1],8],[5,5]]][[[[2,0],7],[[8,9],1]],[[[4,0],[1,6]],1]][[[2,0],[[4,2],[9,9]]],[4,9]][[[[1,9],6],2],[[5,4],[2,4]]][[[[4,1],[4,5]],[[2,3],2]],[3,[[8,8],1]]][[[[8,1],0],[2,2]],[[2,[7,1]],1]][[[7,4],[[1,3],5]],[[6,8],[[0,0],2]]][[[1,2],8],[[[1,7],[4,0]],[[8,2],8]]][[[0,8],[3,6]],[[[5,3],7],[9,7]]][[4,6],[[[7,9],[7,5]],[[4,6],[8,4]]]][[[[7,3],0],[[6,2],[7,2]]],[9,[[8,0],3]]][[[3,0],1],[[2,3],1]][[[5,[8,6]],[[1,2],2]],[[[1,4],6],[5,[7,1]]]][[[[1,5],8],[0,0]],4][[[7,[6,8]],3],[[5,1],[[2,8],[4,6]]]][3,[[[5,8],[4,5]],[[7,7],8]]][[6,[7,[8,2]]],[[9,0],0]][[[8,[7,6]],1],[[2,4],6]][[[[0,4],2],[0,7]],[6,6]][1,[[1,9],[9,3]]][[[[5,2],[5,3]],[[9,0],4]],2][[[[5,5],3],[7,[1,2]]],[6,[7,2]]][[[[2,1],3],8],[[2,[8,2]],[7,4]]][[8,[9,[1,8]]],[[[4,4],[0,6]],[6,3]]][[[1,6],[1,[2,5]]],0][[[[0,1],[7,2]],[[7,2],3]],[2,[[7,8],[0,7]]]][[[[1,8],8],[[5,7],[3,4]]],[[[2,5],[7,4]],[[8,4],9]]][[[2,2],[5,[1,0]]],[[[6,6],[3,0]],[[8,5],5]]][[[[8,2],[4,8]],[9,4]],[[8,[7,9]],0]][[3,[5,[2,4]]],[[[8,1],0],[[0,4],[4,5]]]][[5,[9,[3,8]]],[4,[1,[5,2]]]][[[3,[0,6]],[7,[8,7]]],[[6,8],[[8,7],0]]][[[[0,2],5],[4,6]],3][[6,7],[[1,[4,6]],9]][7,[3,[[8,8],5]]]
[[[0,[5,8]],[[1,7],[9,6]]],[[4,[1,2]],[[1,4],2]]][[[5,[2,8]],4],[5,[[9,9],0]]][6,[[[6,2],[5,6]],[[7,6],[4,7]]]][[[6,[0,7]],[0,9]],[4,[9,[9,0]]]][[[7,[6,4]],[3,[1,3]]],[[[5,5],1],9]][[6,[[7,3],[3,2]]],[[[3,8],[5,7]],4]][[[[5,4],[7,7]],8],[[8,3],8]][[9,3],[[9,9],[6,[4,9]]]][[2,[[7,7],7]],[[5,8],[[9,3],[0,2]]]][[[[5,2],5],[8,[3,7]]],[[5,[7,5]],[4,4]]]
module maingo 1.17