feat: basic wrapper + days 1 to 3

This commit is contained in:
Xavier Morel
2025-04-29 19:21:48 +02:00
committed by installer
parent 6c2240960f
commit d937ef84bb
10 changed files with 181 additions and 10 deletions

View File

@@ -1,5 +1,10 @@
@main def hello(): Unit =
println("Hello world!")
println(msg)
import days._
def msg = "I was compiled by Scala 3. :)"
@main def main(dayNumber: Int): Unit = {
dayNumber match {
case 1 => Day1.solve()
case 2 => Day2.solve()
case 3 => Day3.solve()
case _ => println(s"Day $dayNumber is not yet implemented.")
}
}

View File

@@ -0,0 +1,31 @@
package days
import scala.io.Source
trait Day {
val number: Int
def getInput(): Option[String] = {
val resourcePath = getClass.getResource(s"day${number}.txt")
if (resourcePath != null) {
Some(Source.fromURL(resourcePath).mkString)
} else {
None
}
}
def solve(): Unit = {
getInput() match {
case Some(input) => {
println(s"Day: $number")
println(s"Part 1: ${part1(input)}")
println(s"Part 2: ${part2(input)}")
}
case None =>
println(s"Missing day $number input")
}
}
def part1(input: String): String
def part2(input: String): String
}

View File

@@ -0,0 +1,35 @@
package days
object Day1 extends Day {
val number: Int = 1;
def inputToLists(input: String): (List[Int], List[Int]) =
input.linesIterator
.map(l => {
val line = l.split(" ")
(line(0).toInt, line.last.toInt)
})
.foldLeft((Nil, Nil): Tuple2[List[Int], List[Int]]) {
case ((accL, accR), (l, r)) => (l :: accL, r :: accR)
}
def part1(input: String) = {
val (leftList, rightList) = inputToLists(input)
leftList
.sorted()
.zip(rightList.sorted())
.map((a, b) => (a - b).abs)
.sum
.toString()
}
def part2(input: String) = {
val (leftList, rightList) = inputToLists(input)
val counts =
rightList.sorted
.groupBy((n: Int) => n)
.mapValues(_.length)
leftList.map(n => counts.getOrElse(n, 0) * n).sum().toString()
}
}

View File

@@ -0,0 +1,56 @@
package days
object Day2 extends Day {
val number: Int = 2;
def checkFnP1(input: List[Int], order: Option[Boolean]): Boolean =
input match {
case Nil => true
case _ :: Nil => true
case a :: b :: t => {
val diff = a - b
if (diff < -3 || diff > 3 || diff == 0) {
return false
}
val curOrder = Some(diff > 0)
val newOrder: Option[Boolean] = (order, curOrder) match {
case (None, a) => a
case (a, b) if a == b => a
case _ => return false
}
checkFnP1(b :: t, newOrder)
}
}
def checkFnP2(
input: List[Int]
): Boolean = {
// Wanted to try a recursive approach like p1 but I gave up.. :(
if (checkFnP1(input, None)) {
return true
}
(0 until (input.length)).iterator
.map { n =>
{
val (before, after) = input.splitAt(n)
val newInput = before ++ after.tail
checkFnP1(newInput, None)
}
}
.dropWhile(_ == false)
.nextOption
.getOrElse(false)
}
def part1(input: String) =
input.linesIterator
.map(s => checkFnP1(s.split(" ").map(_.toInt).toList, None))
.count(_ == true)
.toString()
def part2(input: String) =
input.linesIterator
.map(s => checkFnP2(s.split(" ").map(_.toInt).toList))
.count(_ == true)
.toString()
}

View File

@@ -0,0 +1,32 @@
package days
import scala.util.matching.Regex
object Day3 extends Day {
val number: Int = 3;
def part1(input: String) =
"mul\\(([0-9]+),([0-9]+)\\)".r
.findAllMatchIn(input)
.map(m => m.group(1).toInt * m.group(2).toInt)
.sum()
.toString()
def part2(input: String) =
"(do)\\(\\)|(don't)\\(\\)|mul\\(([0-9]+),([0-9]+)\\)".r
.findAllMatchIn(input)
.foldLeft((true, 0)) {
// Activate flag if "do()" matched
case ((_, acc), m) if m.group(1) != null => (true, acc)
// Deactivate flag if "dont() matched"
case ((_, acc), m) if m.group(2) != null => (false, acc)
// Ignore mul() if deactivated
case ((false, acc), _) => (false, acc)
// Add mul() result to the accumulator
case ((true, acc), m) =>
(true, acc + m.group(3).toInt * m.group(4).toInt)
}
._2
.toString()
}

View File

@@ -0,0 +1,9 @@
package days
object Day4 extends Day {
val number: Int = 4;
def part1(input: String) = "pouet"
def part2(input: String) = "pouet"
}