Merge pull request #25 from StevanFreeborn/stevanfreeborn/refactor/cleanup-day-ten-part-one
refactor: make not ugly
This commit is contained in:
@@ -0,0 +1,40 @@
|
|||||||
|
// Package button implements a button that can control multiple switches.
|
||||||
|
package button
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Button interface {
|
||||||
|
Switches() []int
|
||||||
|
}
|
||||||
|
|
||||||
|
type button struct {
|
||||||
|
switches []int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b button) String() string {
|
||||||
|
return fmt.Sprintf("%v", b.switches)
|
||||||
|
}
|
||||||
|
|
||||||
|
func From(line string) button {
|
||||||
|
buttonRegex := regexp.MustCompile(`\d+`)
|
||||||
|
matches := buttonRegex.FindAllString(line, -1)
|
||||||
|
|
||||||
|
switches := []int{}
|
||||||
|
|
||||||
|
for _, m := range matches {
|
||||||
|
num, _ := strconv.Atoi(m)
|
||||||
|
switches = append(switches, num)
|
||||||
|
}
|
||||||
|
|
||||||
|
return button{
|
||||||
|
switches: switches,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b button) Switches() []int {
|
||||||
|
return b.switches
|
||||||
|
}
|
||||||
@@ -0,0 +1,117 @@
|
|||||||
|
// Package machine defines a model for a machine and methods to manipulate it.
|
||||||
|
package machine
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math"
|
||||||
|
"regexp"
|
||||||
|
"slices"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/StevanFreeborn/advent-of-code-2025/cmd/10/button"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Machine interface {
|
||||||
|
ConfigureLights() int
|
||||||
|
}
|
||||||
|
|
||||||
|
type machine struct {
|
||||||
|
desiredLightState []bool
|
||||||
|
buttons []button.Button
|
||||||
|
desiredJoltages []int
|
||||||
|
}
|
||||||
|
|
||||||
|
func From(line string) Machine {
|
||||||
|
parts := strings.Split(line, " ")
|
||||||
|
lastPartIndex := len(parts) - 1
|
||||||
|
|
||||||
|
lightDiagramPart := parts[0]
|
||||||
|
desiredLightState := []bool{}
|
||||||
|
|
||||||
|
for _, c := range lightDiagramPart {
|
||||||
|
if c == '.' {
|
||||||
|
desiredLightState = append(desiredLightState, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
if c == '#' {
|
||||||
|
desiredLightState = append(desiredLightState, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buttonsPart := parts[1:lastPartIndex]
|
||||||
|
|
||||||
|
buttons := []button.Button{}
|
||||||
|
|
||||||
|
for _, bs := range buttonsPart {
|
||||||
|
b := button.From(bs)
|
||||||
|
buttons = append(buttons, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
joltagesPart := parts[lastPartIndex]
|
||||||
|
desiredJoltages := []int{}
|
||||||
|
joltageRegex := regexp.MustCompile(`\d+`)
|
||||||
|
matches := joltageRegex.FindAllString(joltagesPart, -1)
|
||||||
|
|
||||||
|
for _, m := range matches {
|
||||||
|
num, _ := strconv.Atoi(m)
|
||||||
|
desiredJoltages = append(desiredJoltages, num)
|
||||||
|
}
|
||||||
|
|
||||||
|
return machine{
|
||||||
|
desiredLightState: desiredLightState,
|
||||||
|
buttons: buttons,
|
||||||
|
desiredJoltages: desiredJoltages,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m machine) ConfigureLights() int {
|
||||||
|
combinations := [][]bool{}
|
||||||
|
minPresses := math.MaxInt
|
||||||
|
numberOfButtons := len(m.buttons)
|
||||||
|
numberOfCombinations := int(math.Pow(2, float64(numberOfButtons)))
|
||||||
|
currentCombination := make([]bool, numberOfButtons)
|
||||||
|
|
||||||
|
for range numberOfCombinations {
|
||||||
|
temp := make([]bool, numberOfButtons)
|
||||||
|
copy(temp, currentCombination)
|
||||||
|
|
||||||
|
combinations = append(combinations, temp)
|
||||||
|
|
||||||
|
for j := range numberOfButtons {
|
||||||
|
if currentCombination[j] == false {
|
||||||
|
currentCombination[j] = true
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
currentCombination[j] = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, currentCombination := range combinations {
|
||||||
|
currentPresses := 0
|
||||||
|
initialLightState := make([]bool, len(m.desiredLightState))
|
||||||
|
|
||||||
|
for bi, bs := range currentCombination {
|
||||||
|
if bs == false {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
currentPresses++
|
||||||
|
switchesToToggle := m.buttons[bi].Switches()
|
||||||
|
|
||||||
|
for _, switchToToggle := range switchesToToggle {
|
||||||
|
initialLightState[switchToToggle] = !initialLightState[switchToToggle]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if slices.Equal(initialLightState, m.desiredLightState) == false {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if currentPresses < minPresses {
|
||||||
|
minPresses = currentPresses
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return minPresses
|
||||||
|
}
|
||||||
+3
-152
@@ -1,165 +1,16 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"github.com/StevanFreeborn/advent-of-code-2025/cmd/10/machine"
|
||||||
"math"
|
|
||||||
"regexp"
|
|
||||||
"slices"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/StevanFreeborn/advent-of-code-2025/internal/file"
|
"github.com/StevanFreeborn/advent-of-code-2025/internal/file"
|
||||||
)
|
)
|
||||||
|
|
||||||
type machine struct {
|
|
||||||
switches []bool
|
|
||||||
buttons []button
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewMachine(numberOfLights int, buttonsAsStrings []string) machine {
|
|
||||||
buttons := []button{}
|
|
||||||
|
|
||||||
for _, bs := range buttonsAsStrings {
|
|
||||||
b := NewButton(bs)
|
|
||||||
buttons = append(buttons, b)
|
|
||||||
}
|
|
||||||
|
|
||||||
switches := []bool{}
|
|
||||||
|
|
||||||
for range numberOfLights {
|
|
||||||
switches = append(switches, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
return machine{
|
|
||||||
buttons: buttons,
|
|
||||||
switches: switches,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m machine) String() string {
|
|
||||||
var str strings.Builder
|
|
||||||
|
|
||||||
str.WriteString("[MACHINE]\n")
|
|
||||||
|
|
||||||
switchStr := fmt.Sprintf("[SWITCHES]: %v", m.switches)
|
|
||||||
str.WriteString(switchStr + "\n")
|
|
||||||
|
|
||||||
str.WriteString("[BUTTONS]:\n")
|
|
||||||
|
|
||||||
for _, b := range m.buttons {
|
|
||||||
str.WriteString(b.String() + "\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
str.WriteString("\n")
|
|
||||||
|
|
||||||
return str.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
type button struct {
|
|
||||||
switchesControlled []int
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b button) String() string {
|
|
||||||
return fmt.Sprintf("%v", b.switchesControlled)
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewButton(line string) button {
|
|
||||||
buttonRegex := regexp.MustCompile(`\d+`)
|
|
||||||
matches := buttonRegex.FindAllString(line, -1)
|
|
||||||
|
|
||||||
switchesControlled := []int{}
|
|
||||||
|
|
||||||
for _, m := range matches {
|
|
||||||
num, _ := strconv.Atoi(m)
|
|
||||||
switchesControlled = append(switchesControlled, num)
|
|
||||||
}
|
|
||||||
|
|
||||||
return button{
|
|
||||||
switchesControlled: switchesControlled,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m machine) Configure(desiredState []bool) int {
|
|
||||||
combinations := [][]bool{}
|
|
||||||
minPresses := math.MaxInt
|
|
||||||
numberOfButtons := len(m.buttons)
|
|
||||||
numberOfCombinations := int(math.Pow(2, float64(numberOfButtons)))
|
|
||||||
currentCombination := make([]bool, numberOfButtons)
|
|
||||||
|
|
||||||
for range numberOfCombinations {
|
|
||||||
temp := make([]bool, numberOfButtons)
|
|
||||||
copy(temp, currentCombination)
|
|
||||||
|
|
||||||
combinations = append(combinations, temp)
|
|
||||||
|
|
||||||
for j := range numberOfButtons {
|
|
||||||
if currentCombination[j] == false {
|
|
||||||
currentCombination[j] = true
|
|
||||||
break
|
|
||||||
} else {
|
|
||||||
currentCombination[j] = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, currentCombination := range combinations {
|
|
||||||
currentPresses := 0
|
|
||||||
switchesCopy := []bool{}
|
|
||||||
|
|
||||||
for _, v := range m.switches {
|
|
||||||
switchesCopy = append(switchesCopy, v)
|
|
||||||
}
|
|
||||||
|
|
||||||
for bi, bs := range currentCombination {
|
|
||||||
if bs == false {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
currentPresses++
|
|
||||||
switchesToToggle := m.buttons[bi].switchesControlled
|
|
||||||
|
|
||||||
for _, switchToToggle := range switchesToToggle {
|
|
||||||
switchesCopy[switchToToggle] = !switchesCopy[switchToToggle]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if slices.Equal(switchesCopy, desiredState) == false {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if currentPresses < minPresses {
|
|
||||||
minPresses = currentPresses
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return minPresses
|
|
||||||
}
|
|
||||||
|
|
||||||
func SolvePartOne(filePath string) int {
|
func SolvePartOne(filePath string) int {
|
||||||
total := 0
|
total := 0
|
||||||
|
|
||||||
for line := range file.ReadLines(filePath) {
|
for line := range file.ReadLines(filePath) {
|
||||||
parts := strings.Split(line, " ")
|
machine := machine.From(line)
|
||||||
lightDiagramPart := parts[0]
|
buttonsPressed := machine.ConfigureLights()
|
||||||
buttonsPart := parts[1 : len(parts)-1]
|
|
||||||
// NOTE: Parse joltage here
|
|
||||||
|
|
||||||
lightDiagram := []bool{}
|
|
||||||
|
|
||||||
for _, c := range lightDiagramPart {
|
|
||||||
if c == '.' {
|
|
||||||
lightDiagram = append(lightDiagram, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
if c == '#' {
|
|
||||||
lightDiagram = append(lightDiagram, true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
numberOfLights := len(lightDiagram)
|
|
||||||
|
|
||||||
machine := NewMachine(numberOfLights, buttonsPart)
|
|
||||||
buttonsPressed := machine.Configure(lightDiagram)
|
|
||||||
total += buttonsPressed
|
total += buttonsPressed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user