Day 7
This commit is contained in:
111
day7/main.go
Normal file
111
day7/main.go
Normal file
@ -0,0 +1,111 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"math"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(part1(readData("example.txt")))
|
||||
fmt.Println(part1(readData("data.txt")))
|
||||
fmt.Println(part2(readData("example.txt")))
|
||||
fmt.Println(part2(readData("data.txt")))
|
||||
}
|
||||
|
||||
type Case struct {
|
||||
target int64
|
||||
operands []int64
|
||||
}
|
||||
|
||||
func part1(cases []Case) (sumOk int64) {
|
||||
for _, c := range cases {
|
||||
if canReach(c.target, 0, c.operands) {
|
||||
sumOk += c.target
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func part2(cases []Case) (sumOk int64) {
|
||||
for _, c := range cases {
|
||||
if canReach2(c.target, 0, c.operands) {
|
||||
sumOk += c.target
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func concatenate(a int64, b int64) int64 {
|
||||
bDecimalLength := len(strconv.FormatInt(b, 10))
|
||||
return a*int64(math.Pow(10, float64(bDecimalLength))) + b
|
||||
}
|
||||
|
||||
func canReach(target int64, currentTotal int64, operands []int64) bool {
|
||||
if len(operands) == 0 {
|
||||
return target == currentTotal
|
||||
}
|
||||
|
||||
if currentTotal > target {
|
||||
return false
|
||||
}
|
||||
|
||||
return canReach(target, currentTotal+operands[0], operands[1:]) ||
|
||||
canReach(target, currentTotal*operands[0], operands[1:])
|
||||
}
|
||||
|
||||
func canReach2(target int64, currentTotal int64, operands []int64) bool {
|
||||
if len(operands) == 0 {
|
||||
return target == currentTotal
|
||||
}
|
||||
|
||||
if currentTotal > target {
|
||||
return false
|
||||
}
|
||||
|
||||
return canReach2(target, currentTotal+operands[0], operands[1:]) ||
|
||||
canReach2(target, currentTotal*operands[0], operands[1:]) ||
|
||||
canReach2(target, concatenate(currentTotal, operands[0]), operands[1:])
|
||||
}
|
||||
|
||||
func readData(fileName string) (cases []Case) {
|
||||
fp, err := os.Open(fileName)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
scanner := bufio.NewScanner(fp)
|
||||
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
splitColon := strings.Split(line, ":")
|
||||
|
||||
if len(splitColon) != 2 {
|
||||
panic("Not enough data")
|
||||
}
|
||||
|
||||
target, err := strconv.ParseInt(splitColon[0], 10, 64)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
operandsStr := strings.Split(strings.TrimSpace(splitColon[1]), " ")
|
||||
operands := make([]int64, len(operandsStr))
|
||||
|
||||
for i, s := range operandsStr {
|
||||
n, err := strconv.ParseInt(s, 10, 64)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
operands[i] = n
|
||||
}
|
||||
|
||||
cases = append(cases, Case{target, operands})
|
||||
}
|
||||
|
||||
return
|
||||
}
|
Reference in New Issue
Block a user