-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
10,713 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,232 @@ | ||
package main | ||
|
||
import ( | ||
"bufio" | ||
"fmt" | ||
"os" | ||
"strconv" | ||
"time" | ||
) | ||
|
||
type buttonPair struct { | ||
from rune | ||
to rune | ||
} | ||
|
||
type starship struct { | ||
memo map[string]int | ||
paths map[buttonPair]string // contains all | ||
} | ||
|
||
func readInput() []string { | ||
// read from txt file | ||
file, err := os.Open("input21.txt") | ||
if err != nil { | ||
panic(err) | ||
} | ||
defer file.Close() | ||
|
||
result := []string{} | ||
|
||
// read the file line by line | ||
scanner := bufio.NewScanner(file) | ||
for scanner.Scan() { | ||
line := scanner.Text() | ||
result = append(result, line) | ||
} | ||
|
||
if err := scanner.Err(); err != nil { | ||
panic(err) | ||
} | ||
return result | ||
} | ||
|
||
func main() { | ||
startTime := time.Now() | ||
|
||
result := readInput() | ||
|
||
s := &starship{ | ||
memo: make(map[string]int), | ||
paths: map[buttonPair]string{ | ||
{'A', '0'}: "<A", | ||
{'0', 'A'}: ">A", | ||
{'A', '1'}: "^<<A", | ||
{'1', 'A'}: ">>vA", | ||
{'A', '2'}: "<^A", | ||
{'2', 'A'}: "v>A", | ||
{'A', '3'}: "^A", | ||
{'3', 'A'}: "vA", | ||
{'A', '4'}: "^^<<A", | ||
{'4', 'A'}: ">>vvA", | ||
{'A', '5'}: "<^^A", | ||
{'5', 'A'}: "vv>A", | ||
{'A', '6'}: "^^A", | ||
{'6', 'A'}: "vvA", | ||
{'A', '7'}: "^^^<<A", | ||
{'7', 'A'}: ">>vvvA", | ||
{'A', '8'}: "<^^^A", | ||
{'8', 'A'}: "vvv>A", | ||
{'A', '9'}: "^^^A", | ||
{'9', 'A'}: "vvvA", | ||
{'0', '1'}: "^<A", | ||
{'1', '0'}: ">vA", | ||
{'0', '2'}: "^A", | ||
{'2', '0'}: "vA", | ||
{'0', '3'}: "^>A", | ||
{'3', '0'}: "<vA", | ||
{'0', '4'}: "^<^A", | ||
{'4', '0'}: ">vvA", | ||
{'0', '5'}: "^^A", | ||
{'5', '0'}: "vvA", | ||
{'0', '6'}: "^^>A", | ||
{'6', '0'}: "<vvA", | ||
{'0', '7'}: "^^^<A", | ||
{'7', '0'}: ">vvvA", | ||
{'0', '8'}: "^^^A", | ||
{'8', '0'}: "vvvA", | ||
{'0', '9'}: "^^^>A", | ||
{'9', '0'}: "<vvvA", | ||
{'1', '2'}: ">A", | ||
{'2', '1'}: "<A", | ||
{'1', '3'}: ">>A", | ||
{'3', '1'}: "<<A", | ||
{'1', '4'}: "^A", | ||
{'4', '1'}: "vA", | ||
{'1', '5'}: "^>A", | ||
{'5', '1'}: "<vA", | ||
{'1', '6'}: "^>>A", | ||
{'6', '1'}: "<<vA", | ||
{'1', '7'}: "^^A", | ||
{'7', '1'}: "vvA", | ||
{'1', '8'}: "^^>A", | ||
{'8', '1'}: "<vvA", | ||
{'1', '9'}: "^^>>A", | ||
{'9', '1'}: "<<vvA", | ||
{'2', '3'}: ">A", | ||
{'3', '2'}: "<A", | ||
{'2', '4'}: "<^A", | ||
{'4', '2'}: "v>A", | ||
{'2', '5'}: "^A", | ||
{'5', '2'}: "vA", | ||
{'2', '6'}: "^>A", | ||
{'6', '2'}: "<vA", | ||
{'2', '7'}: "<^^A", | ||
{'7', '2'}: "vv>A", | ||
{'2', '8'}: "^^A", | ||
{'8', '2'}: "vvA", | ||
{'2', '9'}: "^^>A", | ||
{'9', '2'}: "<vvA", | ||
{'3', '4'}: "<<^A", | ||
{'4', '3'}: "v>>A", | ||
{'3', '5'}: "<^A", | ||
{'5', '3'}: "v>A", | ||
{'3', '6'}: "^A", | ||
{'6', '3'}: "vA", | ||
{'3', '7'}: "<<^^A", | ||
{'7', '3'}: "vv>>A", | ||
{'3', '8'}: "<^^A", | ||
{'8', '3'}: "vv>A", | ||
{'3', '9'}: "^^A", | ||
{'9', '3'}: "vvA", | ||
{'4', '5'}: ">A", | ||
{'5', '4'}: "<A", | ||
{'4', '6'}: ">>A", | ||
{'6', '4'}: "<<A", | ||
{'4', '7'}: "^A", | ||
{'7', '4'}: "vA", | ||
{'4', '8'}: "^>A", | ||
{'8', '4'}: "<vA", | ||
{'4', '9'}: "^>>A", | ||
{'9', '4'}: "<<vA", | ||
{'5', '6'}: ">A", | ||
{'6', '5'}: "<A", | ||
{'5', '7'}: "<^A", | ||
{'7', '5'}: "v>A", | ||
{'5', '8'}: "^A", | ||
{'8', '5'}: "vA", | ||
{'5', '9'}: "^>A", | ||
{'9', '5'}: "<vA", | ||
{'6', '7'}: "<<^A", | ||
{'7', '6'}: "v>>A", | ||
{'6', '8'}: "<^A", | ||
{'8', '6'}: "v>A", | ||
{'6', '9'}: "^A", | ||
{'9', '6'}: "vA", | ||
{'7', '8'}: ">A", | ||
{'8', '7'}: "<A", | ||
{'7', '9'}: ">>A", | ||
{'9', '7'}: "<<A", | ||
{'8', '9'}: ">A", | ||
{'9', '8'}: "<A", | ||
{'<', '^'}: ">^A", | ||
{'^', '<'}: "v<A", | ||
{'<', 'v'}: ">A", | ||
{'v', '<'}: "<A", | ||
{'<', '>'}: ">>A", | ||
{'>', '<'}: "<<A", | ||
{'<', 'A'}: ">>^A", | ||
{'A', '<'}: "v<<A", | ||
{'^', 'v'}: "vA", | ||
{'v', '^'}: "^A", | ||
{'^', '>'}: "v>A", | ||
{'>', '^'}: "<^A", | ||
{'^', 'A'}: ">A", | ||
{'A', '^'}: "<A", | ||
{'v', '>'}: ">A", | ||
{'>', 'v'}: "<A", | ||
{'v', 'A'}: "^>A", | ||
{'A', 'v'}: "<vA", | ||
{'>', 'A'}: "^A", | ||
{'A', '>'}: "vA", | ||
}, | ||
} | ||
|
||
complexity := 0 | ||
for _, v := range result { | ||
length := s.getSequenceLength(v, 3) | ||
num, _ := strconv.Atoi(v[:len(v)-1]) | ||
complexity += length * num | ||
} | ||
|
||
fmt.Println("Complexity: ", complexity) | ||
|
||
// part 2 - 25 robots | ||
|
||
complexity2 := 0 | ||
for _, v := range result { | ||
length := s.getSequenceLength(v, 26) | ||
num, _ := strconv.Atoi(v[:len(v)-1]) | ||
complexity2 += length * num | ||
} | ||
|
||
fmt.Println("Complexity2: ", complexity2) | ||
|
||
endTime := time.Since(startTime) | ||
fmt.Printf("Day21 execution took: %v ms (%v µs)\n", endTime.Milliseconds(), endTime.Microseconds()) // Day21 execution took: 1 ms (1171 µs) | ||
} | ||
|
||
func (s *starship) getSequenceLength(sequence string, depth int) int { | ||
if v, exists := s.memo[fmt.Sprintf("%v,%v", sequence, depth)]; exists { | ||
return v | ||
} | ||
|
||
length := 0 | ||
if depth == 0 { | ||
length += len(sequence) | ||
} else { | ||
current := 'A' | ||
for _, v := range sequence { | ||
pathSequence := s.paths[buttonPair{rune(current), v}] | ||
currentLength := s.getSequenceLength(pathSequence, depth-1) | ||
if pathSequence == "" { | ||
currentLength = 1 | ||
} | ||
length += currentLength | ||
current = v | ||
} | ||
} | ||
s.memo[fmt.Sprintf("%v,%v", sequence, depth)] = length | ||
|
||
return length | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
805A | ||
170A | ||
129A | ||
283A | ||
540A |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
package main | ||
|
||
import ( | ||
"bufio" | ||
"fmt" | ||
"os" | ||
"strconv" | ||
"time" | ||
) | ||
|
||
func readInput() []int { | ||
// read from txt file | ||
file, err := os.Open("input22.txt") | ||
if err != nil { | ||
panic(err) | ||
} | ||
defer file.Close() | ||
|
||
result := []int{} | ||
|
||
// read the file line by line | ||
scanner := bufio.NewScanner(file) | ||
for scanner.Scan() { | ||
line := scanner.Text() | ||
num, _ := strconv.Atoi(line) | ||
result = append(result, num) | ||
} | ||
|
||
if err := scanner.Err(); err != nil { | ||
panic(err) | ||
} | ||
return result | ||
} | ||
|
||
type bananaLedger struct { | ||
maxBanana []bool | ||
totalBanana int | ||
} | ||
|
||
type secretBananaNumber struct { | ||
secretNumber int | ||
bananaPrice int | ||
diff int | ||
} | ||
|
||
func main() { | ||
startTime := time.Now() | ||
|
||
result := readInput() | ||
|
||
totalSum := 0 | ||
secretNumberArr := make([][]secretBananaNumber, 0, len(result)) | ||
for _, each := range result { | ||
secretNumber := each | ||
currArr := []secretBananaNumber{{secretNumber, getBananaPrice(secretNumber), 0}} | ||
for i := 0; i < 2000; i++ { | ||
nextSecretNumber := getNextSecretNumber(secretNumber) | ||
diff := getBananaPriceDiff(nextSecretNumber, secretNumber) | ||
currArr = append(currArr, secretBananaNumber{nextSecretNumber, getBananaPrice(nextSecretNumber), diff}) | ||
secretNumber = nextSecretNumber | ||
} | ||
secretNumberArr = append(secretNumberArr, currArr) | ||
totalSum += secretNumber | ||
} | ||
|
||
fmt.Println("Total sum is: ", totalSum) | ||
|
||
blmap := make(map[string]bananaLedger) | ||
for buyerIndex, each := range secretNumberArr { | ||
for i := 3; i < len(each); i++ { | ||
currSecretBananaNumber := each[i] | ||
patternKey := fmt.Sprintf("%d,%d,%d,%d", each[i-3].diff, each[i-2].diff, each[i-1].diff, each[i].diff) | ||
if bl, ok := blmap[patternKey]; ok { | ||
// if found, update the existing one | ||
if !blmap[patternKey].maxBanana[buyerIndex] { | ||
bl.maxBanana[buyerIndex] = true | ||
bl.totalBanana += currSecretBananaNumber.bananaPrice | ||
// assign bl back to blmap | ||
blmap[patternKey] = bl | ||
} | ||
|
||
} else { | ||
// if not found, create a new one | ||
bl := bananaLedger{ | ||
maxBanana: make([]bool, len(secretNumberArr)), | ||
totalBanana: currSecretBananaNumber.bananaPrice, | ||
} | ||
bl.maxBanana[buyerIndex] = true | ||
blmap[patternKey] = bl | ||
} | ||
} | ||
} | ||
|
||
// get the max total banana | ||
maxTotalBanana := 0 | ||
for _, each := range blmap { | ||
if each.totalBanana > maxTotalBanana { | ||
maxTotalBanana = each.totalBanana | ||
} | ||
} | ||
|
||
fmt.Println("Max total bananas: ", maxTotalBanana) | ||
|
||
endTime := time.Since(startTime) | ||
fmt.Printf("Day22 execution took: %v ms (%v µs)\n", endTime.Milliseconds(), endTime.Microseconds()) // Day22 execution took: 1459 ms (1459203 µs) | ||
} | ||
|
||
func getBananaPrice(price int) int { | ||
return price % 10 | ||
} | ||
|
||
func getBananaPriceDiff(newPrice, oldPrice int) int { | ||
return getBananaPrice(newPrice) - getBananaPrice(oldPrice) | ||
} | ||
|
||
func mixSecretNumbers(secretNumber, resultant int) int { | ||
return secretNumber ^ resultant | ||
} | ||
|
||
func pruneSecretNumber(secretNumber int) int { | ||
return secretNumber % 16777216 | ||
} | ||
|
||
func getNextSecretNumber(secretNumber int) int { | ||
firsrOperation := pruneSecretNumber(mixSecretNumbers(secretNumber, secretNumber*64)) | ||
secondOperation := pruneSecretNumber(mixSecretNumbers(firsrOperation, firsrOperation/32)) | ||
thirdOperation := pruneSecretNumber(mixSecretNumbers(secondOperation, secondOperation*2048)) | ||
return thirdOperation | ||
} |
Oops, something went wrong.