added input downloader

This commit is contained in:
Andrew Glaze
2024-12-01 20:53:13 -05:00
parent a86940ba8e
commit 02f09d6cca
6 changed files with 110 additions and 44 deletions

2
.gitignore vendored
View File

@@ -3,3 +3,5 @@
# Ignore Gradle build output directory # Ignore Gradle build output directory
build build
.env

View File

@@ -29,6 +29,8 @@ dependencies {
// This dependency is used by the application. // This dependency is used by the application.
implementation(libs.guava) implementation(libs.guava)
implementation("io.github.cdimascio:dotenv-kotlin:6.4.2")
} }
// Apply a specific Java toolchain to ease working on different environments. // Apply a specific Java toolchain to ease working on different environments.

View File

@@ -6,44 +6,36 @@ import kotlin.math.abs
class Day01 { class Day01 {
fun parse(input: String): List<List<Int>> { fun parse(input: String): List<List<Int>> {
val lhs: MutableList<Int> = mutableListOf() val leftList: MutableList<Int> = mutableListOf()
val rhs: MutableList<Int> = mutableListOf() val rightList: MutableList<Int> = mutableListOf()
for (line in input.lines()) { for (line in input.lines()) {
val split = line.split(" ").map { str -> str.toInt() } val split = line.split(" ").map { str -> str.toInt() }
lhs.add(split[0]) leftList.add(split[0])
rhs.add(split[1]) rightList.add(split[1])
} }
return listOf(lhs, rhs) return listOf(leftList, rightList)
} }
fun part1(input: String): Int { fun part1(input: String): Int {
val lists = parse(input) val (leftList, rightList) = parse(input).map { list -> list.sorted() }
val lhs = lists[0].sorted()
val rhs = lists[1].sorted()
var sum = 0 return leftList.zip(rightList).map { (lhs, rhs) -> abs(lhs - rhs) }.sum()
for (i in 0..<lhs.count()) {
sum += abs(lhs[i] - rhs[i])
}
return sum;
} }
fun part2(input: String): Int { fun part2(input: String): Int {
val lists = parse(input) val (leftList, rightList) = parse(input).map { list -> list.sorted() }
val lhs = lists[0].sorted()
val rhs = lists[1].sorted()
var sum = 0 var sum = 0
for (i in 0..<lhs.count()) { for (i in 0..<leftList.count()) {
var rhs_idx = 0 var rhs_idx = 0
val target = lhs[i] val target = leftList[i]
var count = 0 var count = 0
while (rhs[rhs_idx] < target) { while (rightList[rhs_idx] < target) {
rhs_idx += 1 rhs_idx += 1
} }
while (rhs[rhs_idx] == target) { while (rightList[rhs_idx] == target) {
count += 1 count += 1
rhs_idx += 1 rhs_idx += 1
} }

View File

@@ -1,36 +1,42 @@
package day01 package day01
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertNotNull import util.InputDownloader
import kotlin.test.assertIs
class Day01Test { class Day01Test {
@Test fun part1() { val day = 1
val day = Day01()
val test = """3 4
4 3
2 5
1 3
3 9
3 3"""
val output = day.part1(test) val input = InputDownloader().getInput(day)
println(output) val example = InputDownloader().getExample(day)
assert(output == 11)
@Test fun part1Example() {
part1(example, 11)
} }
@Test fun part2() { @Test fun part2Example() {
part2(example, 31)
}
@Test fun part1Solution() {
part1(input, 1189304)
}
@Test fun part2Solution() {
part2(input, 24349736)
}
fun part1(input: String, expected: Int) {
val day = Day01() val day = Day01()
val output = day.part1(input)
println("output: $output")
assert(output == expected)
}
val test = """3 4 fun part2(input: String, expected: Int) {
4 3 val day = Day01()
2 5 val output = day.part2(input)
1 3 println("output: $output")
3 9 assert(output == expected)
3 3"""
val output = day.part2(test)
println(output)
assert(output == 31)
} }
} }

View File

@@ -0,0 +1,64 @@
package util
import java.net.URI
import java.net.http.HttpClient
import java.net.http.HttpRequest
import java.net.http.HttpResponse
import java.net.HttpCookie
import java.net.CookieHandler
import java.net.CookieManager
import java.net.ConnectException
import java.time.Duration
import io.github.cdimascio.dotenv.dotenv
class InputDownloader {
fun getInput(day: Int): String {
val dotenv = dotenv()
val sessionCookie = HttpCookie("session", dotenv["AOC_TOKEN"]);
sessionCookie.path = "/"
sessionCookie.version = 0
val manager = CookieManager()
manager.getCookieStore().add(URI("https://adventofcode.com"), sessionCookie)
val client = HttpClient.newBuilder()
.cookieHandler(manager)
.connectTimeout(Duration.ofSeconds(10))
.build()
val request = HttpRequest.newBuilder()
.uri(URI.create("https://adventofcode.com/2024/day/$day/input"))
.GET()
.build()
val res = client.send(request, HttpResponse.BodyHandlers.ofString())
if (res.statusCode() == 403) {
throw ConnectException("Failed to download input for day $day. Is your session token correct?")
}
if (res.statusCode() != ) {
throw ConnectException("Failed to download input for day $day. Is the day open yet?")
}
return res.body().trim()
}
fun getExample(day: Int): String {
val client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build()
val req = HttpRequest.newBuilder()
.uri(URI("https://adventofcode.com/2024/day/$day"))
.GET()
.build()
val res = client.send(req, HttpResponse.BodyHandlers.ofString())
if (res.statusCode() != 200) {
throw ConnectException("Failed to download example for day $day. Is the day open yet?")
}
val bod = res.body()
val start = bod.indexOf("<pre><code>")
val stop = bod.indexOf("</code></pre>")
val sliced = bod.substring(start + 11..<stop)
return sliced.trim()
}
}

Binary file not shown.