diff --git a/src/day18/day18.go b/src/day18/day18.go index 33efbe2..6d6b909 100644 --- a/src/day18/day18.go +++ b/src/day18/day18.go @@ -4,6 +4,7 @@ import ( "AOC2021/src/helper" "fmt" "os" + "strings" ) type snailNumber struct { @@ -23,15 +24,91 @@ func main() { 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]")) + fmt.Println(part1(input)) + max := 0 + for i, _ := range input { + for j, _ := range input { + if i != j { + tmpResult := part1([]string{input[i], input[j]}) + if max < tmpResult { + max = tmpResult + } + } + } + } + fmt.Println(max) +} + +func part1(input []string) int { + currentNumber := replaceBracketsWithParenthesis(input[0]) + for i := 1; i < len(input); i++ { + currentNumber = addSnailNumberStrings(currentNumber, replaceBracketsWithParenthesis(input[i])) + currentNumber = doAll(currentNumber) + } + reduce := true + testString := magicMagic(currentNumber) + for reduce { + testString, reduce = reduceNumber(testString) + } + return testString[0] +} + +func reduceNumber(snailNumber []int) ([]int, bool) { + index := 0 + for index < len(snailNumber)-2 { + if snailNumber[index] > -1 && snailNumber[index+2] > -1 { + tmpIntLeft := snailNumber[index] + tmpIntRight := snailNumber[index+2] + tmpInt := 3*tmpIntLeft + 2*tmpIntRight + returnArray := append(snailNumber[:index], snailNumber[index+4:]...) + returnArray[index-1] = tmpInt + return returnArray, true + } + index++ + } + return snailNumber, false +} + +func magicMagic(number string) []int { + returnArray := []int{} + for _, char := range number { + switch char { + case ',': + returnArray = append(returnArray, -2) + case '(': + returnArray = append(returnArray, -1) + case ')': + returnArray = append(returnArray, -3) + default: + returnArray = append(returnArray, int(char-'0')) + } + } + return returnArray +} + +func replaceBracketsWithParenthesis(input string) string { + input = strings.Replace(input, "]", ")", -1) + input = strings.Replace(input, "[", "(", -1) + return input +} + +func doAll(currentNumber string) string { + run := true + for run { + exploded := true + splitted := false + for exploded { + currentNumber, exploded = checkExplode(currentNumber) + } + currentNumber, splitted = checkSplit(currentNumber) + run = splitted || exploded + } + return currentNumber } func addSnailNumberStrings(left string, right string) string { - return "[" + left + "," + right + "]" + return "(" + left + "," + right + ")" } func checkExplode(snailNumberString string) (string, bool) { @@ -40,10 +117,10 @@ func checkExplode(snailNumberString string) (string, bool) { for index < len(snailNumberString) { char := snailNumberString[index] index++ - if char == '[' { + if char == '(' { openBracketCounter++ } - if char == ']' { + if char == ')' { openBracketCounter-- } if runeIsNumber(rune(char)) && openBracketCounter >= 5 { @@ -53,49 +130,58 @@ func checkExplode(snailNumberString string) (string, bool) { return snailNumberString, false } +func checkSplit(snailNumberString string) (string, bool) { + index := 0 + for index < len(snailNumberString) { + if runeIsNumberOver9(rune(snailNumberString[index])) { + tmpInt := snailNumberString[index] - '0' + insertNewPair(tmpInt, &snailNumberString, index) + return snailNumberString, true + } + index++ + } + return snailNumberString, false +} + func explode(snailNumberString string, location int) string { - returnString := snailNumberString[:location-2] + snailNumberString[location+3:] + returnString := snailNumberString[:location-2] + "0" + snailNumberString[location+3:] addedLeft := false - positionLeft := location - 2 - index := positionLeft - 1 - for !addedLeft { - if returnString[index] == ',' { + index := location - 3 + for index > 0 && !addedLeft { + if runeIsNumber(rune(returnString[index])) { tmpRuneArray := []rune(returnString) - tmpInt := snailNumberString[location-1] + returnString[index-1] - '0' - tmpRuneArray[index-1] = rune(tmpInt) + tmpInt := snailNumberString[location-1] - '0' + returnString[index] - '0' + tmpRuneArray[index] = rune(tmpInt + '0') returnString = string(tmpRuneArray) + index = location addedLeft = true - if positionLeft-1 == index { - positionLeft = index - 1 - } } index-- - if index == 0 { - returnString = returnString[:positionLeft] + string(rune(48)) + returnString[positionLeft:] - addedLeft = true - } + } + if index == 0 { + index = location - 1 } addedRight := false - positionRight := positionLeft + 2 - index = positionLeft + 1 - for !addedRight { - if returnString[index] == ',' { + for !addedRight && index < len(returnString) { + if runeIsNumber(rune(returnString[index])) { tmpRuneArray := []rune(returnString) - tmpInt := snailNumberString[location+1] + returnString[index+1] - '0' - tmpRuneArray[index+1] = rune(tmpInt) + tmpInt := snailNumberString[location+1] - '0' + returnString[index] - '0' + tmpRuneArray[index] = rune(tmpInt + '0') 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 insertNewPair(tmpInt uint8, returnString *string, index int) { + tmpNumberLeft := tmpInt / 2 + tmpNumberRight := tmpNumberLeft + (tmpInt % 2) + tmpNewPairString := string([]rune{'(', rune(tmpNumberLeft) + '0', ',', rune(tmpNumberRight) + '0', ')'}) + *returnString = (*returnString)[:index] + tmpNewPairString + (*returnString)[index+1:] +} + func parseSnailNumber(input string, nested int) (number snailNumber, index int) { index = 0 number.nested = nested @@ -122,5 +208,9 @@ func parseSnailNumber(input string, nested int) (number snailNumber, index int) } func runeIsNumber(char rune) bool { - return char >= 48 && char <= 57 + return char != 44 && char != 40 && char != 41 +} + +func runeIsNumberOver9(char rune) bool { + return char != 44 && char != 40 && char != 41 && char > 57 } diff --git a/src/day18/day18Input.txt b/src/day18/day18Input.txt new file mode 100644 index 0000000..b489520 --- /dev/null +++ b/src/day18/day18Input.txt @@ -0,0 +1,100 @@ +[[7,[1,5]],[[5,7],[[0,8],2]]] +[[[[7,3],[2,2]],3],[[[7,1],[9,1]],2]] +[[[3,[0,2]],[5,2]],8] +[[[[1,5],8],[[0,5],[0,0]]],2] +[[[[9,9],1],[8,[3,2]]],[0,8]] +[[[[0,8],6],6],[[1,5],[[5,5],[4,6]]]] +[[3,[[9,0],[7,6]]],[7,4]] +[6,[[8,[9,7]],[[1,1],[2,6]]]] +[[[[2,2],6],[2,6]],[[8,[3,2]],[2,[6,5]]]] +[9,[1,[1,[4,6]]]] +[8,[[5,[7,7]],[2,2]]] +[[[[3,2],[4,9]],[6,8]],[[[7,9],9],[7,5]]] +[[[[0,4],[9,6]],0],[4,[6,[5,1]]]] +[[3,[4,5]],[1,[[2,8],4]]] +[[[9,[8,3]],[[0,0],2]],[[1,3],[[8,0],[5,3]]]] +[[[[2,4],4],[[5,8],4]],9] +[[1,[[0,8],[1,0]]],[1,[9,2]]] +[[[[7,3],5],[7,[3,1]]],[[3,1],[9,[2,0]]]] +[0,[[7,[9,3]],9]] +[[5,0],[[5,1],[2,3]]] +[[2,[[8,1],0]],[[0,[9,0]],[[3,4],[8,6]]]] +[[[7,5],8],[6,6]] +[[[2,4],[[4,7],[9,6]]],[6,[[3,5],0]]] +[7,[[3,2],[[9,3],9]]] +[[[[9,9],2],[[1,0],6]],[[[6,4],8],[[4,7],[5,6]]]] +[[[1,0],[[3,1],2]],[[[5,3],6],[2,[8,4]]]] +[[4,[[8,1],2]],[2,3]] +[[[[9,6],1],4],1] +[[5,[3,1]],[[[0,5],5],[[4,2],6]]] +[[6,[8,7]],[[[0,9],6],9]] +[[2,[[2,8],6]],[[[7,9],8],[6,[7,6]]]] +[[2,[[4,6],[7,5]]],[[[3,5],[6,4]],[[6,8],4]]] +[[[[1,8],[0,8]],[0,[5,0]]],[[[2,5],[0,6]],8]] +[[[[8,5],[2,3]],[[2,6],4]],[[0,9],1]] +[[2,[6,4]],8] +[[0,8],[[[1,6],[6,3]],[[2,2],8]]] +[0,[[[7,1],[4,7]],5]] +[[[7,[1,8]],[2,[1,3]]],9] +[[1,[9,1]],[[6,8],[6,[7,3]]]] +[[[[5,1],[6,9]],[0,5]],[0,[[6,5],3]]] +[[2,[[3,4],1]],[4,1]] +[[[[1,6],6],[[6,5],0]],[7,[0,4]]] +[[2,[[6,9],[9,4]]],3] +[[[1,3],[7,9]],3] +[1,[3,[[1,0],4]]] +[[[9,1],[4,[5,1]]],[[6,0],[1,2]]] +[[[3,[0,3]],9],[[6,[7,0]],[1,1]]] +[[2,[0,[1,5]]],[[0,[7,7]],[[4,9],[8,4]]]] +[[7,[[5,1],[6,4]]],[[2,1],9]] +[[5,6],[[8,6],[[9,1],[7,2]]]] +[[[[0,6],5],7],[[[6,7],9],1]] +[[4,[0,[6,9]]],[6,[[5,6],3]]] +[[[[0,0],5],[[1,3],0]],[[[4,1],6],7]] +[7,5] +[[[8,[9,5]],[0,1]],[3,[[0,1],9]]] +[[[[2,1],5],1],[[[8,1],[1,9]],1]] +[[[[0,9],[7,3]],[8,0]],[[4,[9,5]],7]] +[6,[[9,[4,7]],1]] +[[7,1],[[9,7],[7,[5,5]]]] +[[4,[6,[7,1]]],[[2,2],[[0,9],3]]] +[[[6,[5,4]],[9,4]],0] +[5,[[[7,8],5],7]] +[[[[1,8],[2,7]],[3,[4,4]]],[[[0,9],[4,5]],[[9,8],[0,6]]]] +[[[[0,2],6],2],[[[5,8],[1,3]],[[2,5],5]]] +[[3,[0,[2,3]]],[[[3,0],8],3]] +[[[[8,5],[7,2]],[8,7]],[[[8,1],[2,5]],5]] +[[[[6,0],[5,6]],[[7,8],[3,5]]],[[[8,3],9],[6,[5,8]]]] +[[7,0],[[[4,3],[4,3]],[[7,1],[8,9]]]] +[[[0,0],[7,0]],[3,[[3,6],1]]] +[[[6,6],1],[0,[1,[1,5]]]] +[[[1,[7,8]],[[7,7],[5,1]]],[0,6]] +[0,[[7,4],[7,7]]] +[[[4,[8,3]],[[2,9],6]],[2,[4,0]]] +[7,[8,8]] +[[[[1,4],1],3],[[3,2],3]] +[[7,[0,4]],[[[9,1],[4,4]],[4,8]]] +[4,[[1,8],9]] +[[[[5,7],[8,5]],[9,2]],[[7,5],7]] +[[[3,[3,2]],3],[8,[9,0]]] +[[2,0],9] +[[8,[[6,4],[2,2]]],[[[4,8],6],[2,[1,5]]]] +[[6,[[0,4],[3,0]]],[[2,5],[3,3]]] +[[[[6,8],[6,1]],[1,3]],[[[4,9],[0,8]],9]] +[[[1,[1,6]],[[2,8],5]],[[[8,1],9],6]] +[[[3,[9,6]],[1,[6,5]]],[[4,7],[[4,4],8]]] +[[[7,6],0],[[7,7],7]] +[[3,0],[1,[[2,1],9]]] +[[9,[[3,7],9]],[[[1,1],4],[0,[3,9]]]] +[[3,[1,[0,1]]],[[0,9],[4,[8,8]]]] +[[[8,[3,2]],[9,5]],[[[1,2],[0,4]],6]] +[[5,4],[[2,4],[0,[7,2]]]] +[[[[9,2],4],[[9,5],[8,8]]],[[7,[7,0]],3]] +[[[[8,2],[1,1]],[[9,3],3]],[[9,[5,2]],[[1,4],[0,6]]]] +[4,[[[2,7],6],[[0,8],0]]] +[[[4,4],3],[0,8]] +[[3,[3,[8,6]]],[5,[[0,6],3]]] +[[[2,[0,9]],[[5,0],[7,3]]],[[8,1],[5,2]]] +[[7,[[3,2],[6,8]]],[2,[[4,7],[3,1]]]] +[[[[6,3],6],4],[[[7,8],[5,1]],[[3,0],5]]] +[[3,[9,5]],[6,9]] \ No newline at end of file diff --git a/src/day18/day18Test.txt b/src/day18/day18Test.txt new file mode 100644 index 0000000..32b9205 --- /dev/null +++ b/src/day18/day18Test.txt @@ -0,0 +1,2 @@ +[[[[4,3],4],4],[7,[[8,4],9]]] +[1,1] \ No newline at end of file diff --git a/src/day18/day18Test2.txt b/src/day18/day18Test2.txt new file mode 100644 index 0000000..c41dfc3 --- /dev/null +++ b/src/day18/day18Test2.txt @@ -0,0 +1,4 @@ +[1,1] +[2,2] +[3,3] +[4,4] \ No newline at end of file diff --git a/src/day18/day18Test3.txt b/src/day18/day18Test3.txt new file mode 100644 index 0000000..1d267f7 --- /dev/null +++ b/src/day18/day18Test3.txt @@ -0,0 +1,5 @@ +[1,1] +[2,2] +[3,3] +[4,4] +[5,5] \ No newline at end of file diff --git a/src/day18/day18Test4.txt b/src/day18/day18Test4.txt new file mode 100644 index 0000000..dbb4f44 --- /dev/null +++ b/src/day18/day18Test4.txt @@ -0,0 +1,6 @@ +[1,1] +[2,2] +[3,3] +[4,4] +[5,5] +[6,6] \ No newline at end of file diff --git a/src/day18/day18Test5.txt b/src/day18/day18Test5.txt new file mode 100644 index 0000000..20d54d0 --- /dev/null +++ b/src/day18/day18Test5.txt @@ -0,0 +1,10 @@ +[[[0,[4,5]],[0,0]],[[[4,5],[2,6]],[9,5]]] +[7,[[[3,7],[4,3]],[[6,3],[8,8]]]] +[[2,[[0,8],[3,4]]],[[[6,7],1],[7,[1,6]]]] +[[[[2,4],7],[6,[0,5]]],[[[6,8],[2,8]],[[2,1],[4,5]]]] +[7,[5,[[3,8],[1,4]]]] +[[2,[2,2]],[8,[8,1]]] +[2,9] +[1,[[[9,3],9],[[9,0],[0,7]]]] +[[[5,[7,4]],7],1] +[[[[4,2],2],6],[8,7]] \ No newline at end of file diff --git a/src/day18/day18Test6.txt b/src/day18/day18Test6.txt new file mode 100644 index 0000000..2efedbf --- /dev/null +++ b/src/day18/day18Test6.txt @@ -0,0 +1,10 @@ +[[[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]]] \ No newline at end of file diff --git a/src/helper/helper.go b/src/helper/helper.go index 8f3c72b..bc2170b 100644 --- a/src/helper/helper.go +++ b/src/helper/helper.go @@ -82,6 +82,10 @@ func DeleteAt(a []int, i int) []int { return append(a[:i], a[i+1:]...) } +func DeleteCharAt(a string, i int) string { + return a[:i] + a[i+1:] +} + func Equal(a, b []int) bool { if len(a) != len(b) { return false @@ -144,6 +148,16 @@ func ContainsCharacter(input string, characters string) bool { return true } +func AmountCharacterInString(input string, selector rune) int { + amount := 0 + for _, char := range input { + if char == selector { + amount++ + } + } + return amount +} + func AddNummbers(numbers ...int) int { result := 0 for _, number := range numbers { @@ -162,7 +176,7 @@ func Transpose(in [][]int) [][]int { return out } -func RemoveElementFromStringArray (stringArray []string, selector string) []string { +func RemoveElementFromStringArray(stringArray []string, selector string) []string { var returnString []string for _, str := range stringArray { if str != selector { @@ -172,7 +186,7 @@ func RemoveElementFromStringArray (stringArray []string, selector string) []stri return returnString } -func RemovePointFromPointArray (pointArray [][2]int, selector [2]int) [][2]int { +func RemovePointFromPointArray(pointArray [][2]int, selector [2]int) [][2]int { var returnArray [][2]int for _, point := range pointArray { if point != selector { @@ -182,10 +196,10 @@ func RemovePointFromPointArray (pointArray [][2]int, selector [2]int) [][2]int { return returnArray } -func GCD(x int,y int) (int){ +func GCD(x int, y int) int { gcd := -1 - for i := 1; i <=x && i <=y ; i++ { - if(y%i==0 && x%i==0) { + for i := 1; i <= x && i <= y; i++ { + if y%i == 0 && x%i == 0 { gcd = i } } @@ -230,13 +244,13 @@ func SortString(s string) string { } type Pair struct { - Key string + Key string Value int } type PairList []Pair -func RankByValueAmount(wordFrequencies map[string]int) PairList{ +func RankByValueAmount(wordFrequencies map[string]int) PairList { pl := make(PairList, len(wordFrequencies)) i := 0 for k, v := range wordFrequencies { @@ -247,6 +261,6 @@ func RankByValueAmount(wordFrequencies map[string]int) PairList{ return pl } -func (p PairList) Len() int { return len(p) } +func (p PairList) Len() int { return len(p) } func (p PairList) Less(i, j int) bool { return p[i].Value < p[j].Value } -func (p PairList) Swap(i, j int){ p[i], p[j] = p[j], p[i] } +func (p PairList) Swap(i, j int) { p[i], p[j] = p[j], p[i] }