Solution for day 3 (optimized and working)
This commit is contained in:
@@ -11,6 +11,8 @@
|
||||
- 12 instead of 2
|
||||
- "just" generalize approach from Level 1 to use 12 instead of 2 digits
|
||||
|
||||
__Example for 24-char input and 5 digits:__
|
||||
|
||||
### Attempts
|
||||
|
||||
- 154932365400342: too low
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
@@ -41,60 +40,71 @@ func readBanks(fileName string) []string {
|
||||
func maxJolts(digits int, banks <-chan string, results chan<- int) {
|
||||
for bank := range banks {
|
||||
remaining := bank
|
||||
var substring string
|
||||
|
||||
// collect potential substrings
|
||||
var substrings []string
|
||||
|
||||
// find substring
|
||||
// loop through digits from 9 to 1
|
||||
for i := 9; i > 0; i-- {
|
||||
digit := strconv.Itoa(i)
|
||||
|
||||
// determine indexes for digit
|
||||
indexes := allIndexes(remaining, digit)
|
||||
if len(indexes) == 0 {
|
||||
// determine first index of digit
|
||||
index := strings.Index(remaining, digit)
|
||||
if index == -1 {
|
||||
continue
|
||||
}
|
||||
|
||||
// find all substrings that could potentially contain the largest
|
||||
// combination of digits (strings that are at least 12 chars long)
|
||||
substrings = []string{}
|
||||
|
||||
for _, index := range indexes {
|
||||
substring := remaining[index:]
|
||||
if len(substring) >= digits {
|
||||
substrings = append(substrings, substring)
|
||||
}
|
||||
}
|
||||
|
||||
// if substrings have been found, there's no need to search for
|
||||
// substrings for a lower digit, so the loop can be exited
|
||||
if len(substrings) > 0 {
|
||||
// ignore everything before digit index
|
||||
substring = remaining[index:]
|
||||
if len(substring) >= digits {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
candidates := []int{}
|
||||
|
||||
for _, substring := range substrings {
|
||||
if len(substring) > digits {
|
||||
// replace digits one by one, from 1 to 9, until substring
|
||||
// has a length of `digits` and therefore qualifies as candidate
|
||||
for i := 1; i <= 9; i++ {
|
||||
digit := strconv.Itoa(i)
|
||||
for strings.Contains(substring, digit) && len(substring) > digits {
|
||||
substring = strings.Replace(substring, digit, "", 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add candidate
|
||||
candidate, _ := strconv.Atoi(substring)
|
||||
candidates = append(candidates, candidate)
|
||||
// done if length is `digits`
|
||||
if len(substring) == digits {
|
||||
result, _ := strconv.Atoi(substring)
|
||||
results <- result
|
||||
return
|
||||
}
|
||||
|
||||
// out of all candidates, the biggest one is the result for this bank
|
||||
result := slices.Max(candidates)
|
||||
results <- result
|
||||
built := ""
|
||||
|
||||
for i := 9; i > 0; i-- {
|
||||
// done if length is `digits``
|
||||
if len(built) == digits {
|
||||
break
|
||||
}
|
||||
|
||||
for j := 9; j > 0; j-- {
|
||||
digit := strconv.Itoa(j)
|
||||
|
||||
indexes := allIndexes(substring, digit)
|
||||
if len(indexes) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
index := strings.Index(substring, digit)
|
||||
|
||||
// continue is resulting substring is too short
|
||||
if len(built)+len(substring[index:]) < digits {
|
||||
continue
|
||||
}
|
||||
|
||||
built += digit
|
||||
substring = substring[index+1:]
|
||||
|
||||
// reset loops
|
||||
j = 10
|
||||
i = 10
|
||||
|
||||
// done
|
||||
if len(built) == digits {
|
||||
result, _ := strconv.Atoi(built)
|
||||
results <- result
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user