Advent of Code 2021 day 2
12/02/2022, 5:00 AMDavid Whittaker
12/02/2022, 5:14 AMwhen
to the rescue yet again!Jakub Gwóźdź
12/02/2022, 5:29 AMwhen
as it was the fastest way to get the results and I’m not ashamed of it, but I’m sure during the day I will optimize the hell of it! 🙂David Whittaker
12/02/2022, 5:30 AMJakub Gwóźdź
12/02/2022, 5:30 AMinput.parseRecords(regex, ::parse)
.sumOf { (abc, xyz) ->
It looks ok on page, but when I use “export to clipboard” it fails somehow 🙂 ) - fortunately downloading as pdf works ok, next time thenDavid Whittaker
12/02/2022, 5:34 AMelse
--- ROFL 🤣Jan Durovec
12/02/2022, 5:35 AMwhen
just with slightly more math
fun parseInput(name: String): List<Pair<Int, Int>> {
return readInput(name)
.map { it.split(" ") }
.map { it[0][0].code - 'A'.code + 1 to it[1][0].code - 'X'.code + 1 }
}
fun part1(input: List<Pair<Int, Int>>) = input.sumOf {
it.second + when {
it.first == it.second -> drawPoints
1 + (it.first % 3) == it.second -> winPoints
else -> 0
}
}
fun part2(input: List<Pair<Int, Int>>) = input.sumOf {
when (it.second) {
1 -> ((it.first + 1) % 3) + 1
2 -> it.first + drawPoints
else -> (it.first % 3) + 1 + winPoints
}
}
xxfast
12/02/2022, 5:36 AMenum class Hand { Rock, Paper, Scissors; }
enum class Outcome { Loss, Draw, Win }
val Hand.score: Int get() = ordinal + 1
val Outcome.score: Int get() = ordinal * 3
val String.hand: Hand get() = when (this) {
"A", "X" -> Rock
"B", "Y" -> Paper
"C", "Z" -> Scissors
else -> error("Invalid hand")
}
val String.outcome: Outcome get() = when(this){
"X" -> Loss
"Y" -> Draw
"Z" -> Win
else -> error("Invalid outcome")
}
infix fun Hand.against(elf: Hand): Outcome = when {
this == elf -> Draw
this == elf.winner -> Win
else -> Loss
}
val Hand.winner: Hand get() = when(this){
Rock -> Paper
Paper -> Scissors
Scissors -> Rock
}
val Hand.loser: Hand get() = when(this){
Rock -> Scissors
Paper -> Rock
Scissors -> Paper
}
fun handFor(outcome: Outcome, with: Hand): Hand = when(outcome) {
Loss -> with.loser
Win -> with.winner
Draw -> with
}
fun format(input: List<String>): List<List<String>> = input
.map { row -> row.split(" ") }
fun part1(input: List<String>): Int = format(input)
.map { (elf, you) -> elf.hand to you.hand }
.sumOf { (elf, you) -> you.score + (you against elf).score }
fun part2(input: List<String>): Int = format(input)
.map { (elf, game) -> elf.hand to game.outcome }
.sumOf { (elf, outcome) -> handFor(outcome, with = elf).score + outcome.score }
Jakub Gwóźdź
12/02/2022, 5:37 AMKroppeb
12/02/2022, 5:42 AMp1 += (x - 'X' + 1) + 3 * ((x - 'X' - (a - 'A') + 1 + 999) % 3)
p2 += (((a - 'A') + (x - 'X') - 1 + 999) % 3) + 1 + 3 * (x - 'X')
Marcin Wisniowski
12/02/2022, 5:44 AMKroppeb
12/02/2022, 5:59 AMMichael de Kaste
12/02/2022, 6:00 AMobject Day2 : Challenge() {
val parsed = input.lines()
.map { it.split(" ").map(String::first) }
.map { (him, me) -> (him - 'A') to (me - 'X') }
override fun part1() = parsed.sumOf { (him, me) -> ((me + 4 - him) % 3) * 3 + me + 1 }
override fun part2() = parsed.sumOf { (him, me) -> (me + 2 + him) % 3 + 1 + me * 3 }
}
Michael de Kaste
12/02/2022, 6:01 AMJakub Gwóźdź
12/02/2022, 6:06 AMMichael de Kaste
12/02/2022, 6:09 AMVivekpanchal64
12/02/2022, 6:12 AMwhen
with multiple cases but now i look solutions here i see i need to learn alot from you guysCognitive Gear
12/02/2022, 6:15 AMMarcin Wisniowski
12/02/2022, 6:20 AMMarc Javier
12/02/2022, 6:23 AMephemient
12/02/2022, 6:40 AMwhen
, just fun with mod
https://github.com/ephemient/aoc2022/blob/main/kt/src/commonMain/kotlin/com/github/ephemient/aoc2022/Day2.ktMichael Böiers
12/02/2022, 7:07 AMfun main() = day02(String(System.`in`.readAllBytes())).forEach(::println)
fun day02(input: String) = with(input.lines()) { listOf(sumOf(::part1Round), sumOf(::part2Round)) }
private fun part1Round(line: String) = when (line) {
"A X" -> 1 + 3
"B X" -> 1 + 0
"C X" -> 1 + 6
"A Y" -> 2 + 6
"B Y" -> 2 + 3
"C Y" -> 2 + 0
"A Z" -> 3 + 0
"B Z" -> 3 + 6
"C Z" -> 3 + 3
else -> throw IllegalArgumentException(line)
}
private fun part2Round(line: String) = when (line) {
"A X" -> 3 + 0
"B X" -> 1 + 0
"C X" -> 2 + 0
"A Y" -> 1 + 3
"B Y" -> 2 + 3
"C Y" -> 3 + 3
"A Z" -> 2 + 6
"B Z" -> 3 + 6
"C Z" -> 1 + 6
else -> throw IllegalArgumentException(line)
}
Dan Fingal-Surma
12/02/2022, 7:07 AMBig Chungus
12/02/2022, 7:28 AMPoisonedYouth
12/02/2022, 7:29 AMMichael Böiers
12/02/2022, 7:36 AMPoisonedYouth
12/02/2022, 7:41 AMMichael Böiers
12/02/2022, 7:45 AMRock
a big improvement over "R"
in the context of a challenge like this? Even in real projects I’d probably not use enums here to begin with. As soon as the logic gets more complex, you can always introduce enums.Michael de Kaste
12/02/2022, 7:48 AMPoisonedYouth
12/02/2022, 7:58 AMTodor Grudev
12/02/2022, 8:09 AMNeil Banman
12/02/2022, 8:31 AMephemient
12/02/2022, 8:35 AMMichael Böiers
12/02/2022, 8:45 AMfun day02Clean(input: String) = with(input.lines().map { it.split(" ") }) {
listOf(sumOf(::playPart1), sumOf(::playPart2))
}
private fun playPart1(line: List<String>): Int {
val (opponentMove, myMove) = line.map { it.toRPSMove() }
return myMove.score + myMove.playAgainst(opponentMove).score
}
private fun playPart2(line: List<String>): Int {
val opponentMove = line[0].toRPSMove()
val desiredResult = line[1].toRPSResult()
val myMove = opponentMove.whatToPlayToAchieve(desiredResult)
return myMove.score + myMove.playAgainst(opponentMove).score
}
private enum class RPSMove(val score: Int) { Rock(1), Paper(2), Scissors(3) }
private fun RPSMove.playAgainst(move: RPSMove): RPSResult = when (this to move) {
Rock to Rock, Paper to Paper, Scissors to Scissors -> Draw
Rock to Scissors, Paper to Rock, Scissors to Paper -> Win
else -> Lose
}
private fun RPSMove.whatToPlayToAchieve(result: RPSResult) = when (result to this) {
Win to Rock, Lose to Scissors -> Paper
Win to Paper, Lose to Rock -> Scissors
Win to Scissors, Lose to Paper -> Rock
else -> this
}
private fun String.toRPSMove() = when (this) {
"A", "X" -> Rock
"B", "Y" -> Paper
"C", "Z" -> Scissors
else -> throw IllegalArgumentException(this)
}
private enum class RPSResult(val score: Int) { Win(6), Lose(0), Draw(3) }
private fun String.toRPSResult() = when (this) {
"X" -> Lose
"Y" -> Draw
"Z" -> Win
else -> throw IllegalArgumentException(this)
}
PoisonedYouth
12/02/2022, 9:03 AMMichael Böiers
12/02/2022, 9:09 AM(Rock, Scissors)
would work better than Rock to Scissors
in my code above, since the to
reads like it means something, when in this case it just means “Tuple”.Michael de Kaste
12/02/2022, 9:09 AMMichael Böiers
12/02/2022, 9:10 AMMichael Böiers
12/02/2022, 9:12 AMPair(Rock, Scissors), Pair(Paper, Rock), Pair(Scissors, Paper) -> Win
Scissors to Rock, Paper to Scissors, Rock to Paper -> Lose
🤔ritesh
12/02/2022, 9:12 AMwhen
everywhere, it could be more optimised without any extra space but with if-else/when ladder 😄
// Y defeats A
// Z defeats B
// X defeats C
val defeatMap = mapOf(
"A" to "Y",
"B" to "Z",
"C" to "X"
)
// X loses to B
// Y loses to C
// Z loses to A
val loseMap = mapOf(
"B" to "X",
"C" to "Y",
"A" to "Z"
)
val drawMap = mapOf(
"A" to "X",
"B" to "Y",
"C" to "Z"
)
val rockPaperScissorScore = mapOf(
"X" to 1,
"Y" to 2,
"Z" to 3
)
val LOST = 0
val DRAW = 3
val WIN = 6
fun getTotalScorePart1(opponent: String, you: String): Int {
return when (you) {
defeatMap[opponent] -> { // win
WIN + rockPaperScissorScore[you]!!
}
drawMap[opponent] -> { // draw
DRAW + rockPaperScissorScore[you]!!
}
else -> { // lost
LOST + rockPaperScissorScore[you]!!
}
}
}
fun getTotalScorePart2(opponent: String, you: String): Int {
return when (you) {
"X" -> { // need to lose
LOST + rockPaperScissorScore[loseMap[opponent]]!!
}
"Y" -> { // need to draw
DRAW + rockPaperScissorScore[drawMap[opponent]]!!
}
else -> {
// need to win
WIN + rockPaperScissorScore[defeatMap[opponent]]!!
}
}
}
Davio
12/02/2022, 9:20 AMDavio
12/02/2022, 9:20 AMDavio
12/02/2022, 9:22 AMMattia Tommasone
12/02/2022, 9:23 AMDavio
12/02/2022, 9:32 AMscissors, rock, paper
in that order, to decide for a given choice if it wins or loses against another choice, we look at element index+1 in the structure, but if we get out of bounds, we go back to index 0, so for:
if we choose the same option as our opponent, we always draw
say the opponent chooses option A which is at index i in our data structure,
we select option B at index i+1 from the data structure to consider
if the selected option is our choice, we win
otherwise we lose
Davio
12/02/2022, 9:42 AMenum class Outcome(val points: Int) {
WIN(6),
DRAW(3),
LOSE(0)
}
enum class RockPaperScissors(val points: Int) {
ROCK(1),
PAPER(2),
SCISSORS(3),
}
private val opponentCodeMap = mapOf(
'A' to ROCK,
'B' to PAPER,
'C' to SCISSORS
)
private val rspStructure = arrayOf(SCISSORS, ROCK, PAPER)
private fun RockPaperScissors.getOutcomeAgainstOpponent(opponentChoice: RockPaperScissors): Outcome {
if (this == opponentChoice) {
return Outcome.DRAW
}
val choiceToWin = rspStructure[(rspStructure.indexOf(opponentChoice) + 1) % rspStructure.size]
return if (this == choiceToWin) { Outcome.WIN } else { Outcome.LOSE }
}
fun getResultPart1() {
val yourCodeMap = mapOf(
'X' to ROCK,
'Y' to PAPER,
'Z' to SCISSORS
)
getInputAsSequence().map {
val opponentChoice = opponentCodeMap[(it.first())]!!
val yourChoice = yourCodeMap[it[2]]!!
yourChoice.points + yourChoice.getOutcomeAgainstOpponent(opponentChoice).points
}.sum()
.call { println(it) }
}
Davio
12/02/2022, 9:53 AMwhen
to check the desired outcome
fun getResultPart2() {
val desiredOutcomeMap = mapOf(
'X' to LOSE,
'Y' to DRAW,
'Z' to WIN
)
getInputAsSequence().map {
val opponentChoice = opponentCodeMap[(it.first())]!!
val desiredOutcome = desiredOutcomeMap[it[2]]!!
desiredOutcome.points + when (desiredOutcome) {
DRAW -> opponentChoice.points
WIN -> rspStructure[(rspStructure.indexOf(opponentChoice) + 1) % rspStructure.size].points
LOSE -> {
val losingIndex = (rspStructure.indexOf(opponentChoice) - 1).let { index ->
if (index < 0) index + rspStructure.size else index
}
rspStructure[losingIndex].points
}
}
}.sum()
.call { println(it) }
}
Davio
12/02/2022, 9:53 AMwhen
mappings this way 😄Michael Böiers
12/02/2022, 9:54 AMcall
method different from also
?Davio
12/02/2022, 9:55 AMMichael Böiers
12/02/2022, 9:56 AMDavio
12/02/2022, 9:56 AMMichael Böiers
12/02/2022, 9:57 AMDavio
12/02/2022, 9:58 AMMichael Böiers
12/02/2022, 9:58 AMcall
is just an also
, then using it only accomplishes one thing: Annoy everyone but yourself. 😉Davio
12/02/2022, 9:58 AMMichael Böiers
12/02/2022, 9:59 AMwhen
.Davio
12/02/2022, 10:00 AMMichael Böiers
12/02/2022, 10:00 AMDavio
12/02/2022, 10:01 AMDavio
12/02/2022, 10:03 AMialokim
12/02/2022, 10:03 AMwhen
, combinded with a nice enum class
🙂 the rest of the logic was quite straightforward having thisFredrik Rødland
12/02/2022, 10:04 AMHand
enum and based the rest of the code on it's win()
and lose()
function:
https://github.com/fmmr/advent/blob/master/src/main/kotlin/no/rodland/advent_2022/Day02.ktFredrik Rødland
12/02/2022, 10:06 AMFredrik Rødland
12/02/2022, 10:07 AMJakub Gwóźdź
12/02/2022, 10:18 AMDavio
12/02/2022, 10:36 AMJoakim Tall
12/02/2022, 10:49 AMDavio
12/02/2022, 10:50 AMJoakim Tall
12/02/2022, 10:50 AMDavio
12/02/2022, 10:53 AMenum class Hand(val score: Int) : Beatable {
ROCK(1) {
override fun beats() = SCISSORS
override fun loses() = PAPER
},
PAPER(2) {
override fun beats() = ROCK
override fun loses() = SCISSORS
},
SCISSORS(3) {
override fun beats() = PAPER
override fun loses() = ROCK
}
}
interface Beatable {
fun beats(): Hand
fun loses(): Hand
}
Davio
12/02/2022, 10:53 AMDavio
12/02/2022, 10:54 AMJoakim Tall
12/02/2022, 10:54 AMJoakim Tall
12/02/2022, 10:55 AMJoakim Tall
12/02/2022, 10:55 AMFredrik Rødland
12/02/2022, 10:55 AMJoakim Tall
12/02/2022, 10:56 AMDavio
12/02/2022, 10:56 AMFredrik Rødland
12/02/2022, 10:56 AMROCK(1, PAPER, SCISSORS) ...
will not compileJoakim Tall
12/02/2022, 10:56 AMDavio
12/02/2022, 10:58 AMJoakim Tall
12/02/2022, 10:59 AMMichael Böiers
12/02/2022, 11:00 AMCharles Flynn
12/02/2022, 11:23 AMS.
12/02/2022, 11:41 AMMichael Böiers
12/02/2022, 12:36 PMtodd.ginsberg
12/02/2022, 12:40 PMMap<String,Int>
for each part and pre-calculated the answers and just summed them up. I’ll write it up later. 🙂Paul Woitaschek
12/02/2022, 12:59 PMÇAĞRI YILDIRIM
12/02/2022, 1:50 PMFlorent Bergé
12/02/2022, 1:54 PMtodd.ginsberg
12/02/2022, 1:58 PMritesh
12/02/2022, 1:59 PMritesh
12/02/2022, 2:00 PMPoisonedYouth
12/02/2022, 2:14 PMDavio
12/02/2022, 2:22 PMquicksort=: (($:@(<#[), (=#[), $:@(>#[)) ({~ ?@#)) ^: (1<#)
😄Charles Flynn
12/02/2022, 2:50 PMtodd.ginsberg
12/02/2022, 2:51 PMKevin Del Castillo
12/02/2022, 2:54 PMCharles Flynn
12/02/2022, 2:59 PMchiroptical
12/02/2022, 3:07 PMchiroptical
12/02/2022, 3:09 PMScott Peterson
12/02/2022, 3:19 PMwhen
without needing an else
Michael Böiers
12/02/2022, 3:41 PMColin Marsch
12/02/2022, 3:49 PMenum
solutions folks have!Jacob
12/02/2022, 4:01 PMCharles Flynn
12/02/2022, 4:46 PMwakingrufus
12/02/2022, 5:14 PMKroppeb
12/02/2022, 5:46 PMe()
make the Strings into lists so I can destructor them. I should probably add util functions for those too
log
just prints the result essentiallyDirk Groot
12/02/2022, 6:05 PMephemient
12/02/2022, 6:09 PMe
to destructure, if you simply define
operator fun String.component1(): Char = get(0)
operator fun String.component2(): Char = get(1)
operator fun String.component 3(): Char = get(2)
etc.Kroppeb
12/02/2022, 6:10 PMe()
defined, so that's why I used itKroppeb
12/02/2022, 6:16 PMgetLines(2022_02).map { it.zip("A X", Char::minus) }.sumOf { (a, _, x) -> ... }
Davio
12/02/2022, 6:17 PMPoisonedYouth
12/02/2022, 6:24 PMKarloti
12/02/2022, 8:51 PMKroppeb
12/02/2022, 8:55 PMWael Ellithy
12/02/2022, 8:56 PM