Big update: Adding all advent of codes to same repo
This commit is contained in:
14
AdventOfCode2015/README.md
Normal file
14
AdventOfCode2015/README.md
Normal file
@@ -0,0 +1,14 @@
|
||||
# Advent Of Code 2015
|
||||
|
||||
I started doing AoC puzzles in 2020. I have a few more days to finish in 2020, but I wanted to start on 2015 as a way to learn more about Golang.
|
||||
A language which I want to properly learn, and this is a brilliant way of doing just that.
|
||||
|
||||
## Day 6
|
||||
Brute forced solution, it would be good to get a real solution which takes less than a few milliseconds.
|
||||
|
||||
## Day 7
|
||||
Partial solution, misread the instructions, need to rethink it entirely. I actually wrote an emulator for the second set of example instructions
|
||||
|
||||
## Day 8
|
||||
Just started it, not finished as I have to do something else right now.
|
||||
- Finished it, solution takes less than 1ms to complete. Could have finished it much quicker if I didn't forget to add regular characters onto the end result.
|
||||
39
AdventOfCode2015/day1/day1.go
Normal file
39
AdventOfCode2015/day1/day1.go
Normal file
@@ -0,0 +1,39 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
fmt.Println("Day 1")
|
||||
start := time.Now()
|
||||
|
||||
dat, err := ioutil.ReadFile("day1.txt")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
var floor int64 = 0
|
||||
basement := -1
|
||||
|
||||
for i, value := range dat {
|
||||
|
||||
if basement == -1 && floor == -1 {
|
||||
basement = i
|
||||
}
|
||||
|
||||
if value == 40 {
|
||||
floor++
|
||||
} else if value == 41 {
|
||||
floor--
|
||||
}
|
||||
}
|
||||
|
||||
elapsed := time.Since(start)
|
||||
fmt.Printf("Part 1: %v %v \n", floor, elapsed)
|
||||
fmt.Printf("Part 2: %v %v", basement, elapsed)
|
||||
|
||||
}
|
||||
49
AdventOfCode2015/day10/day10.go
Normal file
49
AdventOfCode2015/day10/day10.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
fmt.Println("Day 9")
|
||||
start := time.Now()
|
||||
|
||||
inputString := "1113122113"
|
||||
input := []int64{}
|
||||
|
||||
for _, c := range inputString {
|
||||
stringChar, _ := strconv.Atoi(string(c))
|
||||
input = append(input, int64(stringChar))
|
||||
}
|
||||
|
||||
//Change 40 to 50 for part 2
|
||||
for rounds := 0; rounds < 40; rounds++ {
|
||||
|
||||
lastNum := input[0]
|
||||
var counter int64 = 1
|
||||
|
||||
newNumbers := []int64{}
|
||||
|
||||
for i := 1; i < len(input); i++ {
|
||||
if input[i] != lastNum {
|
||||
newNumbers = append(newNumbers, counter)
|
||||
newNumbers = append(newNumbers, lastNum)
|
||||
counter = 1
|
||||
lastNum = input[i]
|
||||
} else {
|
||||
counter++
|
||||
}
|
||||
}
|
||||
newNumbers = append(newNumbers, counter)
|
||||
newNumbers = append(newNumbers, lastNum)
|
||||
input = newNumbers
|
||||
}
|
||||
|
||||
elapsed := time.Since(start)
|
||||
fmt.Printf("Part 1: %v %v \n", len(input), elapsed)
|
||||
fmt.Printf("Part 2: %v %v \n", len(input), elapsed)
|
||||
|
||||
}
|
||||
64
AdventOfCode2015/day12/day12.go
Normal file
64
AdventOfCode2015/day12/day12.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println("Day 12")
|
||||
start := time.Now()
|
||||
|
||||
dat, err := ioutil.ReadFile("day12.json")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
var result map[string]interface{}
|
||||
json.Unmarshal(dat, &result)
|
||||
fmt.Printf("Input: %v | %T \n", result, result)
|
||||
|
||||
var count float64 = solver(result)
|
||||
|
||||
elapsed := time.Since(start)
|
||||
fmt.Printf("Part 1: %v %v \n", count, elapsed)
|
||||
|
||||
}
|
||||
|
||||
func solver(json map[string]interface{}) float64 {
|
||||
var counter float64
|
||||
for _, value := range json {
|
||||
switch valueType := value.(type) {
|
||||
case bool:
|
||||
case float64:
|
||||
counter += valueType
|
||||
case string:
|
||||
case []interface{}:
|
||||
counter += interfaceArraySolver(valueType)
|
||||
case map[string]interface{}:
|
||||
counter += solver(valueType)
|
||||
}
|
||||
|
||||
}
|
||||
return counter
|
||||
}
|
||||
|
||||
func interfaceArraySolver(json []interface{}) float64 {
|
||||
var counter float64
|
||||
for _, value := range json {
|
||||
switch valueType := value.(type) {
|
||||
case bool:
|
||||
case float64:
|
||||
counter += valueType
|
||||
case string:
|
||||
case []interface{}:
|
||||
counter += interfaceArraySolver(valueType)
|
||||
case map[string]interface{}:
|
||||
counter += solver(valueType)
|
||||
}
|
||||
|
||||
}
|
||||
return counter
|
||||
}
|
||||
55
AdventOfCode2015/day12/day12.js
Normal file
55
AdventOfCode2015/day12/day12.js
Normal file
@@ -0,0 +1,55 @@
|
||||
const fs = require('fs');
|
||||
const obj = JSON.parse(fs.readFileSync('day12.json', 'utf8'));
|
||||
|
||||
console.log("Part 1: " + solver(obj));
|
||||
console.log("Part 2: ", + solverPart2(obj));
|
||||
|
||||
function solver(json) {
|
||||
|
||||
let counter = 0;
|
||||
|
||||
for (let value in json) {
|
||||
if (typeof json[value] == 'number') {
|
||||
counter += json[value]
|
||||
} else if (typeof json[value] == 'boolean') {
|
||||
|
||||
} else if (typeof json[value] == 'string') {
|
||||
|
||||
} else if (typeof json[value] == 'object') {
|
||||
counter += solver(json[value]);
|
||||
}
|
||||
}
|
||||
|
||||
return counter;
|
||||
|
||||
}
|
||||
|
||||
function solverPart2(json) {
|
||||
let counter = 0;
|
||||
let redFound = false;
|
||||
let toSolver = [];
|
||||
|
||||
for (let value in json) {
|
||||
if (typeof json[value] == 'number') {
|
||||
counter += json[value]
|
||||
} else if (typeof json[value] == 'boolean') {
|
||||
|
||||
} else if (typeof json[value] == 'string') {
|
||||
if (json[value] == 'red' && !Array.isArray(json)) {
|
||||
redFound = true;
|
||||
break;
|
||||
}
|
||||
} else if (typeof json[value] == 'object') {
|
||||
toSolver.push(json[value]);
|
||||
}
|
||||
}
|
||||
|
||||
if (redFound) {
|
||||
return 0;
|
||||
} else {
|
||||
for (let e of toSolver) {
|
||||
counter += solverPart2(e);
|
||||
}
|
||||
return counter;
|
||||
}
|
||||
}
|
||||
143
AdventOfCode2015/day13/day13.go
Normal file
143
AdventOfCode2015/day13/day13.go
Normal file
@@ -0,0 +1,143 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Combination struct {
|
||||
subject string
|
||||
nextTo string
|
||||
}
|
||||
|
||||
type Average struct {
|
||||
person1 string
|
||||
person2 string
|
||||
average int
|
||||
}
|
||||
|
||||
func main() {
|
||||
fmt.Println("Day 13")
|
||||
start := time.Now()
|
||||
|
||||
dat, err := ioutil.ReadFile("day13.txt")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
lines := bytes.Split(dat, []byte("\n"))
|
||||
combinationMap := make(map[Combination]int)
|
||||
people := make([]string, 0)
|
||||
|
||||
for _, line := range lines {
|
||||
stringLine := string(line)
|
||||
stringLine = stringLine[:len(stringLine)-1]
|
||||
lineWordArray := strings.Split(string(stringLine), " ")
|
||||
gained, _ := strconv.Atoi(lineWordArray[3])
|
||||
|
||||
if !contains(people, lineWordArray[0]) {
|
||||
people = append(people, lineWordArray[0])
|
||||
}
|
||||
|
||||
if lineWordArray[2] == "lose" {
|
||||
gained = -gained
|
||||
}
|
||||
combinationMap[Combination{subject: lineWordArray[0], nextTo: lineWordArray[10]}] = gained
|
||||
}
|
||||
|
||||
averageCombinations := make([]Average, 0)
|
||||
for _, person := range people {
|
||||
|
||||
for i := 0; i < len(people); i++ {
|
||||
nextPerson := people[i]
|
||||
if nextPerson != person {
|
||||
average := combinationMap[Combination{subject: person, nextTo: nextPerson}] + combinationMap[Combination{subject: nextPerson, nextTo: person}]
|
||||
averageCombinations = append(averageCombinations, Average{person1: person, person2: nextPerson, average: average})
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
startingPerson := people[0]
|
||||
remaining := make([]string, 0)
|
||||
for _, value := range people {
|
||||
if value != startingPerson {
|
||||
remaining = append(remaining, value)
|
||||
}
|
||||
}
|
||||
|
||||
part1 := travellingSalesMan(averageCombinations, startingPerson, startingPerson, remaining)
|
||||
|
||||
elapsed := time.Since(start)
|
||||
fmt.Printf("Part 1: %v %v \n", part1, elapsed)
|
||||
|
||||
start = time.Now()
|
||||
|
||||
for _, person := range people {
|
||||
averageCombinations = append(averageCombinations, Average{person1: "me", person2: person, average: 0})
|
||||
averageCombinations = append(averageCombinations, Average{person1: person, person2: "me", average: 0})
|
||||
}
|
||||
|
||||
people = append(people, "me")
|
||||
startingPerson = people[0]
|
||||
remaining = make([]string, 0)
|
||||
for _, value := range people {
|
||||
if value != startingPerson {
|
||||
remaining = append(remaining, value)
|
||||
}
|
||||
}
|
||||
|
||||
part2 := travellingSalesMan(averageCombinations, startingPerson, startingPerson, remaining)
|
||||
elapsed = time.Since(start)
|
||||
fmt.Printf("Part 2: %v %v \n", part2, elapsed)
|
||||
|
||||
}
|
||||
|
||||
func travellingSalesMan(averages []Average, startingPerson string, currentPerson string, remainingPeople []string) int {
|
||||
|
||||
//*Needs to return to the beginning
|
||||
if len(remainingPeople) == 0 {
|
||||
return getAverage(averages, startingPerson, currentPerson)
|
||||
} else {
|
||||
|
||||
distances := make([]int, 0)
|
||||
for _, person := range remainingPeople {
|
||||
newRemaining := make([]string, 0)
|
||||
for _, p := range remainingPeople {
|
||||
if p != person {
|
||||
newRemaining = append(newRemaining, p)
|
||||
}
|
||||
}
|
||||
distances = append(distances, getAverage(averages, currentPerson, person)+travellingSalesMan(averages, startingPerson, person, newRemaining))
|
||||
}
|
||||
max := 0
|
||||
for _, value := range distances {
|
||||
if value > max {
|
||||
max = value
|
||||
}
|
||||
}
|
||||
return max
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func contains(array []string, person string) bool {
|
||||
for _, v := range array {
|
||||
if v == person {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func getAverage(array []Average, person1 string, person2 string) int {
|
||||
for _, p := range array {
|
||||
if p.person1 == person1 && p.person2 == person2 {
|
||||
return p.average
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
89
AdventOfCode2015/day14/day14.go
Normal file
89
AdventOfCode2015/day14/day14.go
Normal file
@@ -0,0 +1,89 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println("Day 13")
|
||||
start := time.Now()
|
||||
|
||||
dat, err := ioutil.ReadFile("day14.txt")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
lines := bytes.Split(dat, []byte("\n"))
|
||||
|
||||
part1 := 0
|
||||
total := 2503
|
||||
for _, line := range lines {
|
||||
stringLine := string(line)
|
||||
splitLine := strings.Split(stringLine, " ")
|
||||
|
||||
v, _ := strconv.Atoi(splitLine[3])
|
||||
s, _ := strconv.Atoi(splitLine[6])
|
||||
r, _ := strconv.Atoi(splitLine[13])
|
||||
|
||||
currentDistance := (total / (s + r)) * v * s
|
||||
remaining := total % (s + r)
|
||||
if remaining >= s {
|
||||
currentDistance += v * s
|
||||
} else {
|
||||
currentDistance += v * remaining
|
||||
}
|
||||
if currentDistance > part1 {
|
||||
part1 = currentDistance
|
||||
}
|
||||
}
|
||||
|
||||
elapsed := time.Since(start)
|
||||
fmt.Printf("Part 1: %v %v \n", part1, elapsed)
|
||||
|
||||
start = time.Now()
|
||||
|
||||
horses := make(map[int]int)
|
||||
for i := 1; i <= total; i++ {
|
||||
|
||||
longest := 0
|
||||
fastestHorse := 0
|
||||
for index, line := range lines {
|
||||
stringLine := string(line)
|
||||
splitLine := strings.Split(stringLine, " ")
|
||||
|
||||
v, _ := strconv.Atoi(splitLine[3])
|
||||
s, _ := strconv.Atoi(splitLine[6])
|
||||
r, _ := strconv.Atoi(splitLine[13])
|
||||
|
||||
currentDistance := (i / (s + r)) * v * s
|
||||
remaining := i % (s + r)
|
||||
if remaining >= s {
|
||||
currentDistance += v * s
|
||||
} else {
|
||||
currentDistance += v * remaining
|
||||
}
|
||||
if currentDistance > longest {
|
||||
longest = currentDistance
|
||||
fastestHorse = index
|
||||
}
|
||||
}
|
||||
|
||||
horses[fastestHorse] = horses[fastestHorse] + 1
|
||||
|
||||
}
|
||||
|
||||
fastest := 0
|
||||
for _, value := range horses {
|
||||
if value > fastest {
|
||||
fastest = value
|
||||
}
|
||||
}
|
||||
|
||||
elapsed = time.Since(start)
|
||||
fmt.Printf("Part 2: %v %v \n", fastest, elapsed)
|
||||
|
||||
}
|
||||
93
AdventOfCode2015/day15/day15.go
Normal file
93
AdventOfCode2015/day15/day15.go
Normal file
@@ -0,0 +1,93 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
fmt.Println("Day 15")
|
||||
dat, err := ioutil.ReadFile("day15.txt")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
lines := bytes.Split(dat, []byte("\n"))
|
||||
ingredients := make([][]int, 4)
|
||||
for i := range ingredients {
|
||||
ingredients[i] = make([]int, 5)
|
||||
}
|
||||
|
||||
for index, line := range lines {
|
||||
|
||||
stringLine := string(line)
|
||||
splitString := strings.Split(stringLine, " ")
|
||||
ingredients[index][0], _ = strconv.Atoi(strings.TrimRight(splitString[2], ","))
|
||||
ingredients[index][1], _ = strconv.Atoi(strings.TrimRight(splitString[4], ","))
|
||||
ingredients[index][2], _ = strconv.Atoi(strings.TrimRight(splitString[6], ","))
|
||||
ingredients[index][3], _ = strconv.Atoi(strings.TrimRight(splitString[8], ","))
|
||||
ingredients[index][4], _ = strconv.Atoi(splitString[10])
|
||||
|
||||
}
|
||||
|
||||
best := 0
|
||||
part2 := 0
|
||||
for a := 0; a <= 100; a++ {
|
||||
for b := 0; b <= 100-a; b++ {
|
||||
for c := 0; c <= 100-a-b; c++ {
|
||||
for d := 0; d <= 100-a-b-c; d++ {
|
||||
|
||||
calculation := calc_cookie(ingredients, a, b, c, d)
|
||||
totalCalories := a*ingredients[0][4] + b*ingredients[1][4] + c*ingredients[2][4] + d*ingredients[3][4]
|
||||
|
||||
if calculation > best {
|
||||
best = calculation
|
||||
}
|
||||
|
||||
if totalCalories == 500 && calculation > part2 {
|
||||
part2 = calculation
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println(best)
|
||||
fmt.Println(part2)
|
||||
|
||||
}
|
||||
|
||||
func calc_cookie(ingredients [][]int, sprinkles int, peanut int, frosting int, sugar int) int {
|
||||
|
||||
capacity := sprinkles*ingredients[0][0] +
|
||||
peanut*ingredients[1][0] +
|
||||
frosting*ingredients[2][0] +
|
||||
sugar*ingredients[3][0]
|
||||
|
||||
durability := sprinkles*ingredients[0][1] +
|
||||
peanut*ingredients[1][1] +
|
||||
frosting*ingredients[2][1] +
|
||||
sugar*ingredients[3][1]
|
||||
|
||||
flavor := sprinkles*ingredients[0][2] +
|
||||
peanut*ingredients[1][2] +
|
||||
frosting*ingredients[2][2] +
|
||||
sugar*ingredients[3][2]
|
||||
|
||||
texture := sprinkles*ingredients[0][3] +
|
||||
peanut*ingredients[1][3] +
|
||||
frosting*ingredients[2][3] +
|
||||
sugar*ingredients[3][3]
|
||||
|
||||
if capacity <= 0 || durability <= 0 || flavor <= 0 || texture <= 0 {
|
||||
return 0
|
||||
} else {
|
||||
return capacity * durability * flavor * texture
|
||||
}
|
||||
|
||||
}
|
||||
BIN
AdventOfCode2015/day16/Aunt.class
Normal file
BIN
AdventOfCode2015/day16/Aunt.class
Normal file
Binary file not shown.
BIN
AdventOfCode2015/day16/Main.class
Normal file
BIN
AdventOfCode2015/day16/Main.class
Normal file
Binary file not shown.
118
AdventOfCode2015/day16/Main.java
Normal file
118
AdventOfCode2015/day16/Main.java
Normal file
@@ -0,0 +1,118 @@
|
||||
import java.util.Scanner;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class Main {
|
||||
|
||||
public static void main(String[] args) throws FileNotFoundException {
|
||||
|
||||
File myFile = new File("day16.txt");
|
||||
Scanner in = new Scanner(myFile);
|
||||
int index = 1;
|
||||
|
||||
while (in.hasNext()) {
|
||||
|
||||
String[] input = in.nextLine().replaceAll("\\s+", "").split(":");
|
||||
|
||||
Map<String, Integer> currentAunt = new HashMap<>();
|
||||
|
||||
String[] secondLineSplit = input[2].split(",");
|
||||
String[] thirdLineSplit = input[3].split(",");
|
||||
|
||||
currentAunt.put(input[1], Integer.parseInt(secondLineSplit[0]));
|
||||
currentAunt.put(secondLineSplit[1], Integer.parseInt(thirdLineSplit[0]));
|
||||
currentAunt.put(thirdLineSplit[1], Integer.parseInt(input[4]));
|
||||
|
||||
int counter = 0;
|
||||
int part2counter = 0;
|
||||
|
||||
for (String key : currentAunt.keySet()) {
|
||||
|
||||
switch (key) {
|
||||
case "children":
|
||||
if (currentAunt.get(key) == 3) {
|
||||
counter++;
|
||||
part2counter++;
|
||||
}
|
||||
break;
|
||||
case "cats":
|
||||
if (currentAunt.get(key) == 7) {
|
||||
counter++;
|
||||
}
|
||||
if (currentAunt.get(key) > 7) {
|
||||
part2counter++;
|
||||
}
|
||||
break;
|
||||
case "samoyeds":
|
||||
if (currentAunt.get(key) == 2) {
|
||||
counter++;
|
||||
part2counter++;
|
||||
}
|
||||
break;
|
||||
case "pomeranians":
|
||||
if (currentAunt.get(key) == 3) {
|
||||
counter++;
|
||||
}
|
||||
if (currentAunt.get(key) < 3) {
|
||||
part2counter++;
|
||||
}
|
||||
break;
|
||||
case "akitas":
|
||||
if (currentAunt.get(key) == 0) {
|
||||
counter++;
|
||||
part2counter++;
|
||||
}
|
||||
break;
|
||||
case "vizslas":
|
||||
if (currentAunt.get(key) == 0) {
|
||||
counter++;
|
||||
part2counter++;
|
||||
}
|
||||
break;
|
||||
case "goldfish":
|
||||
if (currentAunt.get(key) == 5) {
|
||||
counter++;
|
||||
}
|
||||
if (currentAunt.get(key) < 5) {
|
||||
part2counter++;
|
||||
}
|
||||
break;
|
||||
case "trees":
|
||||
if (currentAunt.get(key) == 3) {
|
||||
counter++;
|
||||
}
|
||||
if (currentAunt.get(key) > 3) {
|
||||
part2counter++;
|
||||
}
|
||||
break;
|
||||
case "cars":
|
||||
if (currentAunt.get(key) == 2) {
|
||||
counter++;
|
||||
part2counter++;
|
||||
}
|
||||
break;
|
||||
case "perfumes":
|
||||
if (currentAunt.get(key) == 1) {
|
||||
counter++;
|
||||
part2counter++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (counter == 3) {
|
||||
System.out.printf("Part 1: %d \n", index);
|
||||
} else if (part2counter == 3) {
|
||||
System.out.printf("Part 2: %d \n", index);
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
in.close();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
53
AdventOfCode2015/day2/day2.go
Normal file
53
AdventOfCode2015/day2/day2.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
fmt.Println("Day 2")
|
||||
start := time.Now()
|
||||
|
||||
dat, err := ioutil.ReadFile("day2.txt")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
lines := bytes.Split(dat, []byte("\n"))
|
||||
total := 0
|
||||
totalPart2 := 0
|
||||
|
||||
for _, value := range lines {
|
||||
|
||||
splitLine := bytes.Split(value, []byte("x"))
|
||||
l, _ := strconv.Atoi(string(splitLine[0]))
|
||||
w, _ := strconv.Atoi(string(splitLine[1]))
|
||||
h, _ := strconv.Atoi(string(splitLine[2]))
|
||||
|
||||
total += 2*l*w + 2*l*h + 2*w*h + MinOf(l*w, w*h, h*l)
|
||||
totalPart2 += MinOf(l*2+w*2, w*2+h*2, h*2+l*2) + l*w*h
|
||||
|
||||
}
|
||||
|
||||
elapsed := time.Since(start)
|
||||
fmt.Printf("Part 1: %v %v \n", total, elapsed)
|
||||
fmt.Printf("Part 2: %v %v", totalPart2, elapsed)
|
||||
|
||||
}
|
||||
|
||||
func MinOf(vars ...int) int {
|
||||
min := vars[0]
|
||||
|
||||
for _, i := range vars {
|
||||
if min > i {
|
||||
min = i
|
||||
}
|
||||
}
|
||||
|
||||
return min
|
||||
}
|
||||
69
AdventOfCode2015/day3/day3.go
Normal file
69
AdventOfCode2015/day3/day3.go
Normal file
@@ -0,0 +1,69 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Coords struct {
|
||||
x int
|
||||
y int
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
fmt.Println("Day 3")
|
||||
start := time.Now()
|
||||
|
||||
dat, err := ioutil.ReadFile("day3.txt")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
position := Coords{x: 0, y: 0}
|
||||
visited := make(map[Coords]int)
|
||||
visited[position] = 1
|
||||
|
||||
for _, value := range dat {
|
||||
solve(visited, &position, value)
|
||||
}
|
||||
|
||||
elapsed := time.Since(start)
|
||||
fmt.Printf("Part 1: %v %v \n", len(visited), elapsed)
|
||||
|
||||
start = time.Now()
|
||||
position = Coords{x: 0, y: 0}
|
||||
visited = make(map[Coords]int)
|
||||
visited[position] = 1
|
||||
|
||||
for i := 0; i < len(dat); i = i + 2 {
|
||||
solve(visited, &position, dat[i])
|
||||
}
|
||||
|
||||
position.x = 0
|
||||
position.y = 0
|
||||
|
||||
for i := 1; i < len(dat); i = i + 2 {
|
||||
solve(visited, &position, dat[i])
|
||||
}
|
||||
|
||||
fmt.Printf("Part 2: %v %v", len(visited), elapsed)
|
||||
|
||||
}
|
||||
|
||||
func solve(visited map[Coords]int, position *Coords, value byte) {
|
||||
if value == []byte("<")[0] {
|
||||
position.x--
|
||||
visited[*position]++
|
||||
} else if value == []byte(">")[0] {
|
||||
position.x++
|
||||
visited[*position]++
|
||||
} else if value == []byte("^")[0] {
|
||||
position.y++
|
||||
visited[*position]++
|
||||
} else if value == []byte("v")[0] {
|
||||
position.y--
|
||||
visited[*position]++
|
||||
}
|
||||
}
|
||||
53
AdventOfCode2015/day4/day4.go
Normal file
53
AdventOfCode2015/day4/day4.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Coords struct {
|
||||
x int
|
||||
y int
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
fmt.Println("Day 3")
|
||||
start := time.Now()
|
||||
|
||||
dat, err := ioutil.ReadFile("day4.txt")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
input := string(dat)
|
||||
|
||||
part1 := ""
|
||||
var hash [16]byte
|
||||
for i := 1; part1 == ""; i++ {
|
||||
hashString := input + strconv.Itoa(i)
|
||||
hash = md5.Sum([]byte(hashString))
|
||||
if hash[0] == 0x00 && hash[1] == 0x00 && hash[2] <= 0x0f {
|
||||
part1 = hashString
|
||||
}
|
||||
}
|
||||
|
||||
elapsed := time.Since(start)
|
||||
fmt.Printf("Part 1: %v %v \n", part1, elapsed)
|
||||
start = time.Now()
|
||||
|
||||
part2 := ""
|
||||
for i := 1; part2 == ""; i++ {
|
||||
hashString := input + strconv.Itoa(i)
|
||||
hash = md5.Sum([]byte(hashString))
|
||||
if hash[0] == 0x00 && hash[1] == 0x00 && hash[2] == 0x00 {
|
||||
part2 = hashString
|
||||
}
|
||||
}
|
||||
|
||||
elapsed = time.Since(start)
|
||||
fmt.Printf("Part 2: %v %v", part2, elapsed)
|
||||
|
||||
}
|
||||
107
AdventOfCode2015/day5/day5.go
Normal file
107
AdventOfCode2015/day5/day5.go
Normal file
@@ -0,0 +1,107 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
fmt.Println("Day 5")
|
||||
start := time.Now()
|
||||
|
||||
dat, err := ioutil.ReadFile("day5.txt")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
lines := bytes.Split(dat, []byte("\n"))
|
||||
part1 := 0
|
||||
part2 := 0
|
||||
|
||||
for _, value := range lines {
|
||||
|
||||
vowels := 0
|
||||
twiceInARow := false
|
||||
forbiddenPhrases := false
|
||||
|
||||
for i := 0; i < len(value); i++ {
|
||||
current := value[i]
|
||||
if current == []byte("a")[0] || current == []byte("e")[0] || current == []byte("i")[0] || current == []byte("o")[0] || current == []byte("u")[0] {
|
||||
vowels++
|
||||
}
|
||||
|
||||
if i != 0 {
|
||||
if value[i-1] == value[i] {
|
||||
twiceInARow = true
|
||||
}
|
||||
|
||||
last2 := []byte{value[i-1], value[i]}
|
||||
if compare(last2, []byte("ab")) || compare(last2, []byte("cd")) || compare(last2, []byte("pq")) || compare(last2, []byte("xy")) {
|
||||
forbiddenPhrases = true
|
||||
break
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if !forbiddenPhrases {
|
||||
if twiceInARow && vowels >= 3 {
|
||||
part1++
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
elapsed := time.Since(start)
|
||||
fmt.Printf("Part 1: %v %v \n", part1, elapsed)
|
||||
|
||||
start = time.Now()
|
||||
|
||||
for _, value := range lines {
|
||||
|
||||
repeatedPair := false
|
||||
repeatedLetterWithGap := false
|
||||
|
||||
var pairs [][]byte
|
||||
for i := 0; i < len(value)-1; i++ {
|
||||
pairs = append(pairs, value[i:i+2])
|
||||
}
|
||||
|
||||
for i := 0; i < len(pairs)-1; i++ {
|
||||
for j := i + 2; j < len(pairs); j++ {
|
||||
if compare(pairs[i], pairs[j]) {
|
||||
repeatedPair = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for i := 0; i < len(value)-2; i++ {
|
||||
if value[i] == value[i+2] {
|
||||
repeatedLetterWithGap = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if repeatedLetterWithGap && repeatedPair {
|
||||
part2++
|
||||
}
|
||||
}
|
||||
|
||||
elapsed = time.Since(start)
|
||||
fmt.Printf("Part 2: %v %v", part2, elapsed)
|
||||
|
||||
}
|
||||
|
||||
func compare(slice1 []byte, slice2 []byte) bool {
|
||||
for i := 0; i < len(slice1) && i < len(slice2); i++ {
|
||||
if slice1[i] != slice2[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
130
AdventOfCode2015/day6/day6.go
Normal file
130
AdventOfCode2015/day6/day6.go
Normal file
@@ -0,0 +1,130 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Square struct {
|
||||
x int64
|
||||
y int64
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
fmt.Println("Day 6")
|
||||
start := time.Now()
|
||||
|
||||
dat, err := ioutil.ReadFile("day6.txt")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
lines := bytes.Split(dat, []byte("\n"))
|
||||
lights := make(map[Square]bool)
|
||||
lights2 := make(map[Square]int64)
|
||||
|
||||
SwitchTheLights(lights, false, false, 0, 0, 1000, 1000)
|
||||
|
||||
part1 := 0
|
||||
var part2 int64 = 0
|
||||
|
||||
for _, value := range lines {
|
||||
|
||||
words := bytes.Split(value, []byte(" "))
|
||||
if len(words) == 4 {
|
||||
|
||||
start := bytes.Split(words[1], []byte(","))
|
||||
end := bytes.Split(words[3], []byte(","))
|
||||
|
||||
startX, _ := strconv.Atoi(string(start[0]))
|
||||
startY, _ := strconv.Atoi(string(start[1]))
|
||||
endX, _ := strconv.Atoi(string(end[0]))
|
||||
endY, _ := strconv.Atoi(string(end[1]))
|
||||
|
||||
SwitchTheLights(lights, false, true, int64(startX), int64(startY), int64(endX), int64(endY))
|
||||
SwitchTheLights2(lights2, false, true, int64(startX), int64(startY), int64(endX), int64(endY))
|
||||
|
||||
} else {
|
||||
|
||||
start := bytes.Split(words[2], []byte(","))
|
||||
end := bytes.Split(words[4], []byte(","))
|
||||
|
||||
startX, _ := strconv.Atoi(string(start[0]))
|
||||
startY, _ := strconv.Atoi(string(start[1]))
|
||||
endX, _ := strconv.Atoi(string(end[0]))
|
||||
endY, _ := strconv.Atoi(string(end[1]))
|
||||
|
||||
SwitchTheLights(lights, compare(words[1], []byte("on")), false, int64(startX), int64(startY), int64(endX), int64(endY))
|
||||
SwitchTheLights2(lights2, compare(words[1], []byte("on")), false, int64(startX), int64(startY), int64(endX), int64(endY))
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for _, v := range lights {
|
||||
if v {
|
||||
part1++
|
||||
}
|
||||
}
|
||||
|
||||
for _, v := range lights2 {
|
||||
part2 += v
|
||||
}
|
||||
|
||||
elapsed := time.Since(start)
|
||||
fmt.Printf("Part 1: %v %v \n", part1, elapsed)
|
||||
fmt.Printf("Part 2: %v %v \n", part2, elapsed)
|
||||
|
||||
}
|
||||
|
||||
func SwitchTheLights(lights map[Square]bool, state bool, toggle bool, startX int64, startY int64, endX int64, endY int64) {
|
||||
|
||||
for i := startX; i <= endX; i++ {
|
||||
for j := startY; j <= endY; j++ {
|
||||
if toggle {
|
||||
lights[Square{x: i, y: j}] = !lights[Square{x: i, y: j}]
|
||||
} else {
|
||||
lights[Square{x: i, y: j}] = state
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func SwitchTheLights2(lights map[Square]int64, state bool, toggle bool, startX int64, startY int64, endX int64, endY int64) {
|
||||
|
||||
for i := startX; i <= endX; i++ {
|
||||
for j := startY; j <= endY; j++ {
|
||||
|
||||
var brighness int64 = lights[Square{x: i, y: j}]
|
||||
if toggle {
|
||||
lights[Square{x: i, y: j}] = brighness + 2
|
||||
} else {
|
||||
|
||||
if state {
|
||||
lights[Square{x: i, y: j}] = brighness + 1
|
||||
} else {
|
||||
lights[Square{x: i, y: j}] = brighness - 1
|
||||
if lights[Square{x: i, y: j}] < 0 {
|
||||
lights[Square{x: i, y: j}] = 0
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func compare(slice1 []byte, slice2 []byte) bool {
|
||||
for i := 0; i < len(slice1) && i < len(slice2); i++ {
|
||||
if slice1[i] != slice2[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
155
AdventOfCode2015/day7/day7.zig
Normal file
155
AdventOfCode2015/day7/day7.zig
Normal file
@@ -0,0 +1,155 @@
|
||||
const std = @import("std");
|
||||
const utils = @import("./utils.zig");
|
||||
|
||||
const InstructionType = enum { LITERAL, REASSIGN, NOT, AND, HACKY_AND, OR, LSHIFT, RSHIFT };
|
||||
|
||||
const Instruction = struct {
|
||||
type: InstructionType,
|
||||
|
||||
// To be used with LITERAL
|
||||
num: ?u16,
|
||||
|
||||
firstLetter: ?[]const u8,
|
||||
secondLetter: ?[]const u8,
|
||||
};
|
||||
|
||||
fn getOp(op: []const u8) InstructionType {
|
||||
if (std.mem.eql(u8, op, "AND")) {
|
||||
return InstructionType.AND;
|
||||
}
|
||||
if (std.mem.eql(u8, op, "OR")) {
|
||||
return InstructionType.OR;
|
||||
}
|
||||
if (std.mem.eql(u8, op, "LSHIFT")) {
|
||||
return InstructionType.LSHIFT;
|
||||
}
|
||||
if (std.mem.eql(u8, op, "RSHIFT")) {
|
||||
return InstructionType.RSHIFT;
|
||||
}
|
||||
|
||||
unreachable;
|
||||
}
|
||||
|
||||
fn getLetter(map: std.StringHashMap(Instruction), cache: *std.StringHashMap(u16), letter: []const u8) !u16 {
|
||||
if (cache.contains(letter)) {
|
||||
return cache.*.get(letter).?;
|
||||
}
|
||||
|
||||
var op = map.get(letter).?;
|
||||
|
||||
if (op.type == InstructionType.LITERAL) {
|
||||
try cache.*.put(letter, op.num.?);
|
||||
return op.num.?;
|
||||
}
|
||||
|
||||
if (op.type == InstructionType.NOT) {
|
||||
var notRes = ~(try getLetter(map, cache, op.firstLetter.?));
|
||||
try cache.*.put(letter, notRes);
|
||||
return notRes;
|
||||
}
|
||||
|
||||
if (op.type == InstructionType.REASSIGN) {
|
||||
var reassignRes = try getLetter(map, cache, op.firstLetter.?);
|
||||
try cache.*.put(letter, reassignRes);
|
||||
return reassignRes;
|
||||
}
|
||||
|
||||
var first = try getLetter(map, cache, op.firstLetter.?);
|
||||
|
||||
if (op.type == InstructionType.HACKY_AND) {
|
||||
try cache.*.put(letter, op.num.? & first);
|
||||
return op.num.? & first;
|
||||
}
|
||||
|
||||
if (op.type == InstructionType.AND or op.type == InstructionType.OR) {
|
||||
var second = try getLetter(map, cache, op.secondLetter.?);
|
||||
if (op.type == InstructionType.AND) {
|
||||
try cache.*.put(letter, first & second);
|
||||
return first & second;
|
||||
}
|
||||
try cache.*.put(letter, first | second);
|
||||
return first | second;
|
||||
}
|
||||
|
||||
if (op.type == InstructionType.LSHIFT) {
|
||||
var shortNum: u4 = @truncate(op.num.?);
|
||||
try cache.*.put(letter, first << shortNum);
|
||||
return first << shortNum;
|
||||
}
|
||||
var shortNum: u4 = @truncate(op.num.?);
|
||||
try cache.*.put(letter, first >> shortNum);
|
||||
return first >> shortNum;
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
var allocator = std.heap.page_allocator;
|
||||
var lines = try utils.splitLines("input.txt", allocator);
|
||||
defer lines.deinit();
|
||||
|
||||
var wireMap = std.StringHashMap(Instruction).init(allocator);
|
||||
defer wireMap.deinit();
|
||||
|
||||
var resultCache = std.StringHashMap(u16).init(allocator);
|
||||
defer resultCache.deinit();
|
||||
|
||||
for (lines.items) |line| {
|
||||
var instructionAndOutput = std.mem.tokenizeSequence(u8, line, " -> ");
|
||||
|
||||
var op = instructionAndOutput.next().?;
|
||||
var output = instructionAndOutput.next().?;
|
||||
|
||||
var instructionParts = std.mem.tokenizeSequence(u8, op, " ");
|
||||
var first = instructionParts.next().?;
|
||||
|
||||
if (std.mem.eql(u8, first, "NOT")) {
|
||||
var notOp = Instruction{ .type = InstructionType.NOT, .firstLetter = instructionParts.next().?, .num = undefined, .secondLetter = undefined };
|
||||
try wireMap.put(output, notOp);
|
||||
continue;
|
||||
}
|
||||
|
||||
var firstNumber = std.fmt.parseInt(u16, first, 10) catch {
|
||||
// Must be a regular double operation (a AND b)
|
||||
|
||||
if (instructionParts.next()) |rawOperator| {
|
||||
var operator = getOp(rawOperator);
|
||||
var second = instructionParts.next().?;
|
||||
|
||||
var myOp = switch (operator) {
|
||||
InstructionType.AND, InstructionType.OR => Instruction{ .type = operator, .firstLetter = first, .secondLetter = second, .num = undefined },
|
||||
InstructionType.LSHIFT, InstructionType.RSHIFT => Instruction{ .type = operator, .firstLetter = first, .secondLetter = undefined, .num = try std.fmt.parseInt(u4, second, 10) },
|
||||
else => unreachable,
|
||||
};
|
||||
|
||||
try wireMap.put(output, myOp);
|
||||
|
||||
continue;
|
||||
}
|
||||
// x -> y
|
||||
var reassign = Instruction{ .type = InstructionType.REASSIGN, .firstLetter = first, .secondLetter = undefined, .num = undefined };
|
||||
try wireMap.put(output, reassign);
|
||||
continue;
|
||||
};
|
||||
|
||||
// Edge case. and gates can have numbers too (seems to be limited to first argument).
|
||||
if (instructionParts.next()) |_| {
|
||||
// an and operation with a 1 in front.
|
||||
var second = instructionParts.next().?;
|
||||
var hackyAnd = Instruction{ .type = InstructionType.HACKY_AND, .firstLetter = second, .secondLetter = undefined, .num = firstNumber };
|
||||
try wireMap.put(output, hackyAnd);
|
||||
continue;
|
||||
}
|
||||
|
||||
var literalOp = Instruction{ .type = InstructionType.LITERAL, .num = firstNumber, .firstLetter = undefined, .secondLetter = undefined };
|
||||
try wireMap.put(output, literalOp);
|
||||
}
|
||||
|
||||
var part1 = try getLetter(wireMap, &resultCache, "a");
|
||||
std.debug.print("Part 1: {}\n", .{part1});
|
||||
|
||||
var resetResultCache = std.StringHashMap(u16).init(allocator);
|
||||
defer resetResultCache.deinit();
|
||||
try resetResultCache.put("b", part1);
|
||||
|
||||
var part2 = try getLetter(wireMap, &resetResultCache, "a");
|
||||
std.debug.print("Part 2: {}\n", .{part2});
|
||||
}
|
||||
1
AdventOfCode2015/day7/utils.zig
Symbolic link
1
AdventOfCode2015/day7/utils.zig
Symbolic link
@@ -0,0 +1 @@
|
||||
../../zig/utils.zig
|
||||
83
AdventOfCode2015/day8/day8.go
Normal file
83
AdventOfCode2015/day8/day8.go
Normal file
@@ -0,0 +1,83 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Square struct {
|
||||
x int64
|
||||
y int64
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
fmt.Println("Day 8")
|
||||
start := time.Now()
|
||||
|
||||
dat, err := ioutil.ReadFile("day8.txt")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
lines := bytes.Split(dat, []byte("\n"))
|
||||
|
||||
part2 := 0
|
||||
totalCharacters := 0
|
||||
realCharacters := 0
|
||||
|
||||
for _, value := range lines {
|
||||
line := string(value)
|
||||
totalCharacters += len(line)
|
||||
|
||||
newLine := line[1 : len(line)-1]
|
||||
currentReal := 0
|
||||
|
||||
for i := 0; i < len(newLine); i++ {
|
||||
char := string(newLine[i])
|
||||
if char == `\` {
|
||||
nextChar := string(newLine[i+1])
|
||||
if nextChar == "x" {
|
||||
i = i + 2
|
||||
} else if nextChar == `"` || nextChar == `\` {
|
||||
i++
|
||||
currentReal++
|
||||
}
|
||||
} else {
|
||||
currentReal++
|
||||
}
|
||||
}
|
||||
realCharacters += currentReal
|
||||
|
||||
currentPart2 := 0
|
||||
|
||||
for i := 0; i < len(line); i++ {
|
||||
char := string(line[i])
|
||||
if char == `"` || char == `\` {
|
||||
currentPart2 += 2
|
||||
} else {
|
||||
currentPart2++
|
||||
}
|
||||
}
|
||||
//Double quotes around the string
|
||||
currentPart2 += 2
|
||||
part2 += currentPart2
|
||||
|
||||
}
|
||||
|
||||
elapsed := time.Since(start)
|
||||
fmt.Printf("Part 1: %v %v \n", totalCharacters-realCharacters, elapsed)
|
||||
fmt.Printf("Part 2: %v %v \n", part2-totalCharacters, elapsed)
|
||||
|
||||
}
|
||||
|
||||
func compare(slice1 []byte, slice2 []byte) bool {
|
||||
for i := 0; i < len(slice1) && i < len(slice2); i++ {
|
||||
if slice1[i] != slice2[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
Reference in New Issue
Block a user