Compare commits
4 Commits
main
...
change-inp
| Author | SHA1 | Date | |
|---|---|---|---|
| df779eb510 | |||
| 79f63b0bf0 | |||
| 492d2a602a | |||
| fc9a332e63 |
5
.github/workflows/build.yml
vendored
5
.github/workflows/build.yml
vendored
@ -1,8 +1,5 @@
|
|||||||
name: Build
|
name: Build
|
||||||
on:
|
on: [push]
|
||||||
push:
|
|
||||||
tags:
|
|
||||||
- "^test$"
|
|
||||||
jobs:
|
jobs:
|
||||||
gobuild:
|
gobuild:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@ -22,4 +22,3 @@ go.work
|
|||||||
|
|
||||||
# Problem data
|
# Problem data
|
||||||
input*.txt
|
input*.txt
|
||||||
inputs/
|
|
||||||
|
|||||||
16
README.md
16
README.md
@ -1,16 +0,0 @@
|
|||||||
# Advent of Code 2023
|
|
||||||
|
|
||||||
An attempt to start programming again.
|
|
||||||
|
|
||||||
- [Day 1](./day01/trebuchet.go)
|
|
||||||
- [Day 2](./day02/lottacubes.go)
|
|
||||||
- [Day 3](./day03/engine-schema.go)
|
|
||||||
- [Day 4](./day04/scratchcards.go)
|
|
||||||
- [Day 5](./day05/seeds.go)
|
|
||||||
- [Day 6](./day06/race.go)
|
|
||||||
- [Day 7](./day07/cards.go)
|
|
||||||
- [Day 8](./day08/charpath.go)
|
|
||||||
- [Day 9](./day09/oasis.go)
|
|
||||||
|
|
||||||
|
|
||||||
This repo gets automatically mirrored to [Github](https://github.com/Doddophonique/aoc2023).
|
|
||||||
24
UNLICENSE
24
UNLICENSE
@ -1,24 +0,0 @@
|
|||||||
This is free and unencumbered software released into the public domain.
|
|
||||||
|
|
||||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
|
||||||
distribute this software, either in source code form or as a compiled
|
|
||||||
binary, for any purpose, commercial or non-commercial, and by any
|
|
||||||
means.
|
|
||||||
|
|
||||||
In jurisdictions that recognize copyright laws, the author or authors
|
|
||||||
of this software dedicate any and all copyright interest in the
|
|
||||||
software to the public domain. We make this dedication for the benefit
|
|
||||||
of the public at large and to the detriment of our heirs and
|
|
||||||
successors. We intend this dedication to be an overt act of
|
|
||||||
relinquishment in perpetuity of all present and future rights to this
|
|
||||||
software under copyright law.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
||||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
||||||
OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
For more information, please refer to <http://unlicense.org/>
|
|
||||||
@ -1,220 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
// "strings"
|
|
||||||
"bufio"
|
|
||||||
"os"
|
|
||||||
"regexp"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
func check(e error) {
|
|
||||||
if e != nil {
|
|
||||||
panic(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func PrintAndWait(x ...any) {
|
|
||||||
fmt.Print(x)
|
|
||||||
fmt.Scanln()
|
|
||||||
}
|
|
||||||
|
|
||||||
func MatchNumbers(lines []string, index int, ast []int, total *int) {
|
|
||||||
// Regex that finds the numbers in a row
|
|
||||||
renum := regexp.MustCompile("[0-9]+")
|
|
||||||
// Gather numbers in prev line
|
|
||||||
prevLine := renum.FindAllStringIndex(lines[index-1], -1)
|
|
||||||
// Gather numbers in this line
|
|
||||||
thisLine := renum.FindAllStringIndex(lines[index], -1)
|
|
||||||
// Gather numbers in next line
|
|
||||||
nextLine := renum.FindAllStringIndex(lines[index+1], -1)
|
|
||||||
// Calculate the number of numbers in three lines
|
|
||||||
totalNumbers := len(prevLine) + len(thisLine) + len(nextLine)
|
|
||||||
|
|
||||||
// Now we create a big array with all the indexes
|
|
||||||
allIndexes := prevLine
|
|
||||||
for i := range thisLine {
|
|
||||||
allIndexes = append(allIndexes, thisLine[i])
|
|
||||||
}
|
|
||||||
for i := range nextLine {
|
|
||||||
allIndexes = append(allIndexes, nextLine[i])
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now we create a big array with all the numbers
|
|
||||||
// We start from the previous line
|
|
||||||
allNumbers := renum.FindAllString(lines[index-1], -1)
|
|
||||||
thisNums := renum.FindAllString(lines[index], -1)
|
|
||||||
for i := range thisNums {
|
|
||||||
allNumbers = append(allNumbers, thisNums[i])
|
|
||||||
}
|
|
||||||
nextNums := renum.FindAllString(lines[index+1], -1)
|
|
||||||
for i := range nextNums {
|
|
||||||
allNumbers = append(allNumbers, nextNums[i])
|
|
||||||
}
|
|
||||||
// When we start, we have zero matches
|
|
||||||
matches := 0
|
|
||||||
// We will stop when we encounter two numbers
|
|
||||||
twoNums := [2]int{0, 0}
|
|
||||||
_ = twoNums
|
|
||||||
// Cycling through all numbers, but stopping at two matches
|
|
||||||
for i := 0; i < totalNumbers && matches < 2; i++ {
|
|
||||||
if (ast[0] >= allIndexes[i][0] - 1 && ast[0] <= allIndexes[i][1]) {
|
|
||||||
matches += 1
|
|
||||||
num, _ := strconv.Atoi(allNumbers[i])
|
|
||||||
twoNums[matches - 1] = num
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(matches == 2) {
|
|
||||||
tempGears := twoNums[0] * twoNums[1]
|
|
||||||
*total += tempGears
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func CheckGears(lines []string) {
|
|
||||||
total := 0
|
|
||||||
totalPoint := &total
|
|
||||||
// Regex that finds the numbers in a row
|
|
||||||
//renum := regexp.MustCompile("[0-9]+")
|
|
||||||
// Regex that finds the asterisks in a row
|
|
||||||
resym := regexp.MustCompile("[*]")
|
|
||||||
// For every line starting from the second
|
|
||||||
for i := 0; i < len(lines) - 1; i++ {
|
|
||||||
// Take the index of the asterisks
|
|
||||||
asteriskIndex := resym.FindAllStringIndex(lines[i], - 1)
|
|
||||||
// For every index we get
|
|
||||||
for j := range asteriskIndex {
|
|
||||||
MatchNumbers(lines, i, asteriskIndex[j], totalPoint)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// firstLineNums := renum.FindAllStringIndex(lines[index], -1)
|
|
||||||
// firstLineSymbolsIndex := resym.FindAllStringIndex(lines[index], -1)
|
|
||||||
// secondLineSymbolsIndex := resym.FindAllStringIndex(lines[index + 1], -1)
|
|
||||||
// For every *number index range*, check if in the same line there is a
|
|
||||||
// symbol on (first - 1) or (last + 1), check in other lines if there is
|
|
||||||
// a symbol in a specific interval of numbers. If you find a match, you
|
|
||||||
// can break as you just need one symbol
|
|
||||||
fmt.Printf("Total of gears is: %d\n", total)
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
file, err := os.Open("./inputs/day03_input")
|
|
||||||
check(err)
|
|
||||||
defer file.Close()
|
|
||||||
|
|
||||||
// This regex find the numbers inside strings
|
|
||||||
renum := regexp.MustCompile("[0-9]+")
|
|
||||||
resym := regexp.MustCompile("[^0-9.]+")
|
|
||||||
|
|
||||||
scanner := bufio.NewScanner(file)
|
|
||||||
var lines []string
|
|
||||||
var totalSum int = 0
|
|
||||||
|
|
||||||
// Read the whole file into an array of strings
|
|
||||||
for scanner.Scan() {
|
|
||||||
lines = append(lines, scanner.Text())
|
|
||||||
}
|
|
||||||
numLines := len(lines)
|
|
||||||
numbers := make([][]int, numLines)
|
|
||||||
|
|
||||||
// The 2D array of numbers will hold all the numbers to easily
|
|
||||||
// match them with corresponding strings in the file using the index
|
|
||||||
// For every line in the file, create an array of numbers
|
|
||||||
for i := 0; i < numLines; i++ {
|
|
||||||
tempNums := renum.FindAllString(lines[i], -1)
|
|
||||||
for j := 0; j < len(tempNums); j++ {
|
|
||||||
num, _ := strconv.Atoi(tempNums[j])
|
|
||||||
numbers[i] = append(numbers[i], num)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Line [0] needs to check only line 1 for symbols.
|
|
||||||
Similarly, the last line needs to check only
|
|
||||||
(last line index - 1) for symbols.
|
|
||||||
So we first check the line [0], then start a loop
|
|
||||||
from 1 to (last line index - 1)
|
|
||||||
*/
|
|
||||||
firstLineNums := renum.FindAllStringIndex(lines[0], -1)
|
|
||||||
firstLineSymbolsIndex := resym.FindAllStringIndex(lines[0], -1)
|
|
||||||
secondLineSymbolsIndex := resym.FindAllStringIndex(lines[1], -1)
|
|
||||||
// For every *number index range*, check if in the same line there is a
|
|
||||||
// symbol on (first - 1) or (last + 1), check in other lines if there is
|
|
||||||
// a symbol in a specific interval of numbers. If you find a match, you
|
|
||||||
// can break as you just need one symbol
|
|
||||||
for i := range firstLineNums {
|
|
||||||
for j := range firstLineSymbolsIndex {
|
|
||||||
if firstLineSymbolsIndex[j][0] >= firstLineNums[i][0] - 1 &&
|
|
||||||
(firstLineSymbolsIndex[j][0] <= firstLineNums[i][1]) {
|
|
||||||
totalSum += numbers[0][i]
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for j := range secondLineSymbolsIndex {
|
|
||||||
if (secondLineSymbolsIndex[j][0] >= firstLineNums[i][0] - 1) &&
|
|
||||||
(secondLineSymbolsIndex[j][0] <= firstLineNums[i][1]) {
|
|
||||||
totalSum += numbers[0][i]
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Now we loop from 1 to (last index - i)
|
|
||||||
for i := 1; i < len(lines) - 1; i++ {
|
|
||||||
// We need to check the current line against an interval of three lines
|
|
||||||
// breaking the loop for a single number as soon as we find a match
|
|
||||||
// (we don't want duplicate matches)
|
|
||||||
currentLineNums := renum.FindAllStringIndex(lines[i], -1)
|
|
||||||
previousLineIndex := resym.FindAllStringIndex(lines[i - 1], -1)
|
|
||||||
currentLineIndex := resym.FindAllStringIndex(lines[i], -1)
|
|
||||||
nextLineIndex := resym.FindAllStringIndex(lines[i + 1], -1)
|
|
||||||
OuterLoop:
|
|
||||||
for k := range currentLineNums {
|
|
||||||
for j := range previousLineIndex {
|
|
||||||
if previousLineIndex[j][0] >= currentLineNums[k][0] - 1 &&
|
|
||||||
previousLineIndex[j][0] <= currentLineNums[k][1] {
|
|
||||||
totalSum += numbers[i][k]
|
|
||||||
continue OuterLoop
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for j := range currentLineIndex {
|
|
||||||
if currentLineIndex[j][0] >= currentLineNums[k][0] - 1 &&
|
|
||||||
currentLineIndex[j][0] <= currentLineNums[k][1] {
|
|
||||||
totalSum += numbers[i][k]
|
|
||||||
continue OuterLoop
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for j := range nextLineIndex {
|
|
||||||
if nextLineIndex[j][0] >= currentLineNums[k][0] - 1 &&
|
|
||||||
nextLineIndex[j][0] <= currentLineNums[k][1] {
|
|
||||||
totalSum += numbers[i][k]
|
|
||||||
continue OuterLoop
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Now we need to loop the last line and confront it with previous
|
|
||||||
// and itself
|
|
||||||
lastLineNums := renum.FindAllStringIndex(lines[len(lines) - 1], -1)
|
|
||||||
lastLineSymbolsIndex := resym.FindAllStringIndex(lines[len(lines) - 1], -1)
|
|
||||||
notLastLineSymbolsIndex := resym.FindAllStringIndex(lines[len(lines) - 2], -1)
|
|
||||||
// For every *number index range*, check if in the same line there is a
|
|
||||||
// symbol on (last - 1) or (last + 1), check in other lines if there is
|
|
||||||
// a symbol in a specific interval of numbers. If you find a match, you
|
|
||||||
// can break as you just need one symbol
|
|
||||||
for i := range lastLineNums {
|
|
||||||
for j := range lastLineSymbolsIndex {
|
|
||||||
if lastLineSymbolsIndex[j][0] >= lastLineNums[i][0] - 1 &&
|
|
||||||
(lastLineSymbolsIndex[j][0] <= lastLineNums[i][1]) {
|
|
||||||
totalSum += numbers[len(lines) - 1][i]
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for j := range notLastLineSymbolsIndex {
|
|
||||||
if (notLastLineSymbolsIndex[j][0] >= lastLineNums[i][0] - 1) &&
|
|
||||||
(notLastLineSymbolsIndex[j][0] <= lastLineNums[i][1]) {
|
|
||||||
totalSum += numbers[len(lines) - 1][i]
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fmt.Printf("The total sum is: %d\n", totalSum)
|
|
||||||
CheckGears(lines)
|
|
||||||
}
|
|
||||||
@ -1 +0,0 @@
|
|||||||
../inputs
|
|
||||||
@ -1 +0,0 @@
|
|||||||
../inputs
|
|
||||||
@ -1,115 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"bufio"
|
|
||||||
"os"
|
|
||||||
// "strconv"
|
|
||||||
"regexp"
|
|
||||||
)
|
|
||||||
|
|
||||||
func check(e error) {
|
|
||||||
if e != nil {
|
|
||||||
panic(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func PrintAndWait(x ...any) {
|
|
||||||
fmt.Print(x)
|
|
||||||
fmt.Scanln()
|
|
||||||
}
|
|
||||||
|
|
||||||
func SplitSets(s []string) ([]string, []string) {
|
|
||||||
|
|
||||||
// Split the two sets into winning and my numbers
|
|
||||||
tempwinningNumbers := s[0]
|
|
||||||
tempMyNumbers := s[1]
|
|
||||||
// Regex to populate a string with numbers
|
|
||||||
renum := regexp.MustCompile("[0-9]+")
|
|
||||||
myNumbers := renum.FindAllString(tempMyNumbers, -1)
|
|
||||||
winningNumbers := renum.FindAllString(tempwinningNumbers, -1)
|
|
||||||
|
|
||||||
return myNumbers, winningNumbers
|
|
||||||
}
|
|
||||||
|
|
||||||
func FindMatches(myNum []string, winNum []string) int {
|
|
||||||
matches := 0
|
|
||||||
for i := range myNum {
|
|
||||||
for j := range winNum {
|
|
||||||
if (myNum[i] == winNum[j]) {
|
|
||||||
matches += 1
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return matches
|
|
||||||
}
|
|
||||||
|
|
||||||
func CalcTickets(s []string, index int, tpr []int ) {
|
|
||||||
|
|
||||||
myNumbers, winningNumbers := SplitSets(s)
|
|
||||||
matches := FindMatches(myNumbers, winningNumbers)
|
|
||||||
if (matches > 0) {
|
|
||||||
for j := 0; j < tpr[index]; j++ {
|
|
||||||
for i := index; i < index + matches; i++ {
|
|
||||||
tpr[i+1] += 1
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func CalcScore (s []string, t *int) {
|
|
||||||
|
|
||||||
myNumbers, winningNumbers := SplitSets(s)
|
|
||||||
matches := FindMatches(myNumbers, winningNumbers)
|
|
||||||
if(matches > 0) {
|
|
||||||
tempTotal := 1
|
|
||||||
for i := 0; i < matches - 1; i++ {
|
|
||||||
tempTotal *= 2
|
|
||||||
}
|
|
||||||
*t += tempTotal
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
file, err := os.Open("./inputs/day04_input")
|
|
||||||
check(err)
|
|
||||||
defer file.Close()
|
|
||||||
|
|
||||||
// The total is a simple sum
|
|
||||||
var total int = 0
|
|
||||||
var totalPoint *int = &total
|
|
||||||
// To keep track of the amount of tickets, an array as long
|
|
||||||
// as the number of lines
|
|
||||||
var lines []string
|
|
||||||
scanner := bufio.NewScanner(file)
|
|
||||||
for scanner.Scan() {
|
|
||||||
lines = append(lines, scanner.Text())
|
|
||||||
}
|
|
||||||
ticketsPerRow := make([]int, len(lines))
|
|
||||||
tprPoint := ticketsPerRow[0:len(lines)]
|
|
||||||
|
|
||||||
for i := range ticketsPerRow {
|
|
||||||
ticketsPerRow[i] = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scan every line
|
|
||||||
for i := 0; i < len(lines); i++ {
|
|
||||||
// e.g.: Card 1: 41 48 83 86 17 | 83 86 6 31 17 9 48 53
|
|
||||||
cardAndNumbers := strings.Split(lines[i], ":")
|
|
||||||
// At this point, cardAndNumbers has "Card N"
|
|
||||||
// We don't need this information (yet?)
|
|
||||||
allNumbers := strings.Split(cardAndNumbers[1], "|")
|
|
||||||
CalcScore(allNumbers, totalPoint)
|
|
||||||
CalcTickets(allNumbers, i, tprPoint)
|
|
||||||
}
|
|
||||||
|
|
||||||
numTickets := 0
|
|
||||||
for i := range ticketsPerRow {
|
|
||||||
numTickets += ticketsPerRow[i]
|
|
||||||
}
|
|
||||||
fmt.Printf("The scratchcards are worth %d points.\n", total)
|
|
||||||
fmt.Printf("In total, I have %d scratchcards.", numTickets)
|
|
||||||
}
|
|
||||||
@ -1 +0,0 @@
|
|||||||
../inputs
|
|
||||||
158
day05/seeds.go
158
day05/seeds.go
@ -1,158 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
// "strings"
|
|
||||||
"bufio"
|
|
||||||
"math"
|
|
||||||
"os"
|
|
||||||
"strconv"
|
|
||||||
"regexp"
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Minimum struct {
|
|
||||||
mu sync.Mutex
|
|
||||||
minimum int
|
|
||||||
}
|
|
||||||
func check(e error) {
|
|
||||||
if e != nil {
|
|
||||||
panic(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func PrintAndWait(x ...any) {
|
|
||||||
fmt.Print(x...)
|
|
||||||
fmt.Scanln()
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetMaps(scanner *bufio.Scanner, re *regexp.Regexp) [][]int {
|
|
||||||
// Scan until there is an empty line
|
|
||||||
var tempNums int = 0
|
|
||||||
tempArray := make([][]int, 0)
|
|
||||||
for i := 0; scanner.Scan() && scanner.Text() != ""; i++ {
|
|
||||||
tempString := re.FindAllString(scanner.Text(), -1)
|
|
||||||
temp := make([]int, 0)
|
|
||||||
for j := range tempString {
|
|
||||||
tempNums, _ = strconv.Atoi(tempString[j])
|
|
||||||
temp = append(temp, tempNums)
|
|
||||||
}
|
|
||||||
tempArray = append(tempArray, temp)
|
|
||||||
}
|
|
||||||
// Prepare for next line
|
|
||||||
scanner.Scan()
|
|
||||||
return tempArray
|
|
||||||
}
|
|
||||||
|
|
||||||
func (min *Minimum) ParallelMinimum(start, finish int, atrocity [][][]int, wg *sync.WaitGroup) {
|
|
||||||
// We check the array one by one, need a temp array because
|
|
||||||
// SeedToLocation wants it
|
|
||||||
tempNum := make([]int, 1)
|
|
||||||
tempMin := []int{0}
|
|
||||||
_ = tempMin
|
|
||||||
for i := 0; i < finish; i++ {
|
|
||||||
tempNum[0] = start + i
|
|
||||||
tempMin := SeedToLocation(tempNum, atrocity)
|
|
||||||
// Need to modify a shared variable, lock
|
|
||||||
min.mu.Lock()
|
|
||||||
if tempMin[0] < min.minimum {
|
|
||||||
min.minimum = tempMin[0]
|
|
||||||
}
|
|
||||||
min.mu.Unlock()
|
|
||||||
}
|
|
||||||
// We finished with the Goroutine
|
|
||||||
wg.Done()
|
|
||||||
}
|
|
||||||
|
|
||||||
func SeedToLocation(seeds []int, atrocity [][][]int) []int {
|
|
||||||
tempRes := seeds
|
|
||||||
for i := range atrocity {
|
|
||||||
tempRes = NextResource(tempRes, atrocity[i])
|
|
||||||
}
|
|
||||||
return tempRes
|
|
||||||
}
|
|
||||||
|
|
||||||
func NextResource(previous []int, resource [][]int) []int {
|
|
||||||
tempRes := make([]int, 0)
|
|
||||||
// [0] is dest, [1] is source, [2] is range
|
|
||||||
for i := range previous {
|
|
||||||
for j := range resource {
|
|
||||||
if previous[i] >= resource[j][1] &&
|
|
||||||
previous[i] <= (resource[j][1] + resource[j][2] - 1) {
|
|
||||||
tempRes = append(tempRes, previous[i] + (resource[j][0] - resource[j][1]))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// If we didn't add an element to the array
|
|
||||||
if len(tempRes) == i {
|
|
||||||
tempRes = append(tempRes, previous[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return tempRes
|
|
||||||
}
|
|
||||||
func main () {
|
|
||||||
file, err := os.Open("./inputs/day05_input")
|
|
||||||
check(err)
|
|
||||||
defer file.Close()
|
|
||||||
|
|
||||||
min := Minimum{
|
|
||||||
minimum: math.MaxInt,
|
|
||||||
}
|
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
|
||||||
|
|
||||||
// Regex that finds the numbers in a row
|
|
||||||
renum := regexp.MustCompile("[0-9]+")
|
|
||||||
|
|
||||||
var seeds []int
|
|
||||||
var soils, fertilizers, waters, lights, temperatures,
|
|
||||||
humidities, locations [][]int
|
|
||||||
scanner := bufio.NewScanner(file)
|
|
||||||
// We know that the seeds only have one row
|
|
||||||
scanner.Scan()
|
|
||||||
// Put all the numbers in an array of strings
|
|
||||||
seedsNums := renum.FindAllString(scanner.Text(), -1)
|
|
||||||
// Extract every number from the string
|
|
||||||
for i := 0; i < len(seedsNums); i++ {
|
|
||||||
num, _ := strconv.Atoi(seedsNums[i])
|
|
||||||
seeds = append(seeds, num)
|
|
||||||
}
|
|
||||||
// We know we have an empty string and just a title, skip them
|
|
||||||
scanner.Scan()
|
|
||||||
scanner.Scan()
|
|
||||||
// Should be possible to just pass the scanner
|
|
||||||
soils = GetMaps(scanner, renum)
|
|
||||||
fertilizers = GetMaps(scanner, renum)
|
|
||||||
waters = GetMaps(scanner, renum)
|
|
||||||
lights = GetMaps(scanner, renum)
|
|
||||||
temperatures = GetMaps(scanner, renum)
|
|
||||||
humidities = GetMaps(scanner, renum)
|
|
||||||
locations = GetMaps(scanner, renum)
|
|
||||||
|
|
||||||
tempRes := make([]int, 0)
|
|
||||||
// Actually insane behaviour
|
|
||||||
monster := [][][]int{
|
|
||||||
soils, fertilizers, waters,
|
|
||||||
lights, temperatures, humidities,
|
|
||||||
locations,
|
|
||||||
}
|
|
||||||
// Send the seeds, receive
|
|
||||||
tempRes = SeedToLocation(seeds, monster)
|
|
||||||
|
|
||||||
minimum := math.MaxInt
|
|
||||||
for i := range tempRes {
|
|
||||||
if tempRes[i] < minimum {
|
|
||||||
minimum = tempRes[i]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fmt.Printf("Minimum of first part: %d\n", minimum)
|
|
||||||
|
|
||||||
// Actual madness
|
|
||||||
for i := 0; i < len(seeds); i += 2 {
|
|
||||||
wg.Add(1)
|
|
||||||
go min.ParallelMinimum(seeds[i], seeds[i+1], monster, &wg)
|
|
||||||
}
|
|
||||||
|
|
||||||
wg.Wait()
|
|
||||||
//tempRes = SeedToLocation(allSeeds, monster)
|
|
||||||
fmt.Printf("Minimum of second part: %d\n", min.minimum)
|
|
||||||
}
|
|
||||||
@ -1 +0,0 @@
|
|||||||
../inputs
|
|
||||||
126
day06/race.go
126
day06/race.go
@ -1,126 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
// "strings"
|
|
||||||
"bufio"
|
|
||||||
// "math"
|
|
||||||
"os"
|
|
||||||
"strconv"
|
|
||||||
"regexp"
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Race struct {
|
|
||||||
mu sync.Mutex
|
|
||||||
total int
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *Race) WeRaceBoys(time, distance int, wg *sync.WaitGroup) {
|
|
||||||
// As we just need to find the minimum necessary and then subtract it from
|
|
||||||
// the maximum, probably a good idea starting form the middle
|
|
||||||
tempTime := 0
|
|
||||||
for i := int(time/2); i > 0; i-- {
|
|
||||||
tempDist := i * (time - i)
|
|
||||||
if tempDist <= distance {
|
|
||||||
tempTime = i + 1
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// If the minimum is tempTime, then the maximum is time - tempTime
|
|
||||||
// time - 2*tempTime is the number of possible victories
|
|
||||||
r.mu.Lock()
|
|
||||||
r.total *= (time - (2 * tempTime - 1))
|
|
||||||
r.mu.Unlock()
|
|
||||||
wg.Done()
|
|
||||||
}
|
|
||||||
|
|
||||||
func MultRaceDist(time, dist []string) ([]int, []int){
|
|
||||||
tempT, tempD := make([]int, 0), make([]int, 0)
|
|
||||||
for i := range time {
|
|
||||||
num, _ := strconv.Atoi(time[i])
|
|
||||||
tempT = append(tempT, num)
|
|
||||||
num, _ = strconv.Atoi(dist[i])
|
|
||||||
tempD = append(tempD, num)
|
|
||||||
}
|
|
||||||
return tempT, tempD
|
|
||||||
}
|
|
||||||
|
|
||||||
func SingleRaceDist(time, dist []string) (int, int) {
|
|
||||||
strT, strD := "", ""
|
|
||||||
numT, numD := 0, 0
|
|
||||||
// Create two big strings
|
|
||||||
for i := range time {
|
|
||||||
strT += time[i]
|
|
||||||
strD += dist[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
numT, _ = strconv.Atoi(strT)
|
|
||||||
numD, _ = strconv.Atoi(strD)
|
|
||||||
|
|
||||||
return numT, numD
|
|
||||||
}
|
|
||||||
|
|
||||||
func check(e error) {
|
|
||||||
if e != nil {
|
|
||||||
panic(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func PrintAndWait(x ...any) {
|
|
||||||
fmt.Print(x...)
|
|
||||||
fmt.Scanln()
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
|
|
||||||
file, err := os.Open("./inputs/day06_input")
|
|
||||||
check(err)
|
|
||||||
defer file.Close()
|
|
||||||
|
|
||||||
// Struct for multiple races
|
|
||||||
rMult := Race{
|
|
||||||
total: 1,
|
|
||||||
}
|
|
||||||
// Struct for a single race
|
|
||||||
rSing := Race{
|
|
||||||
total: 1,
|
|
||||||
}
|
|
||||||
_ = &rSing
|
|
||||||
var wg sync.WaitGroup
|
|
||||||
|
|
||||||
// Regex that finds the numbers in a row
|
|
||||||
renum := regexp.MustCompile("[0-9]+")
|
|
||||||
|
|
||||||
scanner := bufio.NewScanner(file)
|
|
||||||
time, distance := make([]int, 0), make([]int, 0)
|
|
||||||
tempStrings := make([]string, 0)
|
|
||||||
// Generic, would work for more rows
|
|
||||||
for scanner.Scan() {
|
|
||||||
tempStrings = append(tempStrings, scanner.Text())
|
|
||||||
}
|
|
||||||
// Now populate time and distance
|
|
||||||
timeStr := renum.FindAllString(tempStrings[0], - 1)
|
|
||||||
distStr := renum.FindAllString(tempStrings[1], - 1)
|
|
||||||
|
|
||||||
time, distance = MultRaceDist(timeStr, distStr)
|
|
||||||
|
|
||||||
// E.g.: if I hold the button for 1ms and then release it, it will travel at
|
|
||||||
// 1mm/ms fo the remaining amount of seconds.
|
|
||||||
// We can skip the holding down 0 and tMAX ms.
|
|
||||||
// Once we find the MIN amount of ms necessary to win, the limit is
|
|
||||||
// MAX - MIN
|
|
||||||
wg.Add(len(time))
|
|
||||||
for i := 0; i < len(time); i++ {
|
|
||||||
go rMult.WeRaceBoys(time[i], distance[i], &wg)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Silly implementation of the single race
|
|
||||||
singT, singD := SingleRaceDist(timeStr, distStr)
|
|
||||||
wg.Add(1)
|
|
||||||
go rSing.WeRaceBoys(singT, singD, &wg)
|
|
||||||
|
|
||||||
wg.Wait()
|
|
||||||
fmt.Printf("Multiple races result: %d.\n", rMult.total)
|
|
||||||
fmt.Printf("Single race result: %d.\n", rSing.total)
|
|
||||||
}
|
|
||||||
366
day07/cards.go
366
day07/cards.go
@ -1,366 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"fmt"
|
|
||||||
"math"
|
|
||||||
"strings"
|
|
||||||
"os"
|
|
||||||
"strconv"
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
var mapSeedsFirst = map[string]int{
|
|
||||||
"A": 12,
|
|
||||||
"K": 11,
|
|
||||||
"Q": 10,
|
|
||||||
"J": 9,
|
|
||||||
"T": 8,
|
|
||||||
"9": 7,
|
|
||||||
"8": 6,
|
|
||||||
"7": 5,
|
|
||||||
"6": 4,
|
|
||||||
"5": 3,
|
|
||||||
"4": 2,
|
|
||||||
"3": 1,
|
|
||||||
"2": 0,
|
|
||||||
}
|
|
||||||
|
|
||||||
var mapSeedsSecond = map[string]int{
|
|
||||||
"A": 12,
|
|
||||||
"K": 11,
|
|
||||||
"Q": 10,
|
|
||||||
"T": 9,
|
|
||||||
"9": 8,
|
|
||||||
"8": 7,
|
|
||||||
"7": 6,
|
|
||||||
"6": 5,
|
|
||||||
"5": 4,
|
|
||||||
"4": 3,
|
|
||||||
"3": 2,
|
|
||||||
"2": 1,
|
|
||||||
"J": 0,
|
|
||||||
}
|
|
||||||
|
|
||||||
type Game struct {
|
|
||||||
mu sync.Mutex
|
|
||||||
ranks []int
|
|
||||||
// 0: High card, 1: One pair, 2: Two pair, 3: Three of a kind
|
|
||||||
// 4: Full house, 5: Four of a kind, 6: Five of a kind
|
|
||||||
typeOfHand [7][]string
|
|
||||||
indexOfHand [7][]int
|
|
||||||
baseThirteen [7][]int
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *Game) ChangeBase(hType, index int, mapSeeds map[string]int, wg *sync.WaitGroup) {
|
|
||||||
// Starting from the first char [0], we create the base13 num
|
|
||||||
chars := len(g.typeOfHand[hType][index])
|
|
||||||
baseTN := g.typeOfHand[hType][index]
|
|
||||||
decNum := 0
|
|
||||||
for i := 0; i < chars; i++ {
|
|
||||||
// This should be refactored to be a bit more legible
|
|
||||||
// It just computes N * 13^i and adds it over
|
|
||||||
decNum += int(float64(mapSeeds[string(baseTN[i])]) * math.Pow(13, float64(chars-i)))
|
|
||||||
}
|
|
||||||
g.baseThirteen[hType][index] = decNum
|
|
||||||
wg.Done()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *Game) AnalyzeMap(cards string, index, mapSize, offset int) {
|
|
||||||
// The offset defaults to 0 for the regular game
|
|
||||||
// it is +1 for a game with Jokers\
|
|
||||||
mapSeed := mapSeedsFirst
|
|
||||||
if offset != 0 {
|
|
||||||
mapSeed = mapSeedsSecond
|
|
||||||
}
|
|
||||||
switch mapSize {
|
|
||||||
// Five of a kind
|
|
||||||
case 1:
|
|
||||||
g.mu.Lock()
|
|
||||||
g.typeOfHand[6] = append(g.typeOfHand[6], cards)
|
|
||||||
g.indexOfHand[6] = append(g.indexOfHand[6], index)
|
|
||||||
g.mu.Unlock()
|
|
||||||
// Four of a kind || Full House
|
|
||||||
case 2:
|
|
||||||
i := FullOrFour(cards, offset, mapSeed)
|
|
||||||
g.mu.Lock()
|
|
||||||
g.typeOfHand[i] = append(g.typeOfHand[i], cards)
|
|
||||||
g.indexOfHand[i] = append(g.indexOfHand[i], index)
|
|
||||||
g.mu.Unlock()
|
|
||||||
// Three of a kind || Two pair
|
|
||||||
case 3:
|
|
||||||
i := ThreeOrTwo(cards, offset, mapSeed)
|
|
||||||
g.mu.Lock()
|
|
||||||
g.typeOfHand[i] = append(g.typeOfHand[i], cards)
|
|
||||||
g.indexOfHand[i] = append(g.indexOfHand[i], index)
|
|
||||||
g.mu.Unlock()
|
|
||||||
// One pair
|
|
||||||
case 4:
|
|
||||||
g.mu.Lock()
|
|
||||||
g.typeOfHand[1] = append(g.typeOfHand[1], cards)
|
|
||||||
g.indexOfHand[1] = append(g.indexOfHand[1], index)
|
|
||||||
g.mu.Unlock()
|
|
||||||
// High card
|
|
||||||
case 5:
|
|
||||||
g.mu.Lock()
|
|
||||||
g.typeOfHand[0] = append(g.typeOfHand[0], cards)
|
|
||||||
g.indexOfHand[0] = append(g.indexOfHand[0], index)
|
|
||||||
g.mu.Unlock()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *Game) DetermineType(cards string, index int, wg *sync.WaitGroup) {
|
|
||||||
// We create a map and we check the length. Depending on the length, we
|
|
||||||
// insert the string in a specific type
|
|
||||||
m := make(map[string]int)
|
|
||||||
for i := 0; i < len(cards); i++ {
|
|
||||||
key := string(cards[i])
|
|
||||||
m[key] = mapSeedsFirst[key]
|
|
||||||
}
|
|
||||||
// Now, depending on the number of elements in the map, we can assign
|
|
||||||
// append cards to a specific rank
|
|
||||||
mapSize := len(m)
|
|
||||||
g.AnalyzeMap(cards, index, mapSize, 0)
|
|
||||||
|
|
||||||
wg.Done()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *Game) SecondGame(cards string, index int, wg *sync.WaitGroup) {
|
|
||||||
// If I don't have Js, run the standard DetermineType
|
|
||||||
m := make(map[string]int)
|
|
||||||
n := make(map[string]int)
|
|
||||||
for i := 0; i < len(cards); i++ {
|
|
||||||
key := string(cards[i])
|
|
||||||
// We need to track the number of Js
|
|
||||||
m[key] += 1
|
|
||||||
// This is to track the type of hand, knowing the number of Js
|
|
||||||
n[key] = mapSeedsSecond[key]
|
|
||||||
}
|
|
||||||
mapSize := len(n)
|
|
||||||
switch m["J"] {
|
|
||||||
case 0:
|
|
||||||
// We have a hand without Js
|
|
||||||
wg.Add(1)
|
|
||||||
g.DetermineType(cards, index, wg)
|
|
||||||
case 1:
|
|
||||||
// If there is a J, J can be use is not adding information, therefore -1
|
|
||||||
g.AnalyzeMap(cards, index, (mapSize - 1), 1)
|
|
||||||
case 2:
|
|
||||||
g.AnalyzeMap(cards, index, (mapSize - 1), 2)
|
|
||||||
case 3:
|
|
||||||
g.AnalyzeMap(cards, index, (mapSize - 1), 3)
|
|
||||||
case 4:
|
|
||||||
g.AnalyzeMap(cards, index, (mapSize - 1), 4)
|
|
||||||
case 5:
|
|
||||||
wg.Add(1)
|
|
||||||
g.DetermineType(cards, index, wg)
|
|
||||||
}
|
|
||||||
wg.Done()
|
|
||||||
}
|
|
||||||
|
|
||||||
func ThreeOrTwo(cards string, offset int, mapSeed map[string]int) int {
|
|
||||||
m := make(map[string]int)
|
|
||||||
for i := 0; i < len(cards); i++ {
|
|
||||||
key := string(cards[i])
|
|
||||||
m[key] += 1
|
|
||||||
}
|
|
||||||
// If we are in the second game, remove J
|
|
||||||
if mapSeed["J"] == 0 {
|
|
||||||
m["J"] = 0
|
|
||||||
}
|
|
||||||
// m[i] returns 0 if the element is not in the map. I take advantage
|
|
||||||
// of that
|
|
||||||
tempNum := 0
|
|
||||||
for i := range mapSeed {
|
|
||||||
if m[i] > tempNum {
|
|
||||||
tempNum = m[i]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// If an element has 3 values, we have a three of a kind
|
|
||||||
if tempNum+offset == 3 {
|
|
||||||
return 3
|
|
||||||
/// If an element has 2 values, we have a two pair
|
|
||||||
} else if tempNum+offset == 2 {
|
|
||||||
return 2
|
|
||||||
}
|
|
||||||
PrintAndWait("This has run for ", cards)
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
func FullOrFour(cards string, offset int, mapSeed map[string]int) int {
|
|
||||||
m := make(map[string]int)
|
|
||||||
for i := 0; i < len(cards); i++ {
|
|
||||||
key := string(cards[i])
|
|
||||||
m[key] += 1
|
|
||||||
}
|
|
||||||
// If we are in the second game, remove J
|
|
||||||
if mapSeed["J"] == 0 {
|
|
||||||
m["J"] = 0
|
|
||||||
}
|
|
||||||
// m[i] returns 0 if the element is not in the map. I take advantage
|
|
||||||
// of that
|
|
||||||
// Better to save the maximum number
|
|
||||||
tempNum := 0
|
|
||||||
for i := range mapSeed {
|
|
||||||
if m[i] > tempNum {
|
|
||||||
tempNum = m[i]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// If an element has four values, we have a Four of a kind
|
|
||||||
if tempNum+offset == 4 {
|
|
||||||
return 5
|
|
||||||
/// If an element has 3 values, we have a Full House
|
|
||||||
} else if tempNum+offset == 3 {
|
|
||||||
return 4
|
|
||||||
}
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
|
|
||||||
func check(e error) {
|
|
||||||
if e != nil {
|
|
||||||
panic(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func PrintAndWait(x ...any) {
|
|
||||||
fmt.Print(x...)
|
|
||||||
fmt.Scanln()
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://www.golangprograms.com/golang-program-for-implementation-of-quick-sort.html
|
|
||||||
// I need to learn how this shing works
|
|
||||||
func quicksort(a, h []int, hType int) []int {
|
|
||||||
if len(a) < 2 {
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
|
|
||||||
left, right := 0, len(a)-1
|
|
||||||
|
|
||||||
pivot := 0
|
|
||||||
|
|
||||||
a[pivot], a[right] = a[right], a[pivot]
|
|
||||||
h[pivot], h[right] = h[right], h[pivot]
|
|
||||||
|
|
||||||
for i, _ := range a {
|
|
||||||
if a[i] < a[right] {
|
|
||||||
a[left], a[i] = a[i], a[left]
|
|
||||||
h[left], h[i] = h[i], h[left]
|
|
||||||
left++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
a[left], a[right] = a[right], a[left]
|
|
||||||
h[left], h[right] = h[right], h[left]
|
|
||||||
|
|
||||||
quicksort(a[:left], h[:left], hType)
|
|
||||||
quicksort(a[left+1:], h[left+1:], hType)
|
|
||||||
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
|
|
||||||
file, err := os.Open("./inputs/day07_input")
|
|
||||||
check(err)
|
|
||||||
defer file.Close()
|
|
||||||
|
|
||||||
// Struct for regular game
|
|
||||||
g := Game{}
|
|
||||||
// Struct for the Joker game
|
|
||||||
jo := Game{}
|
|
||||||
|
|
||||||
// Variable where we store every line in the file
|
|
||||||
lines := make([]string, 0)
|
|
||||||
|
|
||||||
scanner := bufio.NewScanner(file)
|
|
||||||
for scanner.Scan() {
|
|
||||||
lines = append(lines, scanner.Text())
|
|
||||||
}
|
|
||||||
// Array of strings, set of cards
|
|
||||||
var cards []string
|
|
||||||
// Array of int, bet
|
|
||||||
var bet []int
|
|
||||||
// Now, split the lines
|
|
||||||
for i := 0; i < len(lines); i++ {
|
|
||||||
tempString := strings.Split(lines[i], " ")
|
|
||||||
cards = append(cards, tempString[0])
|
|
||||||
tempNum, _ := strconv.Atoi(tempString[1])
|
|
||||||
bet = append(bet, tempNum)
|
|
||||||
}
|
|
||||||
// Rank will be from 1 to len(lines)
|
|
||||||
g.ranks = make([]int, len(lines))
|
|
||||||
jo.ranks = make([]int, len(lines))
|
|
||||||
// What do we know for sure? 5 identical seeds are the highest ranks,
|
|
||||||
// 5 completely different seeds are the lowest ranks.
|
|
||||||
// We can iterate for every set of cards, and do different things
|
|
||||||
// if the map we build has one element, five elements or the worst
|
|
||||||
// case (two, three or four elements).
|
|
||||||
//
|
|
||||||
// Two identical: 4oK or FH
|
|
||||||
// Three identical: 3oK or 22
|
|
||||||
// Four identical: 12
|
|
||||||
//
|
|
||||||
// With this, I put every typeOfHand in a different array
|
|
||||||
var wg sync.WaitGroup
|
|
||||||
wg.Add(2 * len(lines))
|
|
||||||
for i := 0; i < len(lines); i++ {
|
|
||||||
g.DetermineType(cards[i], i, &wg)
|
|
||||||
jo.SecondGame(cards[i], i, &wg)
|
|
||||||
}
|
|
||||||
|
|
||||||
wg.Wait()
|
|
||||||
// Now that g.typeOfHand has every type of hand separated, the rank
|
|
||||||
// is determined by the first card(s). I can convert every number
|
|
||||||
// to a base 13 representation and sort.
|
|
||||||
// In g.indexOfHand I have the index of the corresponding type.
|
|
||||||
|
|
||||||
// For every type of hand
|
|
||||||
for i := range g.typeOfHand {
|
|
||||||
// As many wait groups as the element we will iterate
|
|
||||||
wg.Add(len(g.typeOfHand[i]))
|
|
||||||
wg.Add(len(jo.typeOfHand[i]))
|
|
||||||
// We also need to initialize the array g.baseThirteen so we can
|
|
||||||
// keep the same index
|
|
||||||
g.baseThirteen[i] = make([]int, len(g.typeOfHand[i]))
|
|
||||||
jo.baseThirteen[i] = make([]int, len(jo.typeOfHand[i]))
|
|
||||||
// For every element in a single type of hand
|
|
||||||
for j := range g.typeOfHand[i] {
|
|
||||||
g.ChangeBase(i, j, mapSeedsFirst, &wg)
|
|
||||||
}
|
|
||||||
for j := range jo.typeOfHand[i] {
|
|
||||||
jo.ChangeBase(i, j, mapSeedsSecond, &wg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
wg.Wait()
|
|
||||||
|
|
||||||
// A sort of some kind. Important is to also move the index with the number as
|
|
||||||
// well.
|
|
||||||
for i := range g.baseThirteen {
|
|
||||||
quicksort(g.baseThirteen[i], g.indexOfHand[i], i)
|
|
||||||
quicksort(jo.baseThirteen[i], jo.indexOfHand[i], i)
|
|
||||||
}
|
|
||||||
|
|
||||||
curRank := 1
|
|
||||||
rank := 0
|
|
||||||
// Iter every array
|
|
||||||
for i := range g.typeOfHand {
|
|
||||||
for j := range g.typeOfHand[i] {
|
|
||||||
index := g.indexOfHand[i][j]
|
|
||||||
rank += curRank * bet[index]
|
|
||||||
curRank++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fmt.Printf("Rank: %d\n", rank)
|
|
||||||
|
|
||||||
curRank = 1
|
|
||||||
rank = 0
|
|
||||||
// Iter every array
|
|
||||||
for i := range jo.typeOfHand {
|
|
||||||
for j := range jo.typeOfHand[i] {
|
|
||||||
index := jo.indexOfHand[i][j]
|
|
||||||
rank += curRank * bet[index]
|
|
||||||
curRank++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fmt.Printf("Rank: %d\n", rank)
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1 +0,0 @@
|
|||||||
../inputs
|
|
||||||
@ -1,233 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"time"
|
|
||||||
"regexp"
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
const LEFT = 'L'
|
|
||||||
|
|
||||||
type Nodes struct {
|
|
||||||
mu sync.Mutex
|
|
||||||
commands []int32
|
|
||||||
singleN []int32
|
|
||||||
leftN []int32
|
|
||||||
rightN []int32
|
|
||||||
index int
|
|
||||||
steps uint64
|
|
||||||
allSteps []int
|
|
||||||
}
|
|
||||||
|
|
||||||
func check(e error) {
|
|
||||||
if e != nil {
|
|
||||||
panic(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func PrintAndWait(x ...any) {
|
|
||||||
fmt.Print(x...)
|
|
||||||
fmt.Scanln()
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://siongui.github.io/2017/06/03/go-find-lcm-by-gcd/
|
|
||||||
// greatest common divisor (GCD) via Euclidean algorithm
|
|
||||||
func GCD(a, b int) int {
|
|
||||||
for b != 0 {
|
|
||||||
t := b
|
|
||||||
b = a % b
|
|
||||||
a = t
|
|
||||||
}
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
|
|
||||||
// find Least Common Multiple (LCM) via GCD
|
|
||||||
func LCM(a, b int, integers ...int) int {
|
|
||||||
result := a * b / GCD(a, b)
|
|
||||||
|
|
||||||
for i := 0; i < len(integers); i++ {
|
|
||||||
result = LCM(result, integers[i])
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Nodes) toByteSingle(s string) {
|
|
||||||
// I've just received something like AAA
|
|
||||||
var temp int32
|
|
||||||
for i := len(s) - 1; i >= 0; i-- {
|
|
||||||
a := int32(s[i])
|
|
||||||
temp += a << ((len(s) - 1 - i) * 8)
|
|
||||||
}
|
|
||||||
n.singleN = append(n.singleN, temp)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Nodes) toByteDuet(s, r string) {
|
|
||||||
// I've just received something like AAA BBB
|
|
||||||
var tempL, tempR int32
|
|
||||||
for i := len(s) - 1; i >= 0; i-- {
|
|
||||||
tempL += int32(s[i]) << ((len(s) - 1 - i) * 8)
|
|
||||||
tempR += int32(r[i]) << ((len(s) - 1 - i) * 8)
|
|
||||||
}
|
|
||||||
n.leftN = append(n.leftN, tempL)
|
|
||||||
n.rightN = append(n.rightN, tempR)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Nodes) findNext(myN int32) int {
|
|
||||||
//var wg sync.WaitGroup
|
|
||||||
ind := 0
|
|
||||||
for i := 0; i < len(n.singleN); i++ {
|
|
||||||
if myN^n.singleN[i] == 0 {
|
|
||||||
n.mu.Lock()
|
|
||||||
n.index = i
|
|
||||||
n.mu.Unlock()
|
|
||||||
ind = i
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ind
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Nodes) findAll(ind int, sp []int, wg *sync.WaitGroup) {
|
|
||||||
index := 0
|
|
||||||
// We only go from the start
|
|
||||||
matching := n.rightN[sp[ind]]
|
|
||||||
if n.commands[0]^LEFT == 0 {
|
|
||||||
matching = n.leftN[sp[ind]]
|
|
||||||
}
|
|
||||||
index = n.findNext(matching)
|
|
||||||
n.allSteps[ind]++
|
|
||||||
i := 0
|
|
||||||
for {
|
|
||||||
// Every step is in a single direction. For every step, we may need to
|
|
||||||
// scan len(n.singleN) elements.
|
|
||||||
// Circular loop
|
|
||||||
index = n.findNext(matching)
|
|
||||||
// Increment i after finding the match
|
|
||||||
i++
|
|
||||||
i = i % len(n.commands)
|
|
||||||
// By default, we will assume we are on the right
|
|
||||||
matching = n.rightN[index]
|
|
||||||
//PrintAndWait()
|
|
||||||
// If we are not, we are in the left
|
|
||||||
if n.commands[i]^LEFT == 0 {
|
|
||||||
matching = n.leftN[index]
|
|
||||||
}
|
|
||||||
n.allSteps[ind]++
|
|
||||||
// If we find XXZ, end
|
|
||||||
temp := matching & 255
|
|
||||||
if temp ^ 'Z' == 0 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//fmt.Printf("I started from %d, matched at %d, taking %d steps.\n", sp[ind], index, n.allSteps[ind] )
|
|
||||||
wg.Done()
|
|
||||||
}
|
|
||||||
|
|
||||||
func timer(name string) func() {
|
|
||||||
start := time.Now()
|
|
||||||
return func() {
|
|
||||||
fmt.Printf("%s took %v\n", name, time.Since(start))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
defer timer ("main")()
|
|
||||||
file, err := os.Open("./inputs/day08_input")
|
|
||||||
check(err)
|
|
||||||
defer file.Close()
|
|
||||||
// Struct with my node
|
|
||||||
n := Nodes{}
|
|
||||||
// Prepare the regex
|
|
||||||
repath := regexp.MustCompile("([A-Z]{3})")
|
|
||||||
// Build the END
|
|
||||||
var END = 'Z'
|
|
||||||
END += ('Z' << 8)
|
|
||||||
END += ('Z' << 16)
|
|
||||||
|
|
||||||
scanner := bufio.NewScanner(file)
|
|
||||||
scanner.Scan()
|
|
||||||
// First line, RL commands
|
|
||||||
strCommands := scanner.Text()
|
|
||||||
// Get every char inside the string just obtained
|
|
||||||
for i := 0; i < len(strCommands); i++ {
|
|
||||||
n.commands = append(n.commands, int32(strCommands[i]))
|
|
||||||
}
|
|
||||||
// One empty line
|
|
||||||
scanner.Scan()
|
|
||||||
// X = (Y, Z)
|
|
||||||
// We regex this one
|
|
||||||
for scanner.Scan() {
|
|
||||||
tempNodes := repath.FindAllString(scanner.Text(), -1)
|
|
||||||
n.toByteSingle(tempNodes[0])
|
|
||||||
n.toByteDuet(tempNodes[1], tempNodes[2])
|
|
||||||
}
|
|
||||||
// We start from 0, we find the match
|
|
||||||
// Let's start an infinite loop
|
|
||||||
// Circular index
|
|
||||||
i := 0
|
|
||||||
// We start from the AAA element
|
|
||||||
START := 'A'
|
|
||||||
START += ('A' << 8)
|
|
||||||
START += ('A' << 16)
|
|
||||||
matching := START
|
|
||||||
// Store where AAA is
|
|
||||||
n.findNext(matching)
|
|
||||||
// By default, we will assume we are on the right
|
|
||||||
// If we are not, we are in the left
|
|
||||||
matching = n.rightN[n.index]
|
|
||||||
if n.commands[i]^LEFT == 0 {
|
|
||||||
matching = n.leftN[n.index]
|
|
||||||
}
|
|
||||||
n.steps++
|
|
||||||
// Infinite loop
|
|
||||||
for {
|
|
||||||
// Every step is in a single direction. For every step, we may need to
|
|
||||||
// scan len(n.singleN) elements.
|
|
||||||
// Circular loop
|
|
||||||
n.findNext(matching)
|
|
||||||
// Increment i after finding the match
|
|
||||||
i++
|
|
||||||
i = i % len(n.commands)
|
|
||||||
// By default, we will assume we are on the right
|
|
||||||
matching = n.rightN[n.index]
|
|
||||||
//PrintAndWait()
|
|
||||||
// If we are not, we are in the left
|
|
||||||
if n.commands[i]^LEFT == 0 {
|
|
||||||
matching = n.leftN[n.index]
|
|
||||||
}
|
|
||||||
n.steps++
|
|
||||||
// If we find ZZZ, end
|
|
||||||
if matching^END == 0 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fmt.Printf("\nSteps: %d\n", n.steps)
|
|
||||||
// Now, for the main event
|
|
||||||
// Let's get ready to rumble
|
|
||||||
startPoints := make([]int, 0)
|
|
||||||
for i := 0; i < len(n.singleN); i++ {
|
|
||||||
// Lets remove all bytes except last 8
|
|
||||||
temp := n.singleN[i] & 255
|
|
||||||
if (temp ^ 'A') == 0 {
|
|
||||||
startPoints = append(startPoints, i)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Now, from the starting points, we should go and match until
|
|
||||||
// we find a path that ends in Z
|
|
||||||
n.allSteps = make([]int, len(startPoints))
|
|
||||||
var wg sync.WaitGroup
|
|
||||||
for i := 0; i < len(startPoints); i++ {
|
|
||||||
wg.Add(1)
|
|
||||||
go n.findAll(i, startPoints, &wg)
|
|
||||||
}
|
|
||||||
wg.Wait()
|
|
||||||
result := 1
|
|
||||||
for i := 0; i < len(n.allSteps); i++ {
|
|
||||||
result = LCM(result, n.allSteps[i])
|
|
||||||
}
|
|
||||||
fmt.Printf("Steps: %d\n", result)
|
|
||||||
}
|
|
||||||
@ -1 +0,0 @@
|
|||||||
../inputs
|
|
||||||
@ -1 +0,0 @@
|
|||||||
../inputs
|
|
||||||
149
day09/oasis.go
149
day09/oasis.go
@ -1,149 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import(
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"bufio"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
"regexp"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Parallel code, global vars
|
|
||||||
type Series struct {
|
|
||||||
mu sync.Mutex
|
|
||||||
numStore [][]int
|
|
||||||
total uint64
|
|
||||||
}
|
|
||||||
|
|
||||||
func check(e error) {
|
|
||||||
if e != nil {
|
|
||||||
panic(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func PrintAndWait(x ...any) {
|
|
||||||
fmt.Print(x...)
|
|
||||||
fmt.Scanln()
|
|
||||||
}
|
|
||||||
// use defer timer("funcname")() when the function you want to
|
|
||||||
// test starts
|
|
||||||
func timer(name string) func() {
|
|
||||||
start := time.Now()
|
|
||||||
return func() {
|
|
||||||
fmt.Printf("%s took %v\n", name, time.Since(start))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func PredictValueBack(numbers []int) []int {
|
|
||||||
// Are we finished? By default, true
|
|
||||||
temp := true
|
|
||||||
for i := 0; i < len(numbers); i++ {
|
|
||||||
if numbers[i] != 0 {
|
|
||||||
temp = false
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Check to end recursion
|
|
||||||
if temp == true {
|
|
||||||
return numbers
|
|
||||||
}
|
|
||||||
|
|
||||||
newNums := make([]int, len(numbers) - 1)
|
|
||||||
for i := 0; i < len(numbers) - 1; i++ {
|
|
||||||
newNums[i] = numbers[i + 1] - numbers[i]
|
|
||||||
}
|
|
||||||
myNums := PredictValueBack(newNums)
|
|
||||||
addValue := newNums[0] - myNums[0]
|
|
||||||
// We need to append at the start
|
|
||||||
newNums = append([]int{addValue}, newNums...)
|
|
||||||
return newNums
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ser *Series) CallPredictBack(numbers []int, wg *sync.WaitGroup) {
|
|
||||||
tempNum := PredictValueBack(numbers)
|
|
||||||
ser.mu.Lock()
|
|
||||||
ser.total += uint64(numbers[0] - tempNum[0])
|
|
||||||
ser.mu.Unlock()
|
|
||||||
wg.Done()
|
|
||||||
}
|
|
||||||
|
|
||||||
func PredictValue(numbers []int) []int {
|
|
||||||
// Are we finished? By default, true
|
|
||||||
temp := true
|
|
||||||
for i := 0; i < len(numbers); i++ {
|
|
||||||
if numbers[i] != 0 {
|
|
||||||
temp = false
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Check to end recursion
|
|
||||||
if temp == true {
|
|
||||||
return numbers
|
|
||||||
}
|
|
||||||
|
|
||||||
newNums := make([]int, len(numbers) - 1)
|
|
||||||
for i := 0; i < len(numbers) - 1; i++ {
|
|
||||||
newNums[i] = numbers[i + 1] - numbers[i]
|
|
||||||
}
|
|
||||||
myNums := PredictValue(newNums)
|
|
||||||
addValue := myNums[len(myNums) - 1]
|
|
||||||
newNums = append(newNums, newNums[len(newNums) - 1] + addValue)
|
|
||||||
return newNums
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ser *Series) CallPredict(numbers []int, wg *sync.WaitGroup) {
|
|
||||||
tempNum := PredictValue(numbers)
|
|
||||||
lt := len(tempNum) - 1
|
|
||||||
ln := len(numbers) - 1
|
|
||||||
ser.mu.Lock()
|
|
||||||
ser.total += uint64(numbers[ln] + tempNum[lt])
|
|
||||||
ser.mu.Unlock()
|
|
||||||
wg.Done()
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
defer timer("main")()
|
|
||||||
file, err := os.Open("./inputs/day09_input")
|
|
||||||
check(err)
|
|
||||||
defer file.Close()
|
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
|
||||||
|
|
||||||
renum := regexp.MustCompile("(\\-[0-9]+|[0-9]+)")
|
|
||||||
|
|
||||||
ser := Series{ total: 0, }
|
|
||||||
|
|
||||||
lines := make([]string, 0)
|
|
||||||
|
|
||||||
scanner := bufio.NewScanner(file)
|
|
||||||
for scanner.Scan() {
|
|
||||||
lines = append(lines, scanner.Text())
|
|
||||||
}
|
|
||||||
ser.numStore = make([][]int, len(lines))
|
|
||||||
for i := 0; i < len(lines); i++ {
|
|
||||||
temp := renum.FindAllString(lines[i], -1)
|
|
||||||
for j := 0; j < len(temp); j++ {
|
|
||||||
num, err := strconv.Atoi(temp[j])
|
|
||||||
check(err)
|
|
||||||
ser.numStore[i] = append(ser.numStore[i], num)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Now I have a 2D array with all the numbers, I can start RECURSING
|
|
||||||
wg.Add(len(ser.numStore))
|
|
||||||
for i := 0; i < len(ser.numStore); i++ {
|
|
||||||
go ser.CallPredict(ser.numStore[i], &wg)
|
|
||||||
}
|
|
||||||
wg.Wait()
|
|
||||||
fmt.Printf("%d\n", ser.total)
|
|
||||||
|
|
||||||
ser.total = 0
|
|
||||||
wg.Add(len(ser.numStore))
|
|
||||||
for i := 0; i < len(ser.numStore); i++ {
|
|
||||||
go ser.CallPredictBack(ser.numStore[i], &wg)
|
|
||||||
}
|
|
||||||
wg.Wait()
|
|
||||||
fmt.Printf("%d\n", ser.total)
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1 +0,0 @@
|
|||||||
../inputs
|
|
||||||
@ -1,48 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Parallel code, global vars
|
|
||||||
type Nodes struct {
|
|
||||||
mu sync.Mutex
|
|
||||||
variable int
|
|
||||||
}
|
|
||||||
|
|
||||||
func check(e error) {
|
|
||||||
if e != nil {
|
|
||||||
panic(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func PrintAndWait(x ...any) {
|
|
||||||
fmt.Print(x...)
|
|
||||||
fmt.Scanln()
|
|
||||||
}
|
|
||||||
|
|
||||||
// use defer timer("funcname")() when the function you want to
|
|
||||||
// test starts
|
|
||||||
func timer(name string) func() {
|
|
||||||
start := time.Now()
|
|
||||||
return func() {
|
|
||||||
fmt.Printf("%s took %v\n", name, time.Since(start))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
file, err := os.Open("./inputs")
|
|
||||||
check(err)
|
|
||||||
defer file.Close()
|
|
||||||
|
|
||||||
lines := make([]string, 0)
|
|
||||||
|
|
||||||
scanner := bufio.NewScanner(file)
|
|
||||||
for scanner.Scan() {
|
|
||||||
lines = append(lines, scanner.Text())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
1000
inputs/day01_input
Normal file
1000
inputs/day01_input
Normal file
File diff suppressed because it is too large
Load Diff
100
inputs/day02_input
Normal file
100
inputs/day02_input
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
Game 1: 4 red, 1 green, 15 blue; 6 green, 2 red, 10 blue; 7 blue, 6 green, 4 red; 12 blue, 10 green, 3 red
|
||||||
|
Game 2: 3 green, 18 blue; 14 green, 4 red, 2 blue; 3 red, 14 green, 15 blue
|
||||||
|
Game 3: 12 green, 2 blue; 9 green; 1 red, 11 blue, 4 green
|
||||||
|
Game 4: 4 blue, 8 green, 5 red; 6 red, 7 blue, 9 green; 2 green, 2 red, 2 blue; 2 green, 6 blue, 9 red; 10 red, 9 green
|
||||||
|
Game 5: 12 red, 1 green, 7 blue; 13 red, 16 blue; 16 blue, 10 red; 4 blue; 16 blue, 7 red; 1 blue, 7 red
|
||||||
|
Game 6: 17 blue, 2 red; 5 blue, 6 green, 2 red; 5 green, 5 blue; 5 green, 12 blue, 4 red
|
||||||
|
Game 7: 2 red, 1 blue, 10 green; 8 red, 14 green, 9 blue; 15 red, 1 blue, 6 green; 9 blue, 3 green, 10 red; 7 blue, 13 red, 4 green
|
||||||
|
Game 8: 1 green, 2 blue; 7 red, 2 blue, 1 green; 1 red, 2 green; 4 red, 1 blue; 11 red, 2 green, 2 blue; 1 blue, 2 green, 11 red
|
||||||
|
Game 9: 11 green, 11 blue, 6 red; 2 green, 3 blue, 2 red; 2 red, 11 blue, 14 green; 5 green, 7 red, 7 blue; 7 green, 1 red, 12 blue; 1 red, 8 green, 7 blue
|
||||||
|
Game 10: 2 red, 8 green, 7 blue; 10 red, 5 green, 2 blue; 4 red, 8 green, 16 blue; 10 blue, 3 green, 15 red
|
||||||
|
Game 11: 2 blue, 2 green, 5 red; 1 green, 3 red, 3 blue; 11 green, 1 red, 2 blue
|
||||||
|
Game 12: 8 blue, 11 green, 14 red; 10 green, 13 red, 2 blue; 1 red, 6 green, 4 blue; 13 red, 11 green, 6 blue
|
||||||
|
Game 13: 15 red, 17 green, 1 blue; 12 red, 1 blue, 1 green; 2 red, 1 blue, 14 green
|
||||||
|
Game 14: 6 green, 11 red, 3 blue; 6 green, 2 blue; 2 green, 10 red, 8 blue; 2 red; 1 green, 9 red; 3 blue, 1 green, 3 red
|
||||||
|
Game 15: 11 blue, 11 green, 4 red; 3 green, 10 blue; 2 red, 9 green, 9 blue
|
||||||
|
Game 16: 2 blue, 11 green; 1 red, 1 blue, 11 green; 12 green, 1 blue, 1 red; 3 blue, 14 green, 1 red; 14 green, 4 blue; 2 blue, 12 green
|
||||||
|
Game 17: 1 red, 2 blue, 4 green; 4 blue, 3 green; 1 green, 1 red, 6 blue; 1 red, 7 blue; 2 green
|
||||||
|
Game 18: 3 red, 3 blue, 7 green; 2 blue, 2 red, 2 green; 4 red, 12 green; 5 green, 2 blue, 4 red; 3 red
|
||||||
|
Game 19: 15 red, 7 blue, 10 green; 5 green, 8 red; 9 green, 8 red; 5 red, 10 green
|
||||||
|
Game 20: 15 blue, 6 green, 11 red; 13 red, 9 blue, 1 green; 15 blue, 10 red, 11 green
|
||||||
|
Game 21: 15 red, 4 green; 11 red, 2 blue, 4 green; 5 blue, 2 green, 4 red; 4 red, 5 blue; 6 red, 3 blue, 1 green
|
||||||
|
Game 22: 4 green, 4 red, 13 blue; 3 red, 7 blue, 9 green; 12 blue, 13 green, 5 red
|
||||||
|
Game 23: 20 green, 4 red; 6 blue, 9 red, 7 green; 6 green
|
||||||
|
Game 24: 1 green, 3 blue, 6 red; 1 green, 1 blue, 2 red; 3 blue, 5 red, 1 green
|
||||||
|
Game 25: 2 red, 9 blue, 2 green; 2 green, 1 red, 5 blue; 3 red, 1 green, 3 blue; 8 blue, 2 green, 3 red; 12 blue, 3 red; 1 blue, 2 green, 1 red
|
||||||
|
Game 26: 2 blue, 5 green, 20 red; 2 blue, 6 red, 9 green; 3 red, 2 blue, 5 green
|
||||||
|
Game 27: 17 blue, 2 red, 14 green; 15 green, 16 blue, 2 red; 13 blue, 13 green; 1 red, 7 green, 3 blue; 1 blue, 2 green
|
||||||
|
Game 28: 5 blue, 6 red, 3 green; 7 red, 19 green; 11 blue, 13 green
|
||||||
|
Game 29: 1 blue, 8 red, 7 green; 1 green, 1 red; 8 red, 7 green, 1 blue; 7 green, 2 red; 1 blue, 7 red; 1 blue, 2 red, 5 green
|
||||||
|
Game 30: 3 red, 17 blue; 11 red, 3 blue, 8 green; 7 green, 12 blue, 10 red; 5 blue, 2 green
|
||||||
|
Game 31: 14 blue, 7 green; 12 green, 14 blue, 2 red; 17 blue, 2 red, 8 green; 2 red, 3 blue, 11 green; 9 green, 4 blue; 1 red, 3 green, 1 blue
|
||||||
|
Game 32: 15 red, 1 blue, 10 green; 15 green, 10 red, 1 blue; 2 red, 6 green, 1 blue
|
||||||
|
Game 33: 10 green, 1 red, 16 blue; 11 blue, 14 green, 3 red; 14 green, 13 blue; 17 blue, 2 red, 3 green
|
||||||
|
Game 34: 8 red, 7 blue, 8 green; 3 green, 1 red; 1 red, 1 green, 5 blue; 6 red, 8 green, 2 blue; 7 red, 8 blue, 3 green
|
||||||
|
Game 35: 5 blue, 19 red; 2 blue, 11 red, 1 green; 16 red, 10 blue; 7 green, 3 blue, 6 red; 3 green, 18 red, 5 blue; 8 blue, 5 red
|
||||||
|
Game 36: 9 red, 6 green, 10 blue; 9 red, 15 green, 6 blue; 6 red, 1 blue, 14 green
|
||||||
|
Game 37: 7 green, 8 red, 2 blue; 3 blue, 5 red, 16 green; 1 green, 1 red, 3 blue
|
||||||
|
Game 38: 5 green, 5 red, 3 blue; 10 blue, 19 red, 9 green; 2 red, 3 blue, 11 green
|
||||||
|
Game 39: 15 red, 11 blue, 5 green; 11 green, 2 red, 6 blue; 2 blue, 3 green, 6 red; 15 red, 3 blue, 13 green
|
||||||
|
Game 40: 7 green, 4 red, 1 blue; 6 blue, 6 green, 2 red; 2 blue, 3 red, 1 green; 1 blue, 3 red, 3 green; 2 red, 5 green, 3 blue
|
||||||
|
Game 41: 10 blue, 8 green, 9 red; 7 blue, 9 red, 2 green; 10 blue, 4 red, 5 green
|
||||||
|
Game 42: 8 blue, 13 green, 14 red; 8 blue, 1 green, 11 red; 4 red, 6 green, 3 blue; 14 green, 4 red, 2 blue
|
||||||
|
Game 43: 2 red, 10 green, 19 blue; 5 blue, 4 green, 9 red; 9 green, 9 red, 2 blue
|
||||||
|
Game 44: 6 red, 2 green, 3 blue; 2 blue, 12 red, 6 green; 1 red, 10 blue; 12 red, 6 green, 2 blue; 14 red, 13 green, 3 blue; 10 green, 9 blue, 11 red
|
||||||
|
Game 45: 2 blue, 1 red, 1 green; 1 green, 1 blue; 2 green, 2 blue
|
||||||
|
Game 46: 7 green, 1 red; 1 green, 4 blue, 1 red; 3 blue, 4 green, 1 red; 1 red, 4 green; 1 blue, 12 green, 1 red; 16 green, 1 blue
|
||||||
|
Game 47: 4 blue, 8 green, 3 red; 6 red, 1 green, 3 blue; 16 green, 4 blue, 1 red; 4 blue, 8 red
|
||||||
|
Game 48: 1 blue, 9 red, 8 green; 8 green, 2 blue, 6 red; 2 green; 4 blue, 5 red; 1 blue, 9 red, 9 green; 1 red, 1 blue, 3 green
|
||||||
|
Game 49: 3 green, 2 blue; 7 blue, 4 red; 20 green, 5 red, 13 blue; 20 green, 1 red, 6 blue
|
||||||
|
Game 50: 3 red, 3 green; 3 green, 3 red; 2 blue, 10 red; 3 blue, 5 green; 14 red, 2 green, 2 blue; 7 red, 2 green
|
||||||
|
Game 51: 3 green, 3 blue, 2 red; 4 green, 16 red, 3 blue; 1 blue, 3 red; 9 red, 1 blue, 4 green
|
||||||
|
Game 52: 6 red, 18 green, 7 blue; 2 blue, 1 red, 5 green; 8 blue, 6 red, 1 green; 1 red, 1 blue; 6 red, 3 green, 10 blue
|
||||||
|
Game 53: 1 blue, 10 red, 3 green; 13 red, 2 green, 1 blue; 1 green, 2 red
|
||||||
|
Game 54: 4 blue, 6 green, 2 red; 5 blue, 6 red, 2 green; 6 blue, 4 green, 8 red; 13 red, 10 blue, 1 green; 5 red, 5 green, 9 blue
|
||||||
|
Game 55: 4 green, 18 red, 4 blue; 9 blue, 7 green, 16 red; 5 red, 6 blue, 14 green; 13 green, 11 red, 9 blue; 6 blue, 13 green, 1 red; 10 blue, 12 red, 14 green
|
||||||
|
Game 56: 8 green, 5 blue, 10 red; 10 green, 7 red, 12 blue; 11 red, 12 blue, 1 green; 4 blue, 6 red, 10 green; 17 blue, 8 green, 2 red
|
||||||
|
Game 57: 1 green, 2 red; 2 green, 5 red, 1 blue; 13 red, 3 green, 4 blue; 3 blue, 13 red, 9 green
|
||||||
|
Game 58: 1 red, 7 blue, 4 green; 2 green, 1 blue, 1 red; 1 green, 11 blue; 12 blue; 1 blue, 5 green, 1 red; 3 green, 11 blue, 1 red
|
||||||
|
Game 59: 5 green, 3 blue, 17 red; 2 red, 9 green; 1 blue, 4 green
|
||||||
|
Game 60: 5 red, 5 green, 1 blue; 2 red, 2 blue, 6 green; 2 red, 3 blue, 3 green
|
||||||
|
Game 61: 2 green, 3 blue, 4 red; 17 green, 1 blue; 1 green, 6 red, 4 blue; 3 blue, 9 green, 3 red; 18 green, 7 red, 2 blue
|
||||||
|
Game 62: 5 red; 3 blue, 9 green; 3 red, 13 blue, 10 green; 14 green, 1 red, 2 blue; 7 blue, 13 green
|
||||||
|
Game 63: 12 blue, 5 green; 5 green, 1 red, 1 blue; 4 red, 7 green, 9 blue; 8 blue, 2 green, 7 red
|
||||||
|
Game 64: 3 blue, 11 green; 5 blue, 2 red, 5 green; 17 green, 5 blue, 1 red; 4 red, 3 blue, 4 green
|
||||||
|
Game 65: 2 red, 1 blue, 2 green; 7 green, 2 red, 1 blue; 2 blue, 7 green, 1 red; 3 blue, 8 green, 3 red
|
||||||
|
Game 66: 4 red, 12 blue, 1 green; 20 blue, 3 green, 2 red; 11 blue, 1 green
|
||||||
|
Game 67: 12 blue, 10 red, 13 green; 19 green, 4 red, 7 blue; 12 red, 9 blue, 13 green
|
||||||
|
Game 68: 2 blue, 17 green; 12 green, 2 red; 5 red, 2 green, 4 blue; 4 blue
|
||||||
|
Game 69: 17 blue, 3 red, 1 green; 4 green, 8 blue, 8 red; 4 green, 7 red, 1 blue; 8 red, 1 green, 11 blue; 13 blue, 10 red, 9 green; 14 blue, 5 green, 6 red
|
||||||
|
Game 70: 1 red, 2 blue, 4 green; 13 blue, 3 red, 2 green; 6 green, 8 blue
|
||||||
|
Game 71: 5 red, 7 green, 1 blue; 11 green, 4 red, 1 blue; 1 red, 12 green, 10 blue; 1 red, 7 blue, 12 green
|
||||||
|
Game 72: 9 blue, 4 green, 1 red; 6 green, 4 blue; 8 green, 5 blue, 1 red
|
||||||
|
Game 73: 1 blue, 10 green, 14 red; 4 green; 2 blue, 9 red, 4 green; 2 blue, 13 green; 13 green, 13 red; 7 red, 5 green, 2 blue
|
||||||
|
Game 74: 3 red, 1 blue, 3 green; 4 green, 1 blue, 1 red; 2 blue, 10 green, 1 red; 1 blue, 3 red, 1 green
|
||||||
|
Game 75: 1 red, 1 blue, 1 green; 2 red, 1 green, 4 blue; 2 red, 4 blue; 1 blue, 1 red
|
||||||
|
Game 76: 4 green, 2 blue, 6 red; 7 green, 1 red; 8 green, 4 red
|
||||||
|
Game 77: 8 green, 7 blue, 5 red; 6 red, 14 green, 7 blue; 8 green, 7 blue; 1 red, 8 green, 8 blue
|
||||||
|
Game 78: 6 red, 3 blue, 3 green; 7 blue, 10 red; 5 green, 10 blue, 1 red; 3 green, 11 blue, 4 red; 14 red, 9 blue, 2 green; 16 red, 2 green, 12 blue
|
||||||
|
Game 79: 1 green; 5 green; 11 green, 3 blue, 2 red; 3 blue
|
||||||
|
Game 80: 2 green, 2 red; 1 blue, 1 green, 1 red; 1 blue, 1 green, 2 red; 2 red; 5 green
|
||||||
|
Game 81: 10 blue, 2 red, 9 green; 4 red, 12 blue, 5 green; 7 green, 4 blue, 6 red; 1 red, 13 green, 14 blue; 13 green, 11 blue
|
||||||
|
Game 82: 4 blue, 2 green; 7 blue, 3 green, 5 red; 1 red, 4 blue, 3 green; 5 blue, 1 red, 6 green; 6 green, 4 red; 11 blue, 3 red, 5 green
|
||||||
|
Game 83: 12 green; 5 red, 8 green; 11 red, 14 green, 1 blue; 9 green, 4 red
|
||||||
|
Game 84: 5 blue, 1 red; 16 blue, 5 green; 1 red, 9 blue, 3 green; 11 blue; 1 green, 2 blue; 1 red, 7 blue, 4 green
|
||||||
|
Game 85: 17 red, 5 blue; 18 blue, 2 red, 2 green; 18 blue, 2 green, 8 red
|
||||||
|
Game 86: 4 red, 1 blue, 11 green; 6 blue, 7 green, 1 red; 3 green, 4 blue; 2 red, 7 blue, 2 green
|
||||||
|
Game 87: 4 red, 5 blue; 1 green, 15 red, 1 blue; 11 blue, 12 red
|
||||||
|
Game 88: 11 green, 3 red, 1 blue; 6 green, 1 blue, 1 red; 1 blue, 3 green; 2 blue, 4 green, 2 red
|
||||||
|
Game 89: 2 green; 1 red, 2 green, 3 blue; 4 blue, 1 red, 10 green; 4 blue, 5 green; 6 blue, 1 red, 10 green
|
||||||
|
Game 90: 15 red, 7 green, 17 blue; 7 blue, 1 red; 7 green, 6 red, 3 blue
|
||||||
|
Game 91: 2 blue, 17 red, 6 green; 1 green, 1 blue, 6 red; 6 red, 4 blue; 10 green, 14 red, 1 blue; 7 blue, 10 green, 10 red; 16 red, 11 green, 9 blue
|
||||||
|
Game 92: 1 green, 8 blue, 4 red; 4 green, 4 red, 4 blue; 1 green, 7 red, 4 blue
|
||||||
|
Game 93: 11 blue, 12 red, 1 green; 9 blue, 2 green, 5 red; 7 red, 5 blue, 2 green
|
||||||
|
Game 94: 7 blue, 10 green; 9 green, 9 blue, 2 red; 1 red, 5 green, 4 blue
|
||||||
|
Game 95: 1 green, 1 blue, 2 red; 6 red; 1 blue; 1 green, 1 blue, 6 red
|
||||||
|
Game 96: 1 blue, 1 red, 2 green; 4 red, 13 green, 1 blue; 1 blue, 13 green, 5 red; 7 green, 4 red
|
||||||
|
Game 97: 10 blue, 5 red, 5 green; 4 red, 8 green, 2 blue; 5 red, 2 green, 15 blue; 2 red, 1 green, 4 blue; 2 red, 14 blue; 14 blue, 4 green
|
||||||
|
Game 98: 11 red, 8 green, 9 blue; 3 blue, 1 green, 14 red; 10 blue, 2 red, 4 green; 7 blue, 11 red, 3 green; 5 red, 12 blue, 4 green; 7 green, 7 blue, 8 red
|
||||||
|
Game 99: 3 green, 2 blue, 1 red; 15 red, 8 blue, 7 green; 18 red, 12 blue, 2 green
|
||||||
|
Game 100: 11 red, 1 blue, 2 green; 3 red, 3 green; 1 blue, 8 red, 4 green; 5 green, 5 blue, 1 red; 2 green, 1 red, 6 blue; 2 green, 8 red, 1 blue
|
||||||
42
template.go
42
template.go
@ -1,42 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import()
|
|
||||||
|
|
||||||
// Parallel code, global vars
|
|
||||||
type Nodes struct {
|
|
||||||
mu sync.Mutex
|
|
||||||
variable type
|
|
||||||
}
|
|
||||||
|
|
||||||
func check(e error) {
|
|
||||||
if e != nil {
|
|
||||||
panic(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func PrintAndWait(x ...any) {
|
|
||||||
fmt.Print(x...)
|
|
||||||
fmt.Scanln()
|
|
||||||
}
|
|
||||||
// use defer timer("funcname")() when the function you want to
|
|
||||||
// test starts
|
|
||||||
func timer(name string) func() {
|
|
||||||
start := time.Now()
|
|
||||||
return func() {
|
|
||||||
fmt.Printf("%s took %v\n", name, time.Since(start))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
file, err := os.Open("./inputs")
|
|
||||||
check(err)
|
|
||||||
defer file.Close()
|
|
||||||
|
|
||||||
lines := make([]string, 0)
|
|
||||||
|
|
||||||
scanner := bufio.NewScanner(file)
|
|
||||||
for scanner.Scan() {
|
|
||||||
lines = append(lines, scanner.Text())
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user