[ADD] main: Added day 3 solution
This commit is contained in:
parent
eb79b7712f
commit
c2378bea26
3 changed files with 251 additions and 0 deletions
1
03/input.txt
Normal file
1
03/input.txt
Normal file
File diff suppressed because one or more lines are too long
249
03/main.go
Normal file
249
03/main.go
Normal file
|
|
@ -0,0 +1,249 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
const FILE_PATH = "./input.txt"
|
||||||
|
|
||||||
|
//const FILE_PATH = "./sample.txt"
|
||||||
|
|
||||||
|
func LoadInput(filename string) ([]string, error) {
|
||||||
|
file, err := os.Open(filename)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
var lines []string
|
||||||
|
scanner := bufio.NewScanner(file)
|
||||||
|
for scanner.Scan() {
|
||||||
|
lines = append(lines, scanner.Text())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := scanner.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return lines, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type structuredInput = string
|
||||||
|
|
||||||
|
func TransformInput(lines []string) structuredInput {
|
||||||
|
return strings.Join(lines, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
const PRE_FIX = "mul("
|
||||||
|
|
||||||
|
func IsNummeric(input byte) bool {
|
||||||
|
return input >= '0' && input <= '9'
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExtractNumber(input string, start_index int) (int, int, bool) {
|
||||||
|
var end_index = start_index
|
||||||
|
if !IsNummeric(input[start_index]) {
|
||||||
|
return -1, -1, false
|
||||||
|
}
|
||||||
|
for i := start_index; i < len(input); i++ {
|
||||||
|
if !IsNummeric(input[i]) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
end_index = i
|
||||||
|
}
|
||||||
|
result, error := strconv.Atoi(input[start_index : end_index+1])
|
||||||
|
if error != nil {
|
||||||
|
return -1, -1, false
|
||||||
|
}
|
||||||
|
return result, end_index - start_index + 1, true
|
||||||
|
}
|
||||||
|
|
||||||
|
func CalculateLinePart1(input string) int {
|
||||||
|
var error = -1
|
||||||
|
var success = false
|
||||||
|
var num1 = 0
|
||||||
|
var num2 = 0
|
||||||
|
var num_length = 0
|
||||||
|
var index = 0
|
||||||
|
var result = 0
|
||||||
|
for i := 0; i < len(input); i++ {
|
||||||
|
error = -1
|
||||||
|
for j := 0; j < len(PRE_FIX) && i+j < len(input); j++ {
|
||||||
|
if PRE_FIX[j] != input[i+j] {
|
||||||
|
error = i + j
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
index = i + len(PRE_FIX)
|
||||||
|
|
||||||
|
if error != -1 {
|
||||||
|
i = error
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
num1 = 0
|
||||||
|
num2 = 0
|
||||||
|
|
||||||
|
num1, num_length, success = ExtractNumber(input, index)
|
||||||
|
|
||||||
|
if !success {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
index += num_length
|
||||||
|
|
||||||
|
if input[index] != ',' {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
index++
|
||||||
|
|
||||||
|
num2, num_length, success = ExtractNumber(input, index)
|
||||||
|
|
||||||
|
if !success {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
index += num_length
|
||||||
|
|
||||||
|
if input[index] != ')' {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
result += num1 * num2
|
||||||
|
i = index
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func Part1(input structuredInput) int {
|
||||||
|
return CalculateLinePart1(input)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Method struct {
|
||||||
|
method string
|
||||||
|
num1 int
|
||||||
|
num2 int
|
||||||
|
}
|
||||||
|
|
||||||
|
var METHODS = map[string]func(paramters string) (bool, Method){
|
||||||
|
"mul": func(paramters string) (bool, Method) {
|
||||||
|
var num_length1 = 0
|
||||||
|
var num_length2 = 0
|
||||||
|
var success = false
|
||||||
|
var num1 = 0
|
||||||
|
var num2 = 0
|
||||||
|
|
||||||
|
num1, num_length1, success = ExtractNumber(paramters, 0)
|
||||||
|
|
||||||
|
if !success {
|
||||||
|
return false, Method{}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(paramters) <= num_length1 || paramters[num_length1] != ',' {
|
||||||
|
return false, Method{}
|
||||||
|
}
|
||||||
|
|
||||||
|
num2, num_length2, success = ExtractNumber(paramters, num_length1+1)
|
||||||
|
|
||||||
|
if !success {
|
||||||
|
return false, Method{}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(paramters) > num_length1+num_length2+1 {
|
||||||
|
return false, Method{}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true, Method{"mul", num1, num2}
|
||||||
|
},
|
||||||
|
"do": func(paramters string) (bool, Method) {
|
||||||
|
return len(paramters) == 0, Method{"do", -1, -1}
|
||||||
|
},
|
||||||
|
"don't": func(paramters string) (bool, Method) {
|
||||||
|
return len(paramters) == 0, Method{"don't", -1, -1}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsMethod(line string, method_name string, start_index int) bool {
|
||||||
|
if start_index+len(method_name) >= len(line) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for i := 0; i < len(method_name); i++ {
|
||||||
|
if line[start_index+i] != method_name[i] {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func CalculateLinePart2(line string) int {
|
||||||
|
var result = 0
|
||||||
|
var para_start = 0
|
||||||
|
var para_end = 0
|
||||||
|
|
||||||
|
var success = false
|
||||||
|
var code = make([]Method, 0)
|
||||||
|
var temp Method
|
||||||
|
for i := 0; i < len(line); i++ {
|
||||||
|
for method := range METHODS {
|
||||||
|
if !IsMethod(line, method, i) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
para_start = i + len(method)
|
||||||
|
if line[para_start] != '(' {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
para_end = para_start
|
||||||
|
for para_end < len(line) && line[para_end] != ')' {
|
||||||
|
para_end++
|
||||||
|
}
|
||||||
|
|
||||||
|
if line[para_end] != ')' {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
success, temp = METHODS[method](line[para_start+1 : para_end])
|
||||||
|
if success {
|
||||||
|
code = append(code, temp)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var enabled = true
|
||||||
|
for _, method := range code {
|
||||||
|
switch method.method {
|
||||||
|
case "do":
|
||||||
|
enabled = true
|
||||||
|
case "don't":
|
||||||
|
enabled = false
|
||||||
|
case "mul":
|
||||||
|
if enabled {
|
||||||
|
result += method.num1 * method.num2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func Part2(input structuredInput) int {
|
||||||
|
return CalculateLinePart2(input)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
input, err := LoadInput(FILE_PATH)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error loading input:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
structuredInput := TransformInput(input)
|
||||||
|
fmt.Println("Structured Input:", structuredInput)
|
||||||
|
|
||||||
|
fmt.Println("Solution Part 1: ", Part1(structuredInput))
|
||||||
|
fmt.Println("Solution Part 2: ", Part2(structuredInput))
|
||||||
|
}
|
||||||
1
03/sample.txt
Normal file
1
03/sample.txt
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))
|
||||||
Loading…
Reference in a new issue