Day 25 (Golang)
This commit is contained in:
parent
ba57fdfe90
commit
fae44916f0
6 changed files with 236 additions and 3 deletions
2
.github/README.md
vendored
2
.github/README.md
vendored
|
@ -40,7 +40,7 @@ Puzzle inputs and descriptions are not included in this repository. You'll have
|
|||
| [22](/22-crabCombat) | ![Partially complete][partial] | [Link](/22-crabCombat/python) | | |
|
||||
| [23](/23-crabCups) | ![Incomplete][cross] | | | |
|
||||
| [24](/24-lobbyLayout) | ![Partially complete][partial] | [Link](/24-lobbyLayout/python) | | |
|
||||
| 25 | ![Not yet attempted][pending] | | | |
|
||||
| [25](/25-comboBreaker) | ![Completed][check] | [Link](/25-comboBreaker/python) | [Link](/25-comboBreaker/go) | |
|
||||
|
||||
<!-- PARSE END -->
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ I might go back and try some of the other challenges from this year that I didn'
|
|||
<details><summary>Script output</summary>
|
||||
|
||||
```
|
||||
❯ python .\python\ ft
|
||||
❯ python python ft
|
||||
AoC 2020: day 25 - Combo Breaker
|
||||
Python 3.8.5
|
||||
|
||||
|
@ -17,8 +17,19 @@ Test cases
|
|||
1.1 pass in 0.0 seconds
|
||||
|
||||
Answers
|
||||
Part 1: 297257 in 7.745995283126831 seconds
|
||||
Part 1: 297257 in 7.089499235153198 seconds
|
||||
Part 2: 0 in 0.0 seconds
|
||||
|
||||
❯ go run .\go\ ft
|
||||
AoC 2020: day 25 - Combo Breaker
|
||||
Go go1.15.2
|
||||
|
||||
Test cases
|
||||
1.1 pass in 0.00000000 seconds
|
||||
|
||||
Answers
|
||||
Part 1: 297257 in 0.13749980 seconds
|
||||
Part 2: 0 in 0.00000000 seconds
|
||||
```
|
||||
|
||||
</details>
|
||||
|
|
18
25-comboBreaker/go/challenge/common.go
Normal file
18
25-comboBreaker/go/challenge/common.go
Normal file
|
@ -0,0 +1,18 @@
|
|||
package challenge
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func parse(instr string) []int {
|
||||
var o []int
|
||||
for _, x := range strings.Split(strings.TrimSpace(instr), "\n") {
|
||||
i, err := strconv.Atoi(x)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
o = append(o, i)
|
||||
}
|
||||
return o
|
||||
}
|
44
25-comboBreaker/go/challenge/partOne.go
Normal file
44
25-comboBreaker/go/challenge/partOne.go
Normal file
|
@ -0,0 +1,44 @@
|
|||
package challenge
|
||||
|
||||
import "errors"
|
||||
|
||||
func singleTransformation(v, subjectNumber int) int {
|
||||
return (v * subjectNumber) % 20201227
|
||||
}
|
||||
|
||||
func transform(loopSize, subjectNumber int) int {
|
||||
v := 1
|
||||
for i := 0; i < loopSize; i += 1 {
|
||||
v = singleTransformation(v, subjectNumber)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func findLoopSize(targetPubkey int) int {
|
||||
var c int
|
||||
v := 1
|
||||
for {
|
||||
c += 1
|
||||
v = singleTransformation(v, 7)
|
||||
if v == targetPubkey {
|
||||
return c
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func PartOne(instr string) int {
|
||||
inputSlice := parse(instr)
|
||||
|
||||
pubkeyOne := inputSlice[0]
|
||||
pubkeyTwo := inputSlice[1]
|
||||
|
||||
loopSizeOne := findLoopSize(pubkeyOne)
|
||||
loopSizeTwo := findLoopSize(pubkeyTwo)
|
||||
|
||||
encryptionKey := transform(loopSizeTwo, pubkeyOne)
|
||||
if encryptionKey != transform(loopSizeOne, pubkeyTwo) {
|
||||
panic(errors.New("encryption keys do not match"))
|
||||
}
|
||||
|
||||
return encryptionKey
|
||||
}
|
5
25-comboBreaker/go/challenge/partTwo.go
Normal file
5
25-comboBreaker/go/challenge/partTwo.go
Normal file
|
@ -0,0 +1,5 @@
|
|||
package challenge
|
||||
|
||||
func PartTwo(instr string) int {
|
||||
return 0
|
||||
}
|
155
25-comboBreaker/go/main.go
Normal file
155
25-comboBreaker/go/main.go
Normal file
|
@ -0,0 +1,155 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"adventOfCode/25-comboBreaker/go/challenge"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/fatih/color"
|
||||
)
|
||||
|
||||
var forceTime bool
|
||||
|
||||
func main() {
|
||||
var infoStruct info
|
||||
{
|
||||
inb, err := ioutil.ReadFile("info.json")
|
||||
if err != nil {
|
||||
fmt.Println("Error: could not open info.json")
|
||||
os.Exit(-1)
|
||||
}
|
||||
err = json.Unmarshal(inb, &infoStruct)
|
||||
if err != nil {
|
||||
fmt.Println("Error: could not parse info.json")
|
||||
os.Exit(-1)
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
year = infoStruct.Year
|
||||
day = infoStruct.Day
|
||||
title = infoStruct.Title
|
||||
)
|
||||
|
||||
fmt.Fprintf(color.Output, "%s: day %s - %s\n", color.YellowString("AoC "+year), color.BlueString(day), title)
|
||||
fmt.Fprintf(color.Output, "Go %s\n\n", color.BlueString(runtime.Version()))
|
||||
|
||||
var challengeInput string
|
||||
{
|
||||
inb, err := ioutil.ReadFile("input.txt")
|
||||
if err != nil {
|
||||
fmt.Println("Error: could not open input.txt")
|
||||
os.Exit(-1)
|
||||
}
|
||||
challengeInput = string(inb)
|
||||
}
|
||||
|
||||
for _, v := range os.Args[1:] {
|
||||
if v == "ft" {
|
||||
forceTime = true
|
||||
}
|
||||
}
|
||||
|
||||
runTests(infoStruct)
|
||||
|
||||
fmt.Println("Answers")
|
||||
|
||||
fmt.Printf("Running part %s...\r", color.BlueString("1"))
|
||||
outputString := fmt.Sprintf("Part %s: ", color.BlueString("1"))
|
||||
x, t := runAndTime(func() int { return challenge.PartOne(challengeInput) })
|
||||
outputString += color.BlueString(strconv.Itoa(x))
|
||||
if t > 15 || forceTime {
|
||||
outputString += fmt.Sprintf(" in %s seconds", color.BlueString(fmt.Sprintf("%.8f", t)))
|
||||
}
|
||||
for i := 0; i < 12; i += 1 {
|
||||
outputString += " "
|
||||
}
|
||||
outputString += "\n"
|
||||
fmt.Fprint(color.Output, outputString)
|
||||
|
||||
fmt.Printf("Running part %s...\r", color.BlueString("2"))
|
||||
outputString = fmt.Sprintf("Part %s: ", color.BlueString("2"))
|
||||
x, t = runAndTime(func() int { return challenge.PartTwo(challengeInput) })
|
||||
outputString += color.BlueString(strconv.Itoa(x))
|
||||
if t > 15 || forceTime {
|
||||
outputString += fmt.Sprintf(" in %s seconds", color.BlueString(fmt.Sprintf("%.8f", t)))
|
||||
}
|
||||
for i := 0; i < 12; i += 1 {
|
||||
outputString += " "
|
||||
}
|
||||
outputString += "\n"
|
||||
fmt.Fprint(color.Output, outputString)
|
||||
|
||||
}
|
||||
|
||||
type tc struct {
|
||||
Input string `json:"input"`
|
||||
Expected int `json:"expected"`
|
||||
}
|
||||
|
||||
type info struct {
|
||||
Year string `json:"year"`
|
||||
Day string `json:"day"`
|
||||
Title string `json:"title"`
|
||||
TestCases struct {
|
||||
One []tc `json:"one"`
|
||||
Two []tc `json:"two"`
|
||||
} `json:"testCases"`
|
||||
}
|
||||
|
||||
func runTests(infoStruct info) {
|
||||
|
||||
if len(infoStruct.TestCases.One) == 0 && len(infoStruct.TestCases.Two) == 0 {
|
||||
fmt.Println("Info: no test cases specified. Skipping tests")
|
||||
fmt.Println()
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println("Test cases")
|
||||
|
||||
rt := func(tcs []tc, f func(string) int, n string) {
|
||||
for i, tc := range tcs {
|
||||
readable_test_num := color.BlueString(n + "." + strconv.Itoa(i+1))
|
||||
fmt.Fprintf(color.Output, "Running %s...\r", readable_test_num)
|
||||
|
||||
outputString := readable_test_num + " "
|
||||
|
||||
result, t := runAndTime(func() int { return f(tc.Input) })
|
||||
|
||||
if result == tc.Expected {
|
||||
outputString += color.GreenString("pass")
|
||||
} else {
|
||||
outputString += fmt.Sprintf("%s (got %s, expected %s)", color.RedString("fail"), color.BlueString(strconv.Itoa(result)), color.BlueString(strconv.Itoa(tc.Expected)))
|
||||
}
|
||||
|
||||
if t > 15 || forceTime {
|
||||
outputString += fmt.Sprintf(" in %s seconds", color.BlueString(fmt.Sprintf("%.8f", t)))
|
||||
}
|
||||
|
||||
for i := 0; i < 12; i += 1 {
|
||||
outputString += " "
|
||||
}
|
||||
outputString += "\n"
|
||||
|
||||
fmt.Fprint(color.Output, outputString)
|
||||
}
|
||||
}
|
||||
|
||||
rt(infoStruct.TestCases.One, challenge.PartOne, "1")
|
||||
rt(infoStruct.TestCases.Two, challenge.PartTwo, "2")
|
||||
|
||||
fmt.Println()
|
||||
|
||||
}
|
||||
|
||||
func runAndTime(f func() int) (int, float64) {
|
||||
st := time.Now()
|
||||
x := f()
|
||||
et := time.Now()
|
||||
return x, et.Sub(st).Seconds()
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue