Guest User

Untitled

a guest
Dec 22nd, 2023
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 4.69 KB | Source Code | 0 0
  1. package main
  2.  
  3. import (
  4.     "fmt"
  5.     "os"
  6.     "slices"
  7.     "strings"
  8.     "util"
  9. )
  10.  
  11. func goUp(above string, curr string) (string, string, bool) {
  12.     // skip first row
  13.     if above == "" {
  14.         return "", curr, false
  15.     }
  16.     rolled := false
  17.     for i, r := range curr {
  18.         if r == '#' || r == '.' || above[i] == '#' || above[i] == 'O' {
  19.             continue
  20.         } else {
  21.             above = util.ReplaceAtIdx(above, r, i)
  22.             curr = util.ReplaceAtIdx(curr, '.', i)
  23.             if !rolled {
  24.                 rolled = true
  25.             }
  26.         }
  27.     }
  28.     return above, curr, rolled
  29. }
  30.  
  31. func goDown(below string, curr string) (string, string, bool) {
  32.     // skip first row
  33.     if below == "" {
  34.         return "", curr, false
  35.     }
  36.     rolled := false
  37.     for i := 0; i < len(curr)-1; i++ {
  38.         r := curr[i]
  39.         if r == '#' || r == '.' || below[i] == '#' || below[i] == 'O' {
  40.             continue
  41.         } else {
  42.             below = util.ReplaceAtIdx(below, rune(r), i)
  43.             curr = util.ReplaceAtIdx(curr, '.', i)
  44.             if !rolled {
  45.                 rolled = true
  46.             }
  47.         }
  48.     }
  49.     return below, curr, rolled
  50. }
  51.  
  52. func goLeft(line string) string {
  53.     newLine := []string{}
  54.     rockCount := 0
  55.     gap := 0
  56.     for i := len(line) - 1; i >= 0; i-- {
  57.         if line[i] == 'O' {
  58.             rockCount++
  59.         }
  60.         if line[i] != '#' {
  61.             gap++
  62.         }
  63.         if line[i] == '#' || i == 0 {
  64.             // rocks
  65.             rocks := util.ArrWithDefaultStr(rockCount, "O")
  66.             gaps := util.ArrWithDefaultStr(gap-rockCount, ".")
  67.             // Create new line
  68.             if i != 0 {
  69.                 newLine = append(newLine, "#"+strings.Join(rocks, "")+strings.Join(gaps, ""))
  70.             } else {
  71.                 newLine = append(newLine, strings.Join(rocks, "")+strings.Join(gaps, ""))
  72.             }
  73.             rockCount = 0
  74.             gap = 0
  75.         }
  76.         // If the last char is "#", add it
  77.         if line[i] == '#' && i == 0 {
  78.             newLine = append(newLine, "#")
  79.         }
  80.     }
  81.     slices.Reverse(newLine)
  82.     return strings.Join(newLine, "")
  83. }
  84.  
  85. func goRight(line string) string {
  86.     newLine := []string{}
  87.     rockCount := 0
  88.     gap := 0
  89.     for i := 0; i <= len(line)-1; i++ {
  90.         if line[i] == 'O' {
  91.             rockCount++
  92.         }
  93.         if line[i] != '#' {
  94.             gap++
  95.         }
  96.         if line[i] == '#' || i == len(line)-1 {
  97.             // rocks
  98.             rocks := util.ArrWithDefaultStr(rockCount, "O")
  99.             gaps := util.ArrWithDefaultStr(gap-rockCount, ".")
  100.             // Create new line
  101.             if i != len(line)-1 {
  102.                 newLine = append(newLine, strings.Join(gaps, "")+strings.Join(rocks, "")+"#")
  103.             } else {
  104.                 newLine = append(newLine, strings.Join(gaps, "")+strings.Join(rocks, ""))
  105.             }
  106.             rockCount = 0
  107.             gap = 0
  108.         }
  109.         // If the last char is "#", add it
  110.         if line[i] == '#' && i == len(line)-1 {
  111.             newLine = append(newLine, "#")
  112.         }
  113.     }
  114.     return strings.Join(newLine, "")
  115. }
  116.  
  117. func Part02() int {
  118.     dataInput, err := util.GetInput("14")
  119.     if err != nil {
  120.         os.Exit(1)
  121.     }
  122.     inputArr := strings.Fields(dataInput)
  123.  
  124.     visited := map[string]int{}
  125.  
  126.     cycles := 1000000000
  127.     // If > 0 there's a remainder we want to calculate through
  128.     remainder := -1
  129.     // north, then west, then south, then east
  130.     for cycles > 0 && remainder != 0 {
  131.         // Speed Track
  132.         // if cycles%1000 == 0 {
  133.         //  fmt.Println("Processed: ", cycles)
  134.         // }
  135.  
  136.         rolling := true
  137.  
  138.         for rolling {
  139.             rolled := false
  140.             for i := 0; i < len(inputArr); i++ {
  141.                 currRolled := false
  142.                 // North
  143.                 if i > 0 {
  144.                     inputArr[i-1], inputArr[i], currRolled = goUp(inputArr[i-1], inputArr[i])
  145.                 }
  146.                 if !rolled && currRolled {
  147.                     rolled = currRolled
  148.                 }
  149.             }
  150.             if !rolled {
  151.                 break
  152.             }
  153.         }
  154.  
  155.         for i := 0; i < len(inputArr); i++ {
  156.             inputArr[i] = goLeft(inputArr[i])
  157.         }
  158.  
  159.         // South
  160.         for rolling {
  161.             rolled := false
  162.             for i := 0; i < len(inputArr)-1; i++ {
  163.                 currRolled := false
  164.                 if i < len(inputArr) {
  165.                     inputArr[i+1], inputArr[i], currRolled = goDown(inputArr[i+1], inputArr[i])
  166.                 }
  167.                 if !rolled && currRolled {
  168.                     rolled = currRolled
  169.                 }
  170.             }
  171.             if !rolled {
  172.                 break
  173.             }
  174.         }
  175.  
  176.         // East
  177.         for i := 0; i < len(inputArr); i++ {
  178.             inputArr[i] = goRight(inputArr[i])
  179.         }
  180.  
  181.         // Find the actual loop
  182.         if visit, ok := visited[strings.Join(inputArr, "")]; remainder < 0 && ok {
  183.             // we found a loop -
  184.             fmt.Println("loop! ", visit, " : ", cycles)
  185.             // get remainder, then just loop through that next bit..
  186.             remainder = visit % (visit - cycles)
  187.         } else {
  188.             visited[strings.Join(inputArr, "")] = cycles
  189.         }
  190.         if remainder > 0 {
  191.             fmt.Println(calculate(inputArr))
  192.             remainder--
  193.         }
  194.         cycles--
  195.     }
  196.  
  197.     finalValue := calculate(inputArr)
  198.     fmt.Println("Part 2: ", finalValue)
  199.     return finalValue
  200. }
  201.  
  202. func calculate(inputArr []string) int {
  203.     // final count
  204.     finalCount := 0
  205.     slices.Reverse(inputArr)
  206.     for i := len(inputArr) - 1; i >= 0; i-- {
  207.         for _, v := range inputArr[i] {
  208.             if v == 'O' {
  209.                 finalCount += (i + 1)
  210.             }
  211.         }
  212.     }
  213.     slices.Reverse(inputArr)
  214.     return finalCount
  215. }
  216.  
  217. func main() {
  218.     // Part01()
  219.     Part02()
  220. }
Tags: aoc
Advertisement
Add Comment
Please, Sign In to add comment