Add archive from Advent of Code 2017.

This commit is contained in:
Danila Fedorin 2020-12-04 18:01:27 -08:00
commit ad81a01063
37 changed files with 1412 additions and 0 deletions

19
day10_1.rb Normal file
View File

@ -0,0 +1,19 @@
initial_string = [*0..255]
# initial_string = [*0..4]
shifts = File.open('puzzle_10.txt').read.split(',').map(&:to_i)
# shifts = [3, 4, 1, 5]
skip_size = 0
offset = 0
for shift in shifts do
initial_string.rotate! offset
if shift > 0 then
rotated_bit = initial_string[0..shift - 1]
kept_bit = initial_string[shift..initial_string.length-1]
initial_string = rotated_bit.reverse + kept_bit
end
initial_string.rotate! -offset
offset += shift + skip_size
skip_size += 1
end
print initial_string[0] * initial_string[1]

27
day10_2.rb Normal file
View File

@ -0,0 +1,27 @@
initial_string = [*0..255]
suffix = [17, 31, 73, 47, 23]
# shifts = File.open('puzzle_10.txt').read.split(',').map(&:to_i) + suffix
# shifts = [1, 2, 3] + suffix
# shifts = suffix
string = '129,154,49,198,200,133,97,254,41,6,2,1,255,0,191,108' # File.open('puzzle_10.txt').read
shifts = string.split('').map(&:ord)
shifts = shifts + suffix
skip_size = 0
offset = 0
shifts = shifts * 64
for shift in shifts do
initial_string.rotate! offset
if shift > 0 then
rotated_bit = initial_string[0..shift - 1]
kept_bit = initial_string[shift..initial_string.length-1]
initial_string = rotated_bit.reverse + kept_bit
end
initial_string.rotate! -offset
offset += shift + skip_size
skip_size += 1
end
blocks = initial_string.each_slice(16).to_a
hash = blocks.map do |block|
block.inject(0) { |x, y| x^y }.to_s(16)
end
puts hash.join('')

24
day11.kt Normal file
View File

@ -0,0 +1,24 @@
import java.io.File
fun main(args: Array<String>) {
val directions = mapOf("n" to (0 to 1),
"s" to (0 to-1),
"ne" to (1 to 1),
"nw" to (-1 to 1),
"se" to (1 to -1),
"sw" to (-1 to -1))
// val instructionString = File("../puzzle_10.txt").readLines().first()
val instructionString = "sw,sw,sw,nw"
var indexX = 0
var indexY = 0
var maxDistance = 0
instructionString.split(",").forEach {
name: String ->
val (dx, dy) = directions[name]!!
indexX += dx
indexY += dy
maxDistance = Math.max(maxDistance, Math.max(Math.abs(indexX), Math.abs(indexY)))
}
println("${Math.max(Math.abs(indexX), Math.abs(indexY))}")
println("$maxDistance")
}

39
day12.kt Normal file
View File

@ -0,0 +1,39 @@
import java.io.File
fun findPath(current: String, to: String, connections: Map<String, List<String>>, visited: MutableList<String> = mutableListOf()): Boolean {
if(current == to) return true
if(visited.contains(current)) return false
visited.add(current)
return connections[current]!!.any { findPath(it, to, connections, visited) }
}
fun findGroup(current: String, connections: Map<String, List<String>>, visited: MutableList<String> = mutableListOf()): MutableList<String> {
if(visited.contains(current)) return visited
visited.add(current)
for(connection in connections[current]!!) findGroup(connection, connections, visited)
return visited
}
fun main(args: Array<String>) {
val sourceFile = File("../puzzle_12.txt")
// val sourceFile = File("test.txt")
val connectionMaps = mutableMapOf<String, MutableList<String>>()
sourceFile.readLines().forEach {
val programId = it.split(" <-> ")[0]
val programs = it.split(" <-> ")[1].split(", ")
programs
.map { connectionMaps.computeIfAbsent(it) { mutableListOf() } }
.forEach { it.add(programId) }
connectionMaps.computeIfAbsent(programId) { mutableListOf() }.addAll(programs)
}
val total = connectionMaps.keys.sumBy { if(findPath(it, "0", connectionMaps)) 1 else 0 }
val programs = connectionMaps.keys
var groups = 0
while(programs.size > 0) {
programs.removeAll(findGroup(programs.first(), connectionMaps))
groups++
}
println(total)
println(groups)
}

35
day13.kt Normal file
View File

@ -0,0 +1,35 @@
import java.io.File
fun updateScanners(depths: MutableMap<Int, Int>, scannerPos: MutableMap<Int, Int>, scannerDirection: MutableMap<Int, Int>){
depths.forEach { t, u ->
val absent = !scannerPos.contains(t)
val position = scannerPos.computeIfAbsent(t) { -1 }
val direction = scannerDirection.computeIfAbsent(t) { 1 }
val nextPosition = (position + direction)
if(nextPosition == u - 1 || (nextPosition == 0 && !absent)) scannerDirection.put(t, -direction)
scannerPos.put(t, nextPosition)
}
}
fun main(args: Array<String>) {
// val sourceFile = File("../puzzle_13.txt")
val sourceFile = File("test.txt")
val allLines = sourceFile.readLines()
val firstLine = allLines.first()
val depthMap = mutableMapOf<Int, Int>()
allLines.forEach {
depthMap.put(it.split(": ")[0].toInt(), it.split(": ")[1].toInt())
}
val scannerPos = mutableMapOf<Int, Int>()
val scannerDir = mutableMapOf<Int, Int>()
var currentIndex = 0
var cost = 0
val goalIndex = depthMap.keys.sorted().last()
while(currentIndex <= goalIndex) {
updateScanners(depthMap, scannerPos, scannerDir)
if(!depthMap.containsKey(currentIndex)) {}
else if(scannerPos[currentIndex]!! == 0) cost += depthMap[currentIndex]!! * currentIndex
currentIndex++
}
println(cost)
}

33
day13_2.kt Normal file
View File

@ -0,0 +1,33 @@
import java.io.File
import kotlin.math.cos
import kotlin.system.measureTimeMillis
fun main(args: Array<String>){
val file = File("../puzzle_13.txt")
// val file = File("test.txt")
val lines = file.readLines()
val scannerDepths = mutableMapOf<Int, Int>()
lines.forEach {
val pieces = it.split(": ")
scannerDepths.put(pieces[0].toInt(), pieces[1].toInt())
}
var offset = 0
val cost = scannerDepths.map {
if(it.key + offset % ((it.value - 1) * 2) == 0) it.value * it.key else 0
}.fold(0) { a, b -> a + b}
val time = measureTimeMillis {
while(offset < Int.MAX_VALUE){
val cost = scannerDepths.map {
if((it.key + offset) % ((it.value - 1) * 2) == 0) it.value * it.key + 1 else 0
}.fold(0) { a, b -> a + b}
if(cost == 0) {
println(offset)
break
}
offset++
}
}
println(time)
}

15
day13_2_crt.kt Normal file
View File

@ -0,0 +1,15 @@
import java.io.File
fun main(args: Array<String>) {
// val file = File("../puzzle_13.txt")
val file = File("test.txt")
val lines = file.readLines()
val list = lines.map {
val pieces = it.split(": ")
val index = pieces[0].toInt()
val depth = pieces[1].toInt()
val period = (depth - 1) * 2
val congruentTo = (-(index % period) + period) % period
period to congruentTo
}.sortedByDescending { it.first }.toMutableList()
}

7
day14.kt Normal file
View File

@ -0,0 +1,7 @@
import java.io.File
fun main(args: Array<String>){
val inputFile = File("../day_14.txt")
val lines = inputFile.readLines()
val firstLine = lines.first()
}

89
day14_1.rb Normal file
View File

@ -0,0 +1,89 @@
require 'set'
def hash_code(string)
initial_string = [*0..255]
suffix = [17, 31, 73, 47, 23]
# shifts = File.open('puzzle_10.txt').read.split(',').map(&:to_i) + suffix
# shifts = [1, 2, 3] + suffix
# shifts = suffix
shifts = string.split('').map(&:ord)
shifts = shifts + suffix
skip_size = 0
offset = 0
shifts = shifts * 64
for shift in shifts do
initial_string.rotate! offset
if shift > 0 then
rotated_bit = initial_string[0..shift - 1]
kept_bit = initial_string[shift..initial_string.length-1]
initial_string = rotated_bit.reverse + kept_bit
end
initial_string.rotate! -offset
offset += shift + skip_size
skip_size += 1
end
blocks = initial_string.each_slice(16).to_a
hash = blocks.map do |block|
block.inject(0) { |x, y| x^y }.to_s(16).rjust(2, '0')
end
return hash.join('')
end
input = "jxqlasbh"
# input = "flqrgnkx"
total = 0
map = []
128.times do |time|
hash_input = input + '-' + time.to_s
computed_hash = hash_code(hash_input)
binary = computed_hash.split('').map do |it|
it.to_i 16
end.map do |it|
(it.to_s 2).rjust(4, '0')
end.join('')
total += binary.count '1'
map.push(binary.split(''))
end
puts total
puts "#{map[0][0..3]}"
puts "#{map[1][0..3]}"
puts "#{map[2][0..3]}"
puts "#{map[3][0..3]}"
enabled = []
128.times do |x|
128.times do |y|
if map[x][y] != '1' then next end
enabled.push [[x, y]]
end
end
def is_neighbor(a, b)
a_neighbors = [[a[0]+1,a[1]],[a[0]-1, a[1]], [a[0],a[1]+1], [a[0],a[1]-1]]
return a_neighbors.include? b
end
final_groups = []
modified = true
while modified do
modified = false
i = 0
while i < enabled.length do
current = enabled[i]
j = i + 1
while j < enabled.length do
other = enabled[j]
if (current.product other).any? { |a| is_neighbor(a[0], a[1]) } then
current.concat other
enabled.delete_at(j)
modified = true
else
j += 1
end
end
i += 1
end
end
puts enabled.length

45
day15.kt Normal file
View File

@ -0,0 +1,45 @@
import java.io.File
fun generateANext(current: Long): Long {
return (current * 16807) % 2147483647
}
fun generateBNext(current: Long): Long {
return (current * 48271) % 2147483647
}
fun generateACertain(current: Long): Long {
var toReturn = current
do {
toReturn = generateANext(toReturn)
} while (toReturn % 4L != 0L)
return toReturn
}
fun generateBCertain(current: Long): Long {
var toReturn = current
do {
toReturn = generateBNext(toReturn)
} while (toReturn % 8L != 0L)
return toReturn
}
fun main(args: Array<String>){
val initialAValue = 873L
val initialBValue = 583L
var i = 0
var count = 0
var currentA = initialAValue
var currentB = initialBValue
while(i < 5000000) {
currentA = generateACertain(currentA)
currentB = generateBCertain(currentB)
// println(currentA.toString(2))
// println(currentB.toString(2))
val firstA = currentA.toShort()
val firstB = currentB.toShort()
if(firstA == firstB) count++
i++
}
println(count)
}

85
day16.kt Normal file
View File

@ -0,0 +1,85 @@
import java.io.File
fun <T> MutableList<T>.shift(num: Int) {
var left = num;
while(left > 0) {
add(0, removeAt(size - 1))
left--
}
}
fun <T> MutableList<T>.switch(a: T, b: T) {
val indexA = indexOf(a)
val indexB = indexOf(b)
set(indexB, a)
set(indexA, b)
}
fun <T> MutableList<T>.switch(a: Int, b: Int){
val elA = elementAt(a)
val elB = elementAt(b)
set(a, elB)
set(b, elA)
}
fun main(args: Array<String>){
val inputFile = File("../puzzle_16.txt")
val inputLines = inputFile.readLines()
val firstLine = inputLines.first()
// "s1,x3/4,pe/b".split(",") //
val instructions = firstLine.split(",")
val programs = MutableList('p'-'a' + 1) {
('a' + it).toString()
}
val original = MutableList('p'-'a' + 1) {
('a' + it).toString()
}
val swapMap = mutableMapOf<Int, Int>()
var count = 0
instructions.forEach {
if(it.startsWith("s")) programs.shift(it.substring(1).toInt())
else {
val split = it.substring(1).split("/")
if(it.startsWith("x")) {
programs.switch(split[0].toInt(), split[1].toInt())
} else {
programs.switch(split[0], split[1])
}
}
}
println(programs.joinToString(""))
val output = programs.joinToString("")
while(true){
instructions.forEach {
if(it.startsWith("s")) programs.shift(it.substring(1).toInt())
else {
val split = it.substring(1).split("/")
if(it.startsWith("x")) {
programs.switch(split[0].toInt(), split[1].toInt())
} else {
programs.switch(split[0], split[1])
}
}
}
val newOutput = programs.joinToString("")
count++
if(newOutput == "abcdefghijklmnop") break
}
println(count)
println(programs.joinToString(""))
for(i in 0 until (1000000000 % (count + 1))){
instructions.forEach {
if(it.startsWith("s")) original.shift(it.substring(1).toInt())
else {
val split = it.substring(1).split("/")
if(it.startsWith("x")) {
original.switch(split[0].toInt(), split[1].toInt())
} else {
original.switch(split[0], split[1])
}
}
}
}
println(original.joinToString(""))
}

21
day17.kt Normal file
View File

@ -0,0 +1,21 @@
import java.io.File
import java.util.*
import kotlin.system.measureTimeMillis
fun main(args: Array<String>){
println(measureTimeMillis {
val numSteps = 301
var iterations = 1
var index = 0
var memorizedNumber = 0
while(iterations <= 50000000) {
index = (index + numSteps) % iterations
if(index == 0) {
memorizedNumber = iterations
}
index++
iterations++
}
println(memorizedNumber)
})
}

70
day18.kt Normal file
View File

@ -0,0 +1,70 @@
import java.io.File
fun getValue(map: MutableMap<String, Long>, value: String): Long {
return if(value.contains(Regex("\\d"))) value.toLong() else (map[value] ?: 0)
}
class Program(val lines: List<String>){
var numSent = 0
var index = 0
var queue = mutableListOf<Long>()
val registerMap = mutableMapOf<String, Long>()
var partner: Program? = null
var wait = false
fun step(){
if(index >= lines.size) return
val it = lines[index]
val split = it.split(" ")
if(it.startsWith("add")) {
registerMap[split[1]] = getValue(registerMap, split[1]) + getValue(registerMap, split[2])
} else if(it.startsWith("set")) {
registerMap[split[1]] = getValue(registerMap, split[2])
} else if(it.startsWith("snd")) {
partner!!.queue.add(getValue(registerMap, split[1]))
numSent++
} else if(it.startsWith("mul")) {
registerMap[split[1]] = getValue(registerMap, split[1]) * getValue(registerMap, split[2])
} else if(it.startsWith("mod")) {
registerMap[split[1]] = getValue(registerMap, split[1]) % getValue(registerMap, split[2])
} else if(it.startsWith("rcv")) {
if(queue.isEmpty()) {
wait = true
return
}
else {
registerMap[split[1]] = queue.removeAt(0)
wait = false
}
} else if(it.startsWith("jgz")) {
if(getValue(registerMap, split[1]) > 0) {
index += getValue(registerMap, split[2]).toInt()
return
}
}
index++
}
}
fun main(args: Array<String>) {
val file = File("../day18.txt")
// val file = File("test.txt")
val lines = file.readLines()
val firstLine = lines.first()
val registerMap = mutableMapOf<String, Long>()
var last = 0L
lines.forEach {
}
var index = 0;
val program1 = Program(lines)
val program2 = Program(lines)
program1.partner = program2
program2.partner = program1
program1.registerMap["p"] = 0
program2.registerMap["p"] = 1
while(!(program1.wait && program2.wait) && !(program1.index >= lines.size && program2.index >= lines.size)){
program1.step()
program2.step()
}
println(program2.numSent)
}

28
day19.txt.kt Normal file
View File

@ -0,0 +1,28 @@
import java.io.File
fun nextIndex(x: Int, y: Int, dir: Int) = listOf(1 + x to y, x to y-1, x-1 to y, x to y+1)[dir]
fun canMove(x: Int, y: Int, dir: Int, path: List<CharArray>): Boolean {
val (newX, newY) = nextIndex(x, y, dir)
return (newY in 0 until path.size) && (newX in 0 until path[newY].size) && path[newY][newX] != ' '
}
fun main(args: Array<String>) {
val file = File("../puzzle_19.txt")
val path = file.readLines().toList().map { it.toCharArray() }
var (indexX, indexY) = (163 to 0)
var direction = 3
val letterStack = mutableListOf<Char>()
var count = 1
while(true){
if(path[indexY][indexX] in ('A'..'Z')) letterStack.add(path[indexY][indexX])
if(!canMove(indexX, indexY, direction, path)) { direction = (direction + 1) % 4 }
if(!canMove(indexX, indexY, direction, path)) { direction = (direction + 2) % 4 }
if(!canMove(indexX, indexY, direction, path)) break
count++
val moveBy = nextIndex(indexX, indexY, direction)
indexX = moveBy.first
indexY = moveBy.second
}
println(letterStack.joinToString(""))
println(count)
}

16
day1_1.cpp Normal file
View File

@ -0,0 +1,16 @@
#include <iostream>
using namespace std;
int main(){
std::string input;
std::cin >> input;
long total = 0;
for(int i = 0; i < input.size(); i++){
int next_index = (i + 1) % input.size();
if(input[i] == input[next_index]){
total += input[i] - '0';
}
}
std::cout << total;
}

16
day1_2.cpp Normal file
View File

@ -0,0 +1,16 @@
#include <iostream>
using namespace std;
int main(){
std::string input;
std::cin >> input;
long total = 0;
for(int i = 0; i < input.size(); i++){
int next_index = (i + input.size() / 2) % input.size();
if(input[i] == input[next_index]){
total += input[i] - '0';
}
}
std::cout << total;
}

38
day20.kt Normal file
View File

@ -0,0 +1,38 @@
import java.io.File
import kotlin.math.absoluteValue
data class Particle(var x: Long, var y: Long, var z: Long,
var vx: Long, var vy: Long, var vz: Long,
var ax: Long, var ay: Long, var az: Long) {
fun distance() = x.absoluteValue + y.absoluteValue + z.absoluteValue
fun step(){
vx += ax
vy += ay
vz += az
x += vx
y += vy
z += vz
}
}
fun main(args: Array<String>){
val file = File("../puzzle_20.txt")
// val file = File("test.txt")
val lines = file.readLines()
val firstLine = lines.first()
val particles = lines.map {
val split = it.split("=")
val (x, y, z) = split[1].substring(1).substringBefore(">").split(",").map { it.toLong() }
val (vx, vy, vz) = split[2].substring(1).substringBefore(">").split(",").map { it.toLong() }
val (ax, ay, az) = split[3].substring(1).substringBefore(">").split(",").map { it.toLong() }
Particle(x, y, z, vx, vy, vz, ax, ay, az)
}
var count = 0
while(count < 1000){
particles.forEach {
it.step()
}
count++
}
println(particles.indexOf(particles.minBy { it.distance() }))
}

40
day20_2.kt Normal file
View File

@ -0,0 +1,40 @@
import java.io.File
import kotlin.math.absoluteValue
fun main(args: Array<String>){
val file = File("../puzzle_20.txt")
// val file = File("test.txt")
val lines = file.readLines()
val firstLine = lines.first()
val particles = lines.map {
val split = it.split("=")
val (x, y, z) = split[1].substring(1).substringBefore(">").split(",").map { it.toLong() }
val (vx, vy, vz) = split[2].substring(1).substringBefore(">").split(",").map { it.toLong() }
val (ax, ay, az) = split[3].substring(1).substringBefore(">").split(",").map { it.toLong() }
Particle(x, y, z, vx, vy, vz, ax, ay, az)
}.toMutableList()
var count = 0
while(count < 1000){
particles.forEach {
it.step()
}
val collidedParticles = mutableListOf<Particle>()
var index = 0
while(index < particles.size){
val par1 = particles[index]
var index2 = index + 1;
while(index2 < particles.size){
val par2 = particles[index2]
if(par1.x == par2.x && par1.y == par2.y && par1.z == par2.z) {
collidedParticles.add(par1)
collidedParticles.add(par2)
}
index2++
}
index++
}
particles.removeAll(collidedParticles)
count++
}
println(particles.size)
}

162
day21.kt Normal file
View File

@ -0,0 +1,162 @@
import java.io.File
class Pattern(val size: Int){
val map = Array(size) { CharArray(size) { ' ' } }
fun flipV(): Pattern {
val newPattern = Pattern(size)
for(x in 0 until size){
for(y in 0 until size){
val newX = size - 1 - x
val newY = y
newPattern.map[newY][newX] = map[y][x]
}
}
return newPattern
}
fun flipH(): Pattern {
val newPattern = Pattern(size)
for(x in 0 until size){
for(y in 0 until size){
val newX = x
val newY = size - 1 - y
newPattern.map[newY][newX] = map[y][x]
}
}
return newPattern
}
fun rotate(): Pattern {
val newPattern = Pattern(size)
for(x in 0 until size){
for(y in 0 until size){
val newX = y
val newY = size - 1 - x
newPattern.map[newY][newX] = map[y][x]
}
}
return newPattern
}
override operator fun equals(other: Any?): Boolean {
if(other !is Pattern) return false
return oneEquals(other)
}
fun equalsPattern(other: Pattern): Boolean {
if(other.size != size) return false
for(x in 0 until size) {
for(y in 0 until size){
if(other.map[y][x] != this.map[y][x]) return false
}
}
return true
}
fun oneEquals(other: Pattern): Boolean {
val first = rotate()
val flipH = flipH()
val flipV = flipV()
val thisMatches = equalsPattern(other) ||
rotate().equalsPattern(other) ||
rotate().rotate().equalsPattern(other) ||
rotate().rotate().rotate().equalsPattern(other)
val flipHMatches = flipH.equalsPattern(other) ||
flipH.rotate().equalsPattern(other) ||
flipH.rotate().rotate().equalsPattern(other) ||
flipH.rotate().rotate().rotate().equalsPattern(other)
val flipVMatches = flipV.equalsPattern(other) ||
flipV.rotate().equalsPattern(other) ||
flipV.rotate().rotate().equalsPattern(other) ||
flipV.rotate().rotate().equalsPattern(other)
return thisMatches || flipHMatches || flipVMatches
}
fun toStrings(): List<String>{
return map.map { it.joinToString(" ") }
}
fun split(): List<List<Pattern>> {
val toReturn = mutableListOf<MutableList<Pattern>>()
if(size % 2 == 0){
for(y in 0 until size / 2){
val newRow = mutableListOf<Pattern>()
for(x in 0 until size / 2){
val newPattern = Pattern(2)
for(newX in 0..1){
for(newY in 0..1){
newPattern.map[newY][newX] = map[y * 2 + newY][x * 2 + newX]
}
}
newRow.add(newPattern)
}
toReturn.add(newRow)
}
} else {
for(y in 0 until size / 3){
val newRow = mutableListOf<Pattern>()
for(x in 0 until size / 3){
val newPattern = Pattern(3)
for(newX in 0..2){
for(newY in 0..2){
newPattern.map[newY][newX] = map[y * 3 + newY][x * 3 + newX]
}
}
newRow.add(newPattern)
}
toReturn.add(newRow)
}
}
return toReturn
}
}
fun fromString(s: String): Pattern {
val lines = s.split("/")
val newPattern = Pattern(lines.size)
for(i in 0 until newPattern.size){
newPattern.map[i] = lines[i].toCharArray()
}
return newPattern
}
fun combine(list: List<List<Pattern>>): Pattern {
val newPattern = Pattern(list[0][0].size * list.size)
for(y in 0 until list.size){
for(x in 0 until list.size){
val copying = list[y][x]
for(oldY in 0 until copying.size){
for(oldX in 0 until copying.size){
newPattern.map[y * copying.size + oldY][x * copying.size + oldX] =
copying.map[oldY][oldX]
}
}
}
}
return newPattern
}
fun Map<Pattern, Pattern>.findMatching(pattern: Pattern): Pattern? {
return keys
.firstOrNull { it == pattern }
?.let { get(it) }
}
fun main(args: Array<String>){
// val file = File("test.txt")
val file = File("../puzzle_21.txt")
val lines = file.readLines()
val patternMap = mutableMapOf<Pattern, Pattern>()
lines.forEach {
val split = it.split(" => ")
patternMap.put(fromString(split[0]), fromString(split[1]))
}
val inputPattern = fromString(".#./..#/###")
var pattern = inputPattern
var count = 0
while (count < 18){
val split = pattern.split()
pattern = combine(split.map { it.map { patternMap.findMatching(it)!! } })
pattern.toStrings().forEach { println(it) }
println()
count += 1
}
println(pattern.toStrings().joinToString("").count { it == '#' })
}

33
day22.kt Normal file
View File

@ -0,0 +1,33 @@
import java.io.File
import kotlin.math.roundToLong
fun dirToCoords(index: Int) = listOf(1L to 0L, 0L to 1L, -1L to 0L, 0L to -1L)[index]
fun main(args: Array<String>){
val file = File("../puzzle_22.txt")
// val file = File("test.txt")
val lines = file.readLines()
val coordMap = mutableMapOf<Pair<Long, Long>, Int>()
lines.forEachIndexed { y, string -> string.toCharArray().forEachIndexed { x, c -> coordMap[x.toLong() to (lines.size - 1 - y).toLong()] = if(c == '#') 2 else 0 } }
var x = Math.ceil(coordMap.keys.maxBy { it.first }!!.first.toDouble() / 2).roundToLong()
var y = Math.ceil(coordMap.keys.maxBy { it.second }!!.second.toDouble() / 2).roundToLong()
println(x to y)
var direction = 1
var count = 0
var infectedCount = 0
while(count < 10000000) {
val isInfected = coordMap.computeIfAbsent(x to y) { 0 }
if(isInfected == 0) direction += 1
else if(isInfected == 1) {}
else if(isInfected == 2) direction -= 1
else direction = (direction + 2) % 4
direction = (direction + 4) % 4
coordMap[x to y] = (isInfected + 1) % 4
if(coordMap[x to y] == 2) infectedCount++
val (dx, dy) = dirToCoords(direction)
x += dx
y += dy
count++
}
println(infectedCount)
}

31
day22_2.kt Normal file
View File

@ -0,0 +1,31 @@
import java.io.File
import kotlin.math.roundToLong
fun main(args: Array<String>){
val file = File("../puzzle_22.txt")
// val file = File("test.txt")
val lines = file.readLines()
val coordMap = mutableMapOf<Pair<Long, Long>, Boolean>()
lines.forEachIndexed { y, string -> string.toCharArray().forEachIndexed { x, c -> coordMap[x.toLong() to (lines.size - 1 - y).toLong()] = c == '#'} }
var x = Math.ceil(coordMap.keys.maxBy { it.first }!!.first.toDouble() / 2).roundToLong()
var y = Math.ceil(coordMap.keys.maxBy { it.second }!!.second.toDouble() / 2).roundToLong()
println(x to y)
var direction = 1
var count = 0
var infectedCount = 0
while(count < 10000) {
val isInfected = coordMap.computeIfAbsent(x to y) { false }
if(isInfected) direction -= 1
else {
direction += 1
infectedCount++
}
direction = (direction + 4) % 4
coordMap[x to y] = !isInfected
val (dx, dy) = dirToCoords(direction)
x += dx
y += dy
count++
}
println(infectedCount)
}

39
day23.kt Normal file
View File

@ -0,0 +1,39 @@
import java.io.File
fun getValue(map: Map<String, Long>, key: String): Long {
return if(key.contains(Regex("\\d+"))) key.toLong() else map.getOrDefault(key, 0L)
}
fun main(args: Array<String>) {
val file = File("../puzzle_23.txt")
// val file = File("test.txt")
val lines = file.readLines().map { it.split(" ") }
val firstLine = lines.first()
val registers = mutableMapOf<String, Long>()
var index = 0
var count = 0
lines.forEach {
}
registers["a"] = 1
while(index < lines.size){
val split = lines[index]
if(split[0] == "set") {
registers[split[1]] = getValue(registers, split[2])
} else if (split[0] == "sub") {
registers[split[1]] = (registers[split[1]] ?: 0) - getValue(registers, split[2])
} else if(split[0] == "mul") {
registers[split[1]] = (registers[split[1]] ?: 0) * getValue(registers, split[2])
} else if(split[0] == "jnz") {
val cond = getValue(registers, split[1])
val offset = getValue(registers, split[2])
if(cond != 0L) {
index += offset.toInt()
continue
}
}
index++
}
println(count)
println(registers["h"])
}

68
day24.kt Normal file
View File

@ -0,0 +1,68 @@
import java.io.File
typealias Piece = List<Int>
typealias Bridge = List<Piece>
fun Bridge.cost(): Int {
val lastcost = last().first()
val betweenCost = (0 until size - 1).map {
this[it].first() * 2
}.sum()
return betweenCost + lastcost
}
fun getPaths(bridge: Bridge, pieces: List<Piece>): List<Bridge> {
val compatiblePieces = pieces.filter { it.contains(bridge.last().first() ) }
if(compatiblePieces.size != 0) {
return compatiblePieces.map {
val newPiece = it.toMutableList()
newPiece.remove(bridge.last().first())
val newPieces = pieces.toMutableList()
newPieces.remove(it)
val newBridge = bridge.toMutableList()
newBridge.add(newPiece)
getPaths(newBridge, newPieces)
}.fold(mutableListOf()) {
a, b ->
val list = mutableListOf<Bridge>()
list.addAll(a)
list.addAll(b)
list
}
} else return mutableListOf(bridge)
}
fun main(args: Array<String>){
val file = File("../puzzle_24.txt")
// val file = File("test.txt")
val lines = file.readLines()
val firstLine = lines.first()
val transformedLines = lines.toMutableList().map {
val split = it.split("/")
mutableListOf(split[0].toInt(), split[1].toInt())
}
var index = 0
var initialCombinations = transformedLines
.filter { it.contains(0) }
.map {
val withoutZero = it.toMutableList()
withoutZero.remove(0)
val withoutZeroPiece = transformedLines.toMutableList()
withoutZeroPiece.remove(it)
mutableListOf(withoutZero) to withoutZeroPiece
}.toMutableList()
val paths = initialCombinations.map {
val (bridge, pieces) = it
getPaths(bridge, pieces)
}.fold(mutableListOf<Bridge>()) {
a, b ->
val list = mutableListOf<Bridge>()
list.addAll(a)
list.addAll(b)
list
}
println(paths.map { it.cost() }.max())
val maxLength = paths.map { it.size }.max()
val maxLenghtMaxStrength = paths.filter { it.size == maxLength }.maxBy { it.cost() }
println(maxLenghtMaxStrength!!.cost())
}

46
day25.kt Normal file
View File

@ -0,0 +1,46 @@
import java.io.File
data class TuringValue(val toWrite: Int, val toMove: Int, val nextState: Char)
data class TuringState(val ifZero: TuringValue, val ifOne: TuringValue, val name: Char)
fun readValue(lines: List<String>, index: Int): TuringValue{
val firstLine = lines[index]
val toWrite = firstLine[firstLine.length - 2].toInt() - '0'.toInt()
val toMove = if(lines[index+1].endsWith("left.")) -1 else 1
val thirdLine = lines[index + 2]
val state = thirdLine[thirdLine.length - 2]
return TuringValue(toWrite, toMove, state)
}
fun readState(lines: List<String>, index: Int): TuringState {
val lineA = lines[index]
val name = lineA[lineA.length - 2]
return TuringState(readValue(lines, index + 2), readValue(lines, index + 6), name)
}
fun main(args: Array<String>){
// val file = File("../puzzle_25.txt")
val file = File("test.txt")
val lines = file.readLines()
val firstLine = lines.first()
val states = mutableMapOf<Char, TuringState>()
(0 until 6)
.map { readState(lines, it * 10) }
.forEach { states.put(it.name, it) }
val tape = mutableMapOf<Int, Int>()
var currentState: Char = 'A'
var steps = 12134527
var index = 0
while(steps > 0){
val tapeValue = tape.getOrDefault(index, 0)
val state = states.get(currentState)!!
val value = if(tapeValue == 0) state.ifZero else state.ifOne
tape[index] = value.toWrite
index += value.toMove
currentState = value.nextState
steps--
}
println(tape.values.count { it == 1 })
}

12
day2_1.rb Normal file
View File

@ -0,0 +1,12 @@
total = 0
while(true) do
line = gets
if line == nil then break end
numbers = line.split(' ').map do |number| number.to_i end
top = numbers.max
bottom = numbers.min
total += (top - bottom)
end
puts(total)

21
day2_2.rb Normal file
View File

@ -0,0 +1,21 @@
total = 0
while(true) do
line = gets
if line == nil then break end
numbers = line.split(' ').map do |num| num.to_i end
for i in (0..numbers.length - 1) do
for j in ((i + 1)..numbers.length - 1) do
pair = [numbers[i], numbers[j]]
max = pair.max
min = pair.min
if max % min == 0 then
total += max / min
next
end
end
end
end
puts(total)

26
day3_1.rb Normal file
View File

@ -0,0 +1,26 @@
def corner_num(corner)
return corner**2 - corner
end
puzzle_input = 289326
corner = (1 + Math.sqrt(1 + 4*(puzzle_input - 1))) / 2
puts corner
next_corner = corner_num(corner.ceil)
prev_corner = corner_num(corner.floor)
distance = 0
if(next_corner == prev_corner) then
distance = 2*((corner / 2).floor)
else
halfway_point = (next_corner + prev_corner) / 2
edge_length = next_corner - halfway_point
start_from = (puzzle_input > halfway_point) ? halfway_point : prev_corner
progress = (puzzle_input - 1 - start_from).to_f / edge_length
if(corner.floor % 2 == 1 and puzzle_input < halfway_point) then distance -= 1 end
previous_distance = (corner.ceil / 2).floor
next_distance = ((corner.floor)/2).floor
puts previous_distance
puts next_distance
distance += (corner / 2).floor
distance += (-previous_distance + (previous_distance + next_distance)*progress).abs
end
puts distance

56
day3_2.rb Normal file
View File

@ -0,0 +1,56 @@
states = {
"left" => "down",
"down" => "right",
"right" => "up",
"up" => "left"
}
stepsx = {
"right" => 1,
"left" => -1
}
stepsy = {
"up" => 1,
"down" => -1
}
increases = {
"left" => 1,
"right" => 1
}
stepsx.default = 0
stepsy.default = 0
increases.default = 0
memory = Array.new(399)
399.times do |time|
memory[time] = Array.new(399, 0)
end
step = 1
x = 199
y = 199
memory[x][y] = 1
x += 1
state = "up"
memory[x][y] = 1
input = 289326
while(true) do
dx = stepsx[state]
dy = stepsy[state]
step.times do |time|
x += dx
y += dy
total = 0
for i in -1..1 do
for j in -1..1 do
if(!(j == 0 && i == 0)) then total += memory[x + i][y + j] end
end
end
puts total
if(total > input) then exit() end
memory[x][y] = total
end
state = states[state]
step += increases[state]
end

9
day4_1.rb Normal file
View File

@ -0,0 +1,9 @@
def is_unique(line)
original = line.split(' ')
unique = original.uniq
return original.length == unique.length
end
contents = File.open("puzzle_4.txt", "rb").read
lines = contents.split("\n")
puts lines.select {|line| is_unique(line)}.length

27
day4_2.rb Normal file
View File

@ -0,0 +1,27 @@
def frequency(string)
keys = {}
keys.default = 0
for letter in string.split('') do
keys[letter] = keys[letter] + 1
end
return keys
end
def is_anagram(first, second)
return frequency(first) == frequency(second)
end
def is_unique(line)
words = line.split(' ')
for i in 0..words.length - 1 do
word = words[i]
for j in (i+1)..words.length - 1 do
if is_anagram(word, words[j]) then return false end
end
end
return true
end
contents = File.open("puzzle_4.txt", "rb").read
lines = contents.split("\n")
puts lines.select {|line| is_unique(line)}.length

9
day5_1.rb Normal file
View File

@ -0,0 +1,9 @@
jumpArray = File.open('puzzle_5.txt').read.split("\n").map(&:to_i)
num_steps = 0
index = 0
while (index < jumpArray.length) do
jumpArray[index] += 1
index += jumpArray[index] - 1
num_steps += 1
end
puts num_steps

10
day5_2.rb Normal file
View File

@ -0,0 +1,10 @@
jumpArray = File.open('puzzle_5.txt').read.split("\n").map(&:to_i)
num_steps = 0
index = 0
while (index < jumpArray.length) do
change = (jumpArray[index] >= 3) ? -1 : 1
jumpArray[index] += change
index += jumpArray[index] - change
num_steps += 1
end
puts num_steps

20
day6_1.rb Normal file
View File

@ -0,0 +1,20 @@
input = File.open('puzzle_6.txt').read.split(' ').map(&:to_i)
combinations = [ input.dup ]
while(true) do
to_distribute = input.max
start_at = input.index to_distribute
input[start_at] = 0
start_at += 1
while(to_distribute > 0) do
start_at %= input.length
to_distribute -= 1
input[start_at] += 1
start_at += 1
end
if(combinations.include? input) then
puts combinations.index input
break
end
combinations.push input.clone
end
puts combinations.length

107
day7.kt Normal file
View File

@ -0,0 +1,107 @@
import java.io.File
abstract class Tree(val weight: Int) {
abstract fun walk(parent: Tree?, name: String, function: (Tree?, String, Tree) -> Unit)
abstract fun <T> reduce(transformFunction: (Tree) -> T, combineFunction: (T, List<T>) -> T): T
val combinedWeight: Int
get() {
val reduceFunction: (Tree) -> Int = {
it.weight
}
val combineFunction: (Int, List<Int>) -> Int = {
parent, children ->
parent + children.fold(0) { a, b -> a + b}
}
return reduce(reduceFunction, combineFunction)
}
}
class Placeholder : Tree(0) {
override fun <T> reduce(transformFunction: (Tree) -> T, combineFunction: (T, List<T>) -> T): T {
return transformFunction(this)
}
override fun walk(parent: Tree?, name: String, function: (Tree?, String, Tree) -> Unit) {
function(parent, name, this)
}
}
class Child(weight: Int) : Tree(weight) {
override fun <T> reduce(transformFunction: (Tree) -> T, combineFunction: (T, List<T>) -> T): T {
return transformFunction(this)
}
override fun walk(parent: Tree?, name: String, function: (Tree?, String, Tree) -> Unit) {
function(parent, name, this)
}
}
class Parent(weight: Int) : Tree(weight) {
val children = mutableMapOf<String, Tree>()
override fun <T> reduce(transformFunction: (Tree) -> T, combineFunction: (T, List<T>) -> T): T {
return combineFunction(transformFunction(this), children.map { it.value.reduce(transformFunction, combineFunction) })
}
override fun walk(parent: Tree?, name: String, function: (Tree?, String, Tree) -> Unit) {
function(parent, name, this)
children.forEach { t, u -> u.walk(this, t, function) }
}
}
fun main(args: Array<String>) {
val extractionPattern = Regex("([a-z]+)\\s*\\((\\d+)\\)\\s*(?:->\\s*(.+))?")
val baseMap = mutableMapOf<String, Tree>()
val nodesWithParent = mutableListOf<Tree>()
File("../puzzle_7.txt").readLines().forEach {
val match = extractionPattern.matchEntire(it)!!
val name = match.groupValues[1]
val weight = match.groupValues[2].toInt()
val childrenString = match.groupValues[3]
val children = if(childrenString.isEmpty()) emptyList() else childrenString.split(", ")
val newNode = if(children.isEmpty()) {
Child(weight)
} else {
val newParent = Parent(weight)
children.forEach { childName -> newParent.children.put(childName, Placeholder()) }
newParent
}
baseMap.put(name, newNode)
}
baseMap.forEach {
val treeNode = it.value as? Parent ?: return@forEach
treeNode.children.forEach {
pair ->
val (childKey, _) = pair
val childNode = baseMap[childKey]!!
treeNode.children[childKey] = childNode
nodesWithParent.add(childNode)
}
}
val (name, node) = baseMap.filterValues { !nodesWithParent.contains(it) }.entries.first()
node.walk(null, name) {
parent, name, node ->
if(parent == null) println("root node is $name")
if(node is Parent){
val childWeightPairs = node.children.map { it.value.combinedWeight to it.key }
val childWeights = childWeightPairs.map { it.first }
if(childWeights.toSet().size != 1) {
val frequencyMap = mutableMapOf<Int, Int>()
childWeights.forEach { frequencyMap[it] = frequencyMap.getOrDefault(it, 0) + 1 }
val culpritWeight = frequencyMap.filter { it.value == 1 }.keys.first()
val properWeight = frequencyMap.filter { it.key != culpritWeight }.keys.first()
val culpritNode = childWeightPairs.filter { it.first == culpritWeight }.first()
val culpritChildren = (node.children[culpritNode.second] as Parent).children.values
val culpritChildrenWeights = culpritChildren.map { it.combinedWeight }
if(culpritChildrenWeights.toSet().size == 1) {
println("$culpritNode has balanced children, but doesn't weight right.")
println("Correct weight is $properWeight, but actually is $culpritWeight")
val difference = properWeight - culpritWeight
println("The difference is $difference, and must be adjusted with node weight.")
println("Correct node weight is ${difference + node.children[culpritNode.second]!!.weight}")
}
}
}
}
}

40
day8.kt Normal file
View File

@ -0,0 +1,40 @@
import java.io.File
val instructionMap = mapOf(
"inc" to { left: Int, right: Int -> left + right},
"dec" to { left: Int, right: Int -> left - right }
)
val conditionMap = mapOf(
"==" to { left: Int, right: Int -> left == right },
"!=" to { left: Int, right: Int -> left != right },
">=" to { left: Int, right: Int -> left >= right },
"<=" to { left: Int, right: Int -> left <= right },
">" to { left: Int, right: Int -> left > right },
"<" to { left: Int, right: Int -> left < right }
)
data class Instruction(val register: String, val op: String, val operand: Int,
val conditionRegister: String, val condition: String, val conditionOperand: Int) {
fun execute(registers: MutableMap<String, Int>) {
if(conditionMap[condition]!!(registers.getOrDefault(conditionRegister, 0), conditionOperand))
registers[register] = instructionMap[op]!!(registers.getOrDefault(register, 0), operand)
}
}
fun main(args: Array<String>) {
val registerMap = mutableMapOf<String, Int>()
val extractionPattern = Regex("([a-z]+) (inc|dec) (-?\\d+) if ([a-z]+) ([^\\s]+) (-?\\d+)")
val instructions = File("../puzzle_8.txt").readLines().map {
val resultingPattern = extractionPattern.matchEntire(it) ?: return
with(resultingPattern.groupValues){
Instruction(get(1), get(2), get(3).toInt(), get(4), get(5), get(6).toInt())
}
}
var maxValue = Int.MIN_VALUE
instructions.forEach {
it.execute(registerMap)
val currentMax = registerMap.values.sorted().last()
maxValue = Math.max(currentMax, maxValue)
}
println("Largest value in any register is ${registerMap.values.sorted().last()}")
println("Largest possible max value is $maxValue")
}

33
day9.kt Normal file
View File

@ -0,0 +1,33 @@
import java.io.File
fun main(args: Array<String>){
val line = File("../puzzle_9.txt").readLines().first()
// val line = "<!!!>>"
var indent = 0
var totalScore = 0
var currentIndex = 0
var garbage = 0
while(currentIndex < line.length) {
when {
line[currentIndex] == '{' -> indent++
line[currentIndex] == '<' -> {
while(currentIndex < line.length && line[currentIndex] != '>') {
if(line[currentIndex] != '!') {
garbage += 1
currentIndex += 1
} else {
currentIndex += 2
}
}
garbage -= 1
}
line[currentIndex] == '}' -> {
totalScore += indent
indent--
}
}
currentIndex++
}
println("The score is $totalScore")
println("The garbage amount is $garbage")
}

16
test.kt Normal file
View File

@ -0,0 +1,16 @@
import kotlin.math.roundToInt
fun main(args: Array<String>) {
var count = 0
var startAt = 84 * 100 + 100000
var iterations = 0
while(iterations <= 1000) {
for(i in 2 until startAt) if(startAt % i == 0) {
count++
break
}
startAt += 17
iterations++
}
println(count)
}