adventofcode/2015/day17/main.go

152 lines
2.8 KiB
Go
Raw Permalink Normal View History

2016-12-16 22:21:15 +00:00
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
type container struct {
value int
name string
}
func main() {
if len(os.Args) < 2 {
fmt.Println("Usage: day17 <liters>")
os.Exit(1)
}
total := mustAtoi(os.Args[1])
var input []string
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
input = append(input, scanner.Text())
}
var containers []container
for i := range input {
val := mustAtoi(input[i])
// Generate a name for this container
var u int
for j := range containers {
if containers[j].value == val {
u++
}
}
n := strconv.Itoa(val) + "-" + strconv.Itoa(u)
containers = append(containers, container{value: val, name: n})
}
fmt.Println("All Containers: ")
fmt.Println(containers)
fmt.Println()
fmt.Println("Finding Combinations...")
res := findCombis(total, containers)
var final [][]container
fmt.Println()
fmt.Println("Sorting Results...")
for i := 0; i < len(res); i++ {
tst := sortContainers(res[i])
var dup bool
for j := 0; j < len(final); j++ {
if isEqual(tst, final[j]) {
dup = true
}
}
if !dup {
final = append(final, tst)
}
}
minNum := len(final[0])
var minConfig [][]container
for i := 0; i < len(final); i++ {
if len(final[i]) < minNum {
minNum = len(final[i])
}
}
for i := 0; i < len(final); i++ {
if len(final[i]) == minNum {
minConfig = append(minConfig, final[i])
}
}
fmt.Print("Total Combinations: ")
fmt.Println(strconv.Itoa(len(final)))
fmt.Println("Minimum Containers: " + strconv.Itoa(minNum))
fmt.Println("Num Configurations: " + strconv.Itoa(len(minConfig)))
}
func findCombis(total int, containers []container) [][]container {
var ret [][]container
for i := range containers {
if total == containers[i].value {
fmt.Print("O")
ret = append(ret, []container{containers[i]})
}
if containers[i].value < total {
fmt.Print(".")
bld := []container{containers[i]}
var pass []container
for j := range containers {
if i != j {
pass = append(pass, containers[j])
}
}
tmp := findCombis((total - containers[i].value), pass)
for idx := 0; idx < len(tmp); idx++ {
tmp[idx] = append(bld, tmp[idx]...)
}
ret = append(ret, tmp...)
}
}
return ret
}
func sortContainers(c []container) []container {
n := len(c)
swapped := true
for swapped {
swapped = false
for i := 1; i <= n-1; i++ {
if strings.Compare(c[i-1].name, c[i].name) > 0 {
tmp := c[i-1]
c[i-1] = c[i]
c[i] = tmp
swapped = true
}
}
n = n - 1
}
return c
}
func isEqual(a, b []container) bool {
if len(a) != len(b) {
return false
}
for i := 0; i < len(a); i++ {
if a[i].name != b[i].name {
return false
}
}
return true
}
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)
os.Exit(1)
}
return i
}