Day2-Cube Conundrum
Table of Contents
My solution and thoughts on Day 2 puzzle of Advent of Code 2023
##
Part One
#
Puzzle
You play several games and record the information from each game (your puzzle input). Each game is listed with its ID number (like the 11
in Game 11: ...
) followed by a semicolon-separated list of subsets of cubes that were revealed from the bag (like 3 red, 5 green, 4 blue
).
For example, the record of a few games might look like this:
Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green
Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue
Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red
Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red
Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green
In game 1, three sets of cubes are revealed from the bag (and then put back again). The first set is 3 blue cubes and 4 red cubes; the second set is 1 red cube, 2 green cubes, and 6 blue cubes; the third set is only 2 green cubes.
The Elf would first like to know which games would have been possible if the bag contained only 12 red cubes, 13 green cubes, and 14 blue cubes?
In the example above, games 1, 2, and 5 would have been possible if the bag had been loaded with that configuration. However, game 3 would have been impossible because at one point the Elf showed you 20 red cubes at once; similarly, game 4 would also have been impossible because the Elf showed you 15 blue cubes at once. If you add up the IDs of the games that would have been possible, you get _8_
.
Determine which games would have been possible if the bag had been loaded with only 12 red cubes, 13 green cubes, and 14 blue cubes. _What is the sum of the IDs of those games?
#
Solution - Functions
- main()
- setRead(line string)
- checkPossible(color string, count int, colorMap map[string]int) bool
- sumSlice(sets []string) int
##
global variables
there should be a better way to deal with it, i think i need to avoid global variables by using pointer better, but now i can’t, so i will resort myself to this
// var SumOfImpossible []int
var PossibleSets []string
##
main
func main() {
file, err := os.ReadFile("input1.txt")
if err != nil {
return
}
lines := strings.Split(string(file), "\n")
for _, line := range lines {
setRead(line)
} sum := sumSlice(PossibleSets)
fmt.Println(sum)
}
##
setRead
func setRead(line string) {
// separate the set name from the set
clrSets := strings.Split(line, ":")
if len(clrSets) != 2 {
return
}
// separate each set, i.e. [ 1 blue, 2 green 3 green, 4 blue, 1 red 1 green, 1 blue]
sets := strings.Split(clrSets[1], ";")
// make a map for each color and its count
colorMap := make(map[string]int)
possible := true
for i, set := range sets {
// separate the color name from the color, i.e. [ 3 blue 4 red] [ 1 red 2 green 6 blue] [ 2 green]
color := strings.Split(set, ",")
for _, c := range color {
// separate the count from the color, i.e. [ 3 blue] [ 4 red]
s := strings.Split(c, ",")
for _, v := range s {
v = strings.TrimSpace(v)
f := strings.Split(v, " ")
count, _ := strconv.Atoi(f[0])
// search for the color in the map
// if the color is not in the map, add it
_, ok := colorMap[f[1]]
if ok {
possible = checkPossible(f[1], count, colorMap)
if !possible {
//SumOfImpossible = append(SumOfImpossible, markImpossible(clrSets[0]))
return
}
colorMap[f[1]] += count
continue
} else {
possible = checkPossible(f[1], count, colorMap)
if !possible {
//SumOfImpossible = append(SumOfImpossible, markImpossible(clrSets[0]))
return
}
colorMap[f[1]] = count
continue
}
}
}
if i == len(sets)-1 {
// for check
//fmt.Println(colorMap)
}
}
// id of sets if it is possible
PossibleSets = append(PossibleSets, strings.Split(clrSets[0], " ")[1])
}
##
checkPossible
func checkPossible(color string, count int, colorMap map[string]int) bool {
if color == "red" && count > 12 {
return false
}
if color == "green" && count > 13 {
return false
}
if color == "blue" && count > 14 {
return false
}
return true
}
##
sumSlice
func sumSlice(sets []string) int {
sum := 0
for _, s := range sets {
id, _ := strconv.Atoi(s)
sum += id
}
return sum
}
##
Extra
alternative way to deal by marking impossible IDs
func markImpossible(set string) int {
impossible := strings.Split(set, " ")[1]
id, _ := strconv.Atoi(impossible)
return id
}
##
Part Two
#
Puzzle
Again consider the example games from earlier:
Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green
Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue
Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red
Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red
Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green
- In game 1, the game could have been played with as few as 4 red, 2 green, and 6 blue cubes. If any color had even one fewer cube, the game would have been impossible.
- Game 2 could have been played with a minimum of 1 red, 3 green, and 4 blue cubes.
- Game 3 must have been played with at least 20 red, 13 green, and 6 blue cubes.
- Game 4 required at least 14 red, 3 green, and 15 blue cubes.
- Game 5 needed no fewer than 6 red, 3 green, and 2 blue cubes in the bag.
The power of a set of cubes is equal to the numbers of red, green, and blue cubes multiplied together. The power of the minimum set of cubes in game 1 is 48
. In games 2-5 it was 12
, 1560
, 630
, and 36
, respectively. Adding up these five powers produces the sum _2286_
.
For each game, find the minimum set of cubes that must have been present. _What is the sum of the power of these sets?
#
Solution - Functions
- main()
- setRead(line string)
- multiplyColors(colorMap map[string]int) int
##
global variables
var Multiplication int
##
main
func Part2() {
file, err := os.ReadFile("input2.txt")
if err != nil {
return
}
lines := strings.Split(string(file), "\n")
for _, line := range lines {
setRead(line)
} fmt.Println(Multiplication)
}
##
setRead
func setRead(line string) {
// separate the set name from the set
clrSets := strings.Split(line, ":")
if len(clrSets) != 2 {
return
}
// separate each set, i.e. [ 1 blue, 2 green 3 green, 4 blue, 1 red 1 green, 1 blue]
sets := strings.Split(clrSets[1], ";")
// make a map for each color and its count
colorMap := make(map[string]int)
//possible := true
for i, set := range sets {
// separate the color name from the color, i.e. [ 3 blue 4 red] [ 1 red 2 green 6 blue] [ 2 green]
color := strings.Split(set, ",")
for _, c := range color {
// separate the count from the color, i.e. [ 3 blue] [ 4 red]
s := strings.Split(c, ",")
for _, v := range s {
v = strings.TrimSpace(v)
f := strings.Split(v, " ")
count, _ := strconv.Atoi(f[0])
// search for the color in the map
// if the color is not in the map, add it
_, ok := colorMap[f[1]]
if ok {
if colorMap[f[1]] <= count {
colorMap[f[1]] = count
}
continue
} else {
colorMap[f[1]] = count
continue
}
}
}
if i == len(sets)-1 {
multiplication := multiplyColors(colorMap)
Multiplication += multiplication
// for check
//fmt.Println(colorMap)
}
}
}
##
multiplyColors
func multiplyColors(colorMap map[string]int) int {
red := colorMap["red"]
green := colorMap["green"]
blue := colorMap["blue"]
result := red * green * blue
return result
}
#
Review
I myself still think my way is too verbose, too many nested loops, the bigO time will significantly increase if i put too many nested loops, for each loop, it will be n ^(the number of loops), and i should avoid global variables, that being said, i can’t find a better and distinct way to do this.