mirror of
https://github.com/zebrajr/coding-challenges.git
synced 2026-01-15 12:15:02 +00:00
add part b solver, even if not "ideal"
This commit is contained in:
15
Advent of Code/2024/Day 07/puzzle_b.md
Normal file
15
Advent of Code/2024/Day 07/puzzle_b.md
Normal file
@@ -0,0 +1,15 @@
|
||||
## Part Two
|
||||
|
||||
The engineers seem concerned; the total calibration result you gave them is nowhere close to being within safety tolerances. Just then, you spot your mistake: some well-hidden elephants are holding a third type of operator.
|
||||
|
||||
The concatenation operator (||) combines the digits from its left and right inputs into a single number. For example, 12 || 345 would become 12345. All operators are still evaluated left-to-right.
|
||||
|
||||
Now, apart from the three equations that could be made true using only addition and multiplication, the above example has three more equations that can be made true by inserting operators:
|
||||
|
||||
156: 15 6 can be made true through a single concatenation: 15 || 6 = 156.
|
||||
7290: 6 8 6 15 can be made true using 6 * 8 || 6 * 15.
|
||||
192: 17 8 14 can be made true using 17 || 8 + 14.
|
||||
Adding up all six test values (the three that could be made before using only + and * plus the new three that can now be made by also using ||) produces the new total calibration result of 11387.
|
||||
|
||||
Using your new knowledge of elephant hiding spots, determine which equations could possibly be true. What is their total calibration result?
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"time"
|
||||
"bufio"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -44,14 +45,14 @@ func load_puzzle_from_file(target_file_name string) []equation{
|
||||
return equations_list
|
||||
}
|
||||
|
||||
func generate_combinations(numbers int) []string{
|
||||
func generate_combinations(numbers int, operators []string) []string{
|
||||
if numbers == 0 {
|
||||
return []string {""}
|
||||
}
|
||||
|
||||
combinations := []string{}
|
||||
for _, c := range []string {"+", "*"}{
|
||||
for _, prev := range generate_combinations(numbers -1){
|
||||
for _, c := range operators{
|
||||
for _, prev := range generate_combinations(numbers -1, operators){
|
||||
combinations = append(combinations, prev + string(c))
|
||||
}
|
||||
}
|
||||
@@ -59,11 +60,12 @@ func generate_combinations(numbers int) []string{
|
||||
return combinations
|
||||
}
|
||||
|
||||
func calculate_all_operations_for_equation(eq equation) []string {
|
||||
func calculate_all_operations_for_equation(eq equation, operations []string) []string {
|
||||
var final_list []string
|
||||
combinations := generate_combinations(len(eq.numbers) - 1)
|
||||
list_combinations := generate_combinations(len(eq.numbers) - 1, operations)
|
||||
|
||||
for _, c := range combinations {
|
||||
for _, c := range list_combinations {
|
||||
//log.Println(list_combinations, idx, c)
|
||||
final_list = append(final_list, c)
|
||||
}
|
||||
|
||||
@@ -83,8 +85,14 @@ func is_equation_possible(eq equation, operations []string) bool {
|
||||
if string(op) == "*" {
|
||||
current_result = current_result * eq.numbers[ido + 1]
|
||||
}
|
||||
if string(op) == "|" {
|
||||
temp_a := strconv.Itoa(current_result)
|
||||
temp_b := strconv.Itoa(eq.numbers[ido + 1])
|
||||
result_string := temp_a + temp_b
|
||||
current_result, _ = strconv.Atoi(result_string)
|
||||
}
|
||||
}
|
||||
//fmt.Println("Wanted vs Got: ", eq.target_number, current_result)
|
||||
//log.Println("Wanted vs Got: ", eq.target_number, current_result)
|
||||
if eq.target_number == current_result {
|
||||
return true
|
||||
}
|
||||
@@ -92,14 +100,39 @@ func is_equation_possible(eq equation, operations []string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
func time_track(start time.Time, name string){
|
||||
elapsed := time.Since(start)
|
||||
log.Printf("%s took %s", name, elapsed)
|
||||
}
|
||||
|
||||
func main() {
|
||||
defer time_track(time.Now(), "main")
|
||||
equations := load_puzzle_from_file(puzzle_file_name)
|
||||
final_result := 0
|
||||
possible_operations := []string {"+", "*"}
|
||||
for _, eq := range equations {
|
||||
operations_list := calculate_all_operations_for_equation(eq)
|
||||
operations_list := calculate_all_operations_for_equation(eq, possible_operations)
|
||||
if is_equation_possible(eq, operations_list){
|
||||
final_result += eq.target_number
|
||||
}
|
||||
}
|
||||
fmt.Println("Final Result: ", final_result)
|
||||
log.Println("Final Result - Part A: ", final_result)
|
||||
|
||||
// this is WRONG
|
||||
// the question clearly asks to use "||" as the operators
|
||||
// I don't want to refactor the code base to handle 2 characters for the operations
|
||||
//
|
||||
// the fix would be to instead of returning an array of strings eg: [ +*|| *+|| ]
|
||||
// to instead return a string of strings [ [+ * || ] [ * + || ] ]
|
||||
// which would then allow for safe iteration
|
||||
final_result = 0
|
||||
possible_operations = []string {"+", "*", "|"}
|
||||
for _, eq := range equations {
|
||||
operations_list := calculate_all_operations_for_equation(eq, possible_operations)
|
||||
if is_equation_possible(eq, operations_list){
|
||||
final_result += eq.target_number
|
||||
}
|
||||
}
|
||||
log.Println("Final Result - Part B: ", final_result)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user