2020 Day 13 Complete!
This commit is contained in:
parent
3d518b7034
commit
54aa1b1bf1
0
2020/day05/main.go
Normal file → Executable file
0
2020/day05/main.go
Normal file → Executable file
0
2020/day06/input
Normal file → Executable file
0
2020/day06/input
Normal file → Executable file
0
2020/day12/input
Normal file → Executable file
0
2020/day12/input
Normal file → Executable file
2
2020/day13/input
Executable file
2
2020/day13/input
Executable file
@ -0,0 +1,2 @@
|
||||
1006605
|
||||
19,x,x,x,x,x,x,x,x,x,x,x,x,37,x,x,x,x,x,883,x,x,x,x,x,x,x,23,x,x,x,x,13,x,x,x,17,x,x,x,x,x,x,x,x,x,x,x,x,x,797,x,x,x,x,x,x,x,x,x,41,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,29
|
131
2020/day13/main.go
Executable file
131
2020/day13/main.go
Executable file
@ -0,0 +1,131 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
h "git.bullercodeworks.com/brian/adventofcode/helpers"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println("# Day 13")
|
||||
inp := h.StdinToStringSlice()
|
||||
if len(inp) != 2 {
|
||||
fmt.Println("Invalid input")
|
||||
return
|
||||
}
|
||||
part1(inp)
|
||||
part2Rework(inp)
|
||||
}
|
||||
|
||||
func part1(inp []string) {
|
||||
me := h.Atoi(inp[0])
|
||||
pts := strings.Split(inp[1], ",")
|
||||
earliest := h.MAX_INT
|
||||
var earliestBus int
|
||||
for k := range pts {
|
||||
if pts[k] == "x" {
|
||||
continue
|
||||
}
|
||||
bus := h.Atoi(pts[k])
|
||||
div := me / bus
|
||||
wait := (bus * (div + 1)) - me
|
||||
if earliest > wait {
|
||||
earliest = wait
|
||||
earliestBus = bus
|
||||
}
|
||||
}
|
||||
fmt.Println("## Part 1")
|
||||
fmt.Printf("Answer %d\n\n", earliest*earliestBus)
|
||||
}
|
||||
|
||||
// This may not work with all inputs...
|
||||
func part2Rework(inp []string) {
|
||||
pts := strings.Split(inp[1], ",")
|
||||
buses := make(map[int]int)
|
||||
var keys []int
|
||||
for k, v := range pts {
|
||||
if v == "x" {
|
||||
continue
|
||||
}
|
||||
keys = append(keys, k)
|
||||
buses[k] = h.Atoi(v)
|
||||
}
|
||||
for _, v := range buses {
|
||||
if !h.IsPrime(v) {
|
||||
fmt.Println("Not all buses are prime numbers... This solution _may not work_. Or it may still.", h.SHRUG)
|
||||
break
|
||||
}
|
||||
}
|
||||
res := 0
|
||||
mins := buses[keys[0]]
|
||||
for k := 1; k < len(keys); k++ {
|
||||
wrk := keys[k]
|
||||
bus := buses[wrk]
|
||||
for (res+wrk)%bus != 0 {
|
||||
res = res + mins
|
||||
}
|
||||
mins = mins * bus
|
||||
}
|
||||
fmt.Println("## Part 2")
|
||||
fmt.Printf("Answer: %d\n", res)
|
||||
}
|
||||
|
||||
/*
|
||||
7 13 59 31 19
|
||||
1068781 D . . . .
|
||||
1068782 . D . . .
|
||||
1068783 . . . . .
|
||||
1068784 . . . . .
|
||||
1068785 . . D . .
|
||||
1068786 . . . . .
|
||||
1068787 . . . D .
|
||||
1068788 D . . . D
|
||||
|
||||
7 = 0
|
||||
13 = 1
|
||||
59 = 4
|
||||
31 = 6
|
||||
19 = 7
|
||||
|
||||
*/
|
||||
|
||||
// I think this will get there... Eventually... Maybe...
|
||||
func part2(inp []string) {
|
||||
pts := strings.Split(inp[1], ",")
|
||||
wrk := make(map[int]int)
|
||||
var keys []int
|
||||
var vals []int
|
||||
var highK, highV int
|
||||
for k := range pts {
|
||||
if pts[k] == "x" {
|
||||
continue
|
||||
}
|
||||
keys = append(keys, k)
|
||||
vals = append(vals, wrk[k])
|
||||
wrk[k] = h.Atoi(pts[k])
|
||||
if wrk[k] > highV {
|
||||
highK = k
|
||||
highV = wrk[k]
|
||||
}
|
||||
}
|
||||
sort.Sort(sort.Reverse(sort.IntSlice(keys)))
|
||||
sort.Sort(sort.Reverse(sort.IntSlice(keys)))
|
||||
target := highV - highK
|
||||
for !checkMap(target, keys, wrk) {
|
||||
target = target + highV
|
||||
}
|
||||
|
||||
fmt.Println("## Part 2")
|
||||
fmt.Printf("Answer: %d\n", target)
|
||||
}
|
||||
|
||||
func checkMap(target int, keys []int, all map[int]int) bool {
|
||||
for _, k := range keys {
|
||||
if (target+k)%all[k] != 0 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
2
2020/day13/testinput
Executable file
2
2020/day13/testinput
Executable file
@ -0,0 +1,2 @@
|
||||
939
|
||||
7,13,x,x,59,x,31,19
|
2
2020/day13/testinput2
Executable file
2
2020/day13/testinput2
Executable file
@ -0,0 +1,2 @@
|
||||
1
|
||||
1789,37,47,1889
|
7
go.mod
7
go.mod
@ -3,20 +3,13 @@ module git.bullercodeworks.com/brian/adventofcode
|
||||
go 1.13
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v0.3.1 // indirect
|
||||
github.com/br0xen/termbox-screen v0.0.0-20190712162752-c91f70ac38c6
|
||||
github.com/br0xen/termbox-util v0.0.0-20190325151025-c168c0df31ca
|
||||
github.com/br0xen/user-config v0.0.0-20170914134719-16e743ec93a2 // indirect
|
||||
github.com/casimir/xdg-go v0.0.0-20160329195404-372ccc2180da // indirect
|
||||
github.com/fatih/color v1.7.0
|
||||
github.com/go-gl/gl v0.0.0-20190320180904-bf2b1f2f34d7
|
||||
github.com/go-gl/glfw v0.0.0-20191125211704-12ad95a8df72
|
||||
github.com/google/uuid v1.1.1 // indirect
|
||||
github.com/jcelliott/lumber v0.0.0-20160324203708-dd349441af25 // indirect
|
||||
github.com/mattn/go-colorable v0.1.4 // indirect
|
||||
github.com/mattn/go-isatty v0.0.10 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.7 // indirect
|
||||
github.com/nanobox-io/golang-scribble v0.0.0-20190309225732-aa3e7c118975 // indirect
|
||||
github.com/nlopes/slack v0.6.0 // indirect
|
||||
github.com/nsf/termbox-go v0.0.0-20190817171036-93860e161317
|
||||
)
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"math"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
@ -25,9 +26,11 @@ const (
|
||||
|
||||
MAX_INT = int(^uint(0) >> 1)
|
||||
MIN_INT = -MAX_INT - 1
|
||||
|
||||
SHRUG = "¯\\_(ツ)_/¯"
|
||||
)
|
||||
|
||||
// Find the greatest common denominator
|
||||
// Gcd Finds the greatest common denominator
|
||||
func Gcd(x, y int) int {
|
||||
for y != 0 {
|
||||
x, y = y, x%y
|
||||
@ -35,7 +38,7 @@ func Gcd(x, y int) int {
|
||||
return x
|
||||
}
|
||||
|
||||
// Find the least common multiple, using gcd
|
||||
// Lcm finds the least common multiple, using gcd
|
||||
func Lcm(a, b int, integers ...int) int {
|
||||
result := a * b / Gcd(a, b)
|
||||
for i := 0; i < len(integers); i++ {
|
||||
@ -44,6 +47,7 @@ func Lcm(a, b int, integers ...int) int {
|
||||
return result
|
||||
}
|
||||
|
||||
// AbsInt returns the absolute value of i
|
||||
func AbsInt(i int) int {
|
||||
if i < 0 {
|
||||
return i * -1
|
||||
@ -51,6 +55,7 @@ func AbsInt(i int) int {
|
||||
return i
|
||||
}
|
||||
|
||||
// ArgIsSet return true if an argument with the asked for key is present
|
||||
func ArgIsSet(a string) bool {
|
||||
for i := range os.Args {
|
||||
if os.Args[i] == a || strings.HasPrefix(os.Args[i], a+"=") {
|
||||
@ -60,6 +65,7 @@ func ArgIsSet(a string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// GetArgValue returns the argument with the asked for key or ""
|
||||
func GetArgValue(a string) string {
|
||||
for i := range os.Args {
|
||||
if strings.HasPrefix(os.Args[i], a+"=") {
|
||||
@ -69,6 +75,7 @@ func GetArgValue(a string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// GetArgNumber returns the asked for argument position or ""
|
||||
func GetArgNumber(i int) string {
|
||||
if len(os.Args) > i {
|
||||
return os.Args[i]
|
||||
@ -76,6 +83,7 @@ func GetArgNumber(i int) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// OptArgNumber returns either the asked for argument position or the passed default
|
||||
func OptArgNumber(i int, def string) string {
|
||||
if len(os.Args) > i {
|
||||
return os.Args[i]
|
||||
@ -83,6 +91,7 @@ func OptArgNumber(i int, def string) string {
|
||||
return def
|
||||
}
|
||||
|
||||
// StdinToIntSlice reads from stdin and returns it as an int slice
|
||||
func StdinToIntSlice() []int {
|
||||
var ret []int
|
||||
st := StdinToStringSlice()
|
||||
@ -92,6 +101,7 @@ func StdinToIntSlice() []int {
|
||||
return ret
|
||||
}
|
||||
|
||||
// StdinToStringSlice reads from stdin and returns it as a string slice
|
||||
func StdinToStringSlice() []string {
|
||||
var input []string
|
||||
scanner := bufio.NewScanner(os.Stdin)
|
||||
@ -101,10 +111,12 @@ func StdinToStringSlice() []string {
|
||||
return input
|
||||
}
|
||||
|
||||
// StdinToCoordMap reads stdin and returns it as a CoordByteMap
|
||||
func StdinToCoordMap() CoordByteMap {
|
||||
return StringSliceToCoordByteMap(StdinToStringSlice())
|
||||
}
|
||||
|
||||
// Atoi is basically redundant
|
||||
func Atoi(i string) int {
|
||||
var ret int
|
||||
var err error
|
||||
@ -114,10 +126,12 @@ func Atoi(i string) int {
|
||||
return ret
|
||||
}
|
||||
|
||||
// Itoa is basically redundant
|
||||
func Itoa(i int) string {
|
||||
return strconv.Itoa(i)
|
||||
}
|
||||
|
||||
// StdinToString reads from stdin and returns a string
|
||||
func StdinToString() string {
|
||||
var input string
|
||||
scanner := bufio.NewScanner(os.Stdin)
|
||||
@ -127,14 +141,17 @@ func StdinToString() string {
|
||||
return input
|
||||
}
|
||||
|
||||
// FileToStringSlice takes a file and returns it as a slice of strings
|
||||
func FileToStringSlice(fn string) []string {
|
||||
return strings.Split(string(FileToBytes(fn)), "\n")
|
||||
}
|
||||
|
||||
// FileToString reads a file and returns it as a string
|
||||
func FileToString(fn string) string {
|
||||
return string(FileToBytes(fn))
|
||||
}
|
||||
|
||||
// FileToBytes reads a file and returns it as a slice of bytes
|
||||
func FileToBytes(fn string) []byte {
|
||||
var c []byte
|
||||
var err error
|
||||
@ -146,6 +163,7 @@ func FileToBytes(fn string) []byte {
|
||||
return c
|
||||
}
|
||||
|
||||
// PrintProgress is for outputting a progress bar
|
||||
func PrintProgress(curr, total int) {
|
||||
pct := int(float64(curr)/float64(total)) * 100
|
||||
for i := 0; i < 100; i += 10 {
|
||||
@ -155,6 +173,7 @@ func PrintProgress(curr, total int) {
|
||||
}
|
||||
}
|
||||
|
||||
// StringPermutations takes a string and returns all permutations of it
|
||||
func StringPermutations(str string) []string {
|
||||
perms := stringPermHelper(str, 0)
|
||||
var wrk []string
|
||||
@ -186,6 +205,7 @@ func stringPermHelper(str string, i int) []string {
|
||||
return ret
|
||||
}
|
||||
|
||||
// IntPermutations takes a slice of ints and returns all permutations of it
|
||||
func IntPermutations(inp []int) [][]int {
|
||||
perms := intPermHelper(inp, 0)
|
||||
var wrk [][]int
|
||||
@ -219,6 +239,7 @@ func intPermHelper(inp []int, i int) [][]int {
|
||||
return ret
|
||||
}
|
||||
|
||||
// IntSlicesAreEqual takes two int slices and returns if they are equal
|
||||
func IntSlicesAreEqual(s1 []int, s2 []int) bool {
|
||||
if len(s1) != len(s2) {
|
||||
return false
|
||||
@ -231,6 +252,8 @@ func IntSlicesAreEqual(s1 []int, s2 []int) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// StringSliceContains takes a string slice and a string and return true
|
||||
// if the string is in the slice
|
||||
func StringSliceContains(h []string, n string) bool {
|
||||
for _, v := range h {
|
||||
if v == n {
|
||||
@ -239,3 +262,13 @@ func StringSliceContains(h []string, n string) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsPrime takes a number and return true if that number is prime
|
||||
func IsPrime(value int) bool {
|
||||
for i := 2; i <= int(math.Floor(float64(value)/2)); i++ {
|
||||
if value%i == 0 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return value > 1
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user