adventofcode/2015/day15/main.go

157 lines
3.1 KiB
Go

package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
var ings []ingredient
func main() {
var input []string
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
input = append(input, scanner.Text())
}
var stringIngs []string
total := 100
for i := range input {
bldI := *createIngredient(input[i])
ings = append(ings, bldI)
stringIngs = append(stringIngs, bldI.name)
}
combis := getIntCombis(total, len(stringIngs))
ingPerms := getStringPermus(stringIngs)
var highVal int
var highMap map[string]int
for h := range combis {
for i := range ingPerms {
tstMap := make(map[string]int)
for j := range ingPerms[i] {
tstMap[ingPerms[i][j]] = combis[h][j]
}
tmp, cals := calcValue(tstMap)
if cals == 500 && tmp > highVal {
highVal = tmp
highMap = tstMap
fmt.Print(strconv.Itoa(tmp))
fmt.Print(" :: ")
fmt.Println(tstMap)
}
}
}
fmt.Println()
fmt.Println(highMap)
fmt.Println("Highest Value: " + strconv.Itoa(highVal))
}
func getStringPermus(vals []string) [][]string {
var ret [][]string
if len(vals) == 1 {
return append(ret, vals)
}
for j := range vals {
var bld []string
for i := range vals {
if i != j {
bld = append(bld, vals[i])
}
}
tmp := getStringPermus(bld)
for i := range tmp {
tmp[i] = append([]string{vals[j]}, tmp[i]...)
ret = append(ret, tmp[i])
}
}
return ret
}
func getIntCombis(total, containers int) [][]int {
var ret [][]int
if containers == 2 {
for i := total; i >= 0; i-- { //(total / 2); i-- {
ret = append(ret, []int{i, (total - i)})
}
return ret
}
for i := total; i >= 0; i-- { //(total / 2); i-- {
tmp := getIntCombis((total - i), (containers - 1))
for j := 0; j < len(tmp); j++ {
tmp[j] = append([]int{i}, tmp[j]...)
ret = append(ret, tmp[j])
}
}
return ret
}
func getIngredient(name string) *ingredient {
for i := range ings {
if ings[i].name == name {
return &ings[i]
}
}
return nil
}
func calcValue(list map[string]int) (int, int) {
tmp := new(ingredient)
for kname, v := range list {
k := getIngredient(kname)
tmp.capacity += k.capacity * v
tmp.durability += k.durability * v
tmp.flavor += k.flavor * v
tmp.texture += k.texture * v
tmp.calories += k.calories * v
}
if tmp.texture < 0 || tmp.durability < 0 || tmp.flavor < 0 || tmp.texture < 0 {
return 0, 0
}
return (tmp.capacity * tmp.durability * tmp.flavor * tmp.texture), tmp.calories
}
type ingredient struct {
name string
capacity int
durability int
flavor int
texture int
calories int
}
func createIngredient(s string) *ingredient {
parts := strings.Split(s, " ")
name := parts[0]
name = name[:len(name)-1]
c := parts[2]
d := parts[4]
f := parts[6]
t := parts[8]
cal := parts[10]
i := ingredient{
name: name,
capacity: mustAtoi(c[:len(c)-1]),
durability: mustAtoi(d[:len(d)-1]),
flavor: mustAtoi(f[:len(f)-1]),
texture: mustAtoi(t[:len(t)-1]),
calories: mustAtoi(cal),
}
return &i
}
func mustAtoi(s string) int {
var i int
var err error
if i, err = strconv.Atoi(s); err != nil {
fmt.Println("Tried to atoi " + s)
}
return i
}