diff --git a/day09/inputs b/day09/inputs new file mode 120000 index 0000000..a80bb2b --- /dev/null +++ b/day09/inputs @@ -0,0 +1 @@ +../inputs \ No newline at end of file diff --git a/day09/oasis.go b/day09/oasis.go new file mode 100644 index 0000000..9a9dfc2 --- /dev/null +++ b/day09/oasis.go @@ -0,0 +1,149 @@ +package main + +import( + "fmt" + "os" + "bufio" + "sync" + "time" + "regexp" + "strconv" +) + +// Parallel code, global vars +type Series struct { + mu sync.Mutex + numStore [][]int + total uint64 +} + +func check(e error) { + if e != nil { + panic(e) + } +} + +func PrintAndWait(x ...any) { + fmt.Print(x...) + fmt.Scanln() +} +// use defer timer("funcname")() when the function you want to +// test starts +func timer(name string) func() { + start := time.Now() + return func() { + fmt.Printf("%s took %v\n", name, time.Since(start)) + } +} + +func PredictValueBack(numbers []int) []int { + // Are we finished? By default, true + temp := true + for i := 0; i < len(numbers); i++ { + if numbers[i] != 0 { + temp = false + break + } + } + // Check to end recursion + if temp == true { + return numbers + } + + newNums := make([]int, len(numbers) - 1) + for i := 0; i < len(numbers) - 1; i++ { + newNums[i] = numbers[i + 1] - numbers[i] + } + myNums := PredictValueBack(newNums) + addValue := newNums[0] - myNums[0] + // We need to append at the start + newNums = append([]int{addValue}, newNums...) + return newNums +} + +func (ser *Series) CallPredictBack(numbers []int, wg *sync.WaitGroup) { + tempNum := PredictValueBack(numbers) + ser.mu.Lock() + ser.total += uint64(numbers[0] - tempNum[0]) + ser.mu.Unlock() + wg.Done() +} + +func PredictValue(numbers []int) []int { + // Are we finished? By default, true + temp := true + for i := 0; i < len(numbers); i++ { + if numbers[i] != 0 { + temp = false + break + } + } + // Check to end recursion + if temp == true { + return numbers + } + + newNums := make([]int, len(numbers) - 1) + for i := 0; i < len(numbers) - 1; i++ { + newNums[i] = numbers[i + 1] - numbers[i] + } + myNums := PredictValue(newNums) + addValue := myNums[len(myNums) - 1] + newNums = append(newNums, newNums[len(newNums) - 1] + addValue) + return newNums +} + +func (ser *Series) CallPredict(numbers []int, wg *sync.WaitGroup) { + tempNum := PredictValue(numbers) + lt := len(tempNum) - 1 + ln := len(numbers) - 1 + ser.mu.Lock() + ser.total += uint64(numbers[ln] + tempNum[lt]) + ser.mu.Unlock() + wg.Done() +} + +func main() { + defer timer("main")() + file, err := os.Open("./inputs/day09_input") + check(err) + defer file.Close() + + var wg sync.WaitGroup + + renum := regexp.MustCompile("(\\-[0-9]+|[0-9]+)") + + ser := Series{ total: 0, } + + lines := make([]string, 0) + + scanner := bufio.NewScanner(file) + for scanner.Scan() { + lines = append(lines, scanner.Text()) + } + ser.numStore = make([][]int, len(lines)) + for i := 0; i < len(lines); i++ { + temp := renum.FindAllString(lines[i], -1) + for j := 0; j < len(temp); j++ { + num, err := strconv.Atoi(temp[j]) + check(err) + ser.numStore[i] = append(ser.numStore[i], num) + } + } + // Now I have a 2D array with all the numbers, I can start RECURSING + wg.Add(len(ser.numStore)) + for i := 0; i < len(ser.numStore); i++ { + go ser.CallPredict(ser.numStore[i], &wg) + } + wg.Wait() + fmt.Printf("%d\n", ser.total) + + ser.total = 0 + wg.Add(len(ser.numStore)) + for i := 0; i < len(ser.numStore); i++ { + go ser.CallPredictBack(ser.numStore[i], &wg) + } + wg.Wait() + fmt.Printf("%d\n", ser.total) + +}