diff --git a/README.md b/README.md index 2c48387..b524da0 100644 --- a/README.md +++ b/README.md @@ -9,3 +9,5 @@ Day | Name | Type of Algo 1 | The Tyranny of the Rocket Equation | - Simple math problem 2 | Program Alarm | - Intro to the crazy Intcode problems that are half the AoC days...
- Array (slice...) manipulation
- I used recursion 3 | Crossed Wires | - Geometry kind of algo, finding intersections of lines on a grid +4 | Secure Container | - May appear math-y, but it's really a string manipulation problem +5 | \ No newline at end of file diff --git a/day04/input.txt b/day04/input.txt new file mode 100644 index 0000000..a5d5848 --- /dev/null +++ b/day04/input.txt @@ -0,0 +1 @@ +138307-654504 diff --git a/day04/main.go b/day04/main.go deleted file mode 100644 index e8ac0ec..0000000 --- a/day04/main.go +++ /dev/null @@ -1,64 +0,0 @@ -package main - -import ( - "fmt" - "strconv" -) - -func numMatching(sliceToEnd []rune) int { - // fmt.Println(sliceToEnd) - // gets in a slice from a character to the end, returns an int of the matching characters - result := 1 - for i := 1; i < len(sliceToEnd); i++ { - if sliceToEnd[i] == sliceToEnd[0] { - result += 1 - } else { - break - } - } - // fmt.Println(result) - return result -} - -func testNumber(num int) bool { - // cast to string to iterate through digits? - strNum := strconv.Itoa(num) - runesSlice := []rune(strNum) - - duplicate := false - - for i := 0; i < len(runesSlice)-1; { - if runesSlice[i] > runesSlice[i+1] { - return false - } - - matches := numMatching(runesSlice[i:len(runesSlice)]) - if matches == 2 { - duplicate = true - i++ - } else if matches == 1 { - i++ - } else if matches > 2 { - i += (matches - 1) - } - } - - // if the entire for loop passes, return if there was a duplicate or not - return duplicate -} - -func main() { - start, end := 138307, 654504 - possibleCombinations := 0 - - for i := start; i <= end; i++ { - if testNumber(i) { - possibleCombinations++ - } - } - - fmt.Println(possibleCombinations) - // fmt.Println(testNumber(111122)) - // fmt.Println(testNumber(123444)) - // fmt.Println(testNumber(112233)) -} diff --git a/day04/part1/main.go b/day04/part1/main.go new file mode 100644 index 0000000..6116614 --- /dev/null +++ b/day04/part1/main.go @@ -0,0 +1,47 @@ +package main + +import ( + "fmt" +) + +func main() { + start, end := 138307, 654504 + possibleCombinations := 0 + + for i := start; i <= end; i++ { + digits := makeDigitsSlice(i) + if isIncreasing(digits) && hasDuplicate(digits) { + possibleCombinations++ + } + } + + fmt.Println(possibleCombinations) +} + +func makeDigitsSlice(num int) []int { + result := make([]int, 6) + for i := 5; num > 0; i-- { + result[i] = num % 10 + num -= num % 10 + num /= 10 + } + return result +} + +func isIncreasing(digits []int) bool { + for i := 1; i < len(digits); i++ { + if digits[i] < digits[i-1] { + return false + } + } + return true +} + +func hasDuplicate(digits []int) bool { + for i := 1; i < len(digits); i++ { + if digits[i-1] == digits[i] { + return true + } + } + return false +} diff --git a/day04/part2/main.go b/day04/part2/main.go new file mode 100644 index 0000000..01883ca --- /dev/null +++ b/day04/part2/main.go @@ -0,0 +1,80 @@ +/* +Only change from part1 is adding a decorator to the digit slices to shrink large +groups (more than 2 digits) into a single digit. Then pass that into the same +checks for a duplicate & all decreasing +*/ + +package main + +import "fmt" + +func main() { + start, end := 138307, 654504 + possibleCombinations := 0 + + for i := start; i <= end; i++ { + digits := shrinkLargeGroups(makeDigitsSlice(i)) + if isIncreasing(digits) && hasDuplicate(digits) { + possibleCombinations++ + } + } + + fmt.Println(possibleCombinations) +} + +func makeDigitsSlice(num int) []int { + result := make([]int, 6) + for i := 5; num > 0; i-- { + result[i] = num % 10 + num -= num % 10 + num /= 10 + } + return result +} + +/* +shrinkLargeGroups will return a new slice with any groups larger than 2 shrinked +down to 1. e.g. 111223 -> 1223 +*/ +func shrinkLargeGroups(digits []int) []int { + // from start of number & ensure i+2 is within bounds of the digits slice + for i := 0; i+2 < len(digits); i++ { + if digits[i] == digits[i+1] && digits[i] == digits[i+2] { + // figure out how many items to remove + removeUpTo := i + 1 + for removeUpTo < len(digits) && digits[i] == digits[removeUpTo] { + removeUpTo++ + } + + // copy the values into a new slice + newSli := make([]int, 0) + for j := 0; j <= i; j++ { + newSli = append(newSli, digits[j]) + } + for removeUpTo < len(digits) { + newSli = append(newSli, digits[removeUpTo]) + removeUpTo++ + } + digits = newSli + } + } + return digits +} + +func isIncreasing(digits []int) bool { + for i := 1; i < len(digits); i++ { + if digits[i] < digits[i-1] { + return false + } + } + return true +} + +func hasDuplicate(digits []int) bool { + for i := 1; i < len(digits); i++ { + if digits[i-1] == digits[i] { + return true + } + } + return false +}