Skip to content

Commit

Permalink
Merge pull request #90 from ephemient/kt/day12
Browse files Browse the repository at this point in the history
Day 12: Garden Groups
  • Loading branch information
ephemient authored Dec 12, 2024
2 parents 5553690 + ea20a02 commit 31ed7fe
Show file tree
Hide file tree
Showing 5 changed files with 169 additions and 1 deletion.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ Development occurs in language-specific directories:
|[Day9.hs](hs/src/Day9.hs)|[Day9.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day9.kt)|[day9.py](py/aoc2024/day9.py)|[day9.rs](rs/src/day9.rs)|
|[Day10.hs](hs/src/Day10.hs)|[Day10.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day10.kt)|[day10.py](py/aoc2024/day10.py)|[day10.rs](rs/src/day10.rs)|
|[Day11.hs](hs/src/Day11.hs)|[Day11.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day11.kt)|[day11.py](py/aoc2024/day11.py)|[day11.rs](rs/src/day11.rs)|
|[Day12.hs](hs/src/Day12.hs)||||
|[Day12.hs](hs/src/Day12.hs)|[Day12.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day12.kt)|||
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.github.ephemient.aoc2024.exe

import com.github.ephemient.aoc2024.Day12
import kotlinx.benchmark.Benchmark
import kotlinx.benchmark.Blackhole
import kotlinx.benchmark.Scope
import kotlinx.benchmark.Setup
import kotlinx.benchmark.State

@State(Scope.Benchmark)
class Day12Bench {
private lateinit var input: String

@Setup
fun setup() {
input = getDayInput(12)
}

@Benchmark
fun part1() = Day12(input).part1()

@Benchmark
fun part2() = Day12(input).part2()

@Benchmark
fun solve(bh: Blackhole) {
val day12 = Day12(input)
bh.consume(day12.part1())
bh.consume(day12.part2())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package com.github.ephemient.aoc2024

import kotlin.math.abs

class Day12(input: String) {
private val groups = buildList {
val visited = mutableSetOf<IntPair>()
val lines = input.lines()
for ((y, line) in lines.withIndex()) {
line.forEachIndexed { x, char ->
add(
buildSet {
val stack = mutableListOf(y to x)
while (stack.isNotEmpty()) {
val pos = stack.removeLast()
if (lines[pos] != char || !visited.add(pos)) continue
add(pos)
stack.add(pos.first - 1 to pos.second)
stack.add(pos.first to pos.second - 1)
stack.add(pos.first to pos.second + 1)
stack.add(pos.first + 1 to pos.second)
}
}.ifEmpty { return@forEachIndexed }
)
}
}
}

fun part1() = groups.sumOf { group ->
group.size * group.flatMap { (y, x) ->
listOf(2 * y - 1 to 2 * x, 2 * y to 2 * x - 1, 2 * y to 2 * x + 1, 2 * y + 1 to 2 * x)
}.groupingBy { it }.eachCount().count { it.value == 1 }
}

fun part2() = groups.sumOf { group ->
group.size * group.flatMap { (y, x) ->
listOf(
2 * y - 1 to 2 * x to true,
2 * y to 2 * x - 1 to false,
2 * y to 2 * x + 1 to true,
2 * y + 1 to 2 * x to false,
)
}
.groupBy { it.first }
.flatMap { (_, value) -> if (value.size == 1) value else emptyList() }
.groupBy { (pos, _) ->
val (y, x) = pos
if (y % 2 == 0) x else y + 1
}
.values
.sumOf { edges ->
val line = buildList {
edges.mapTo(this) { (pos, dir) -> pos.first + pos.second to dir }
sortBy(Pair<Int, Boolean>::first)
}
line.indices.count {
line[it].second != line.getOrNull(it + 1)?.second ||
abs(line[it].first - line[it + 1].first) > 2
}
}
}

companion object {
private operator fun List<String>.get(pos: IntPair) = getOrNull(pos.first)?.getOrNull(pos.second)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ val days: List<Day> = listOf(
Day(9, ::Day9, Day9::part1, Day9::part2),
Day(10, ::Day10, Day10::part1, Day10::part2),
Day(11, ::Day11, Day11::part1, Day11::part2),
Day(12, ::Day12, Day12::part1, Day12::part2),
)

data class Day(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package com.github.ephemient.aoc2024

import kotlin.test.Test
import kotlin.test.assertEquals

class Day12Test {
@Test
fun part1() {
assertEquals(140, Day12(example1).part1())
assertEquals(772, Day12(example2).part1())
assertEquals(1930, Day12(example3).part1())
}

@Test
fun part2() {
// assertEquals(80, Day12(example1).part2())
// assertEquals(436, Day12(example2).part2())
// assertEquals(236, Day12(example4).part2())
assertEquals(368, Day12(example5).part2())
assertEquals(1206, Day12(example3).part2())
}

companion object {
private val example1 =
"""
|AAAA
|BBCD
|BBCC
|EEEC
|""".trimMargin()
private val example2 =
"""
|OOOOO
|OXOXO
|OOOOO
|OXOXO
|OOOOO
|""".trimMargin()
private val example3 =
"""
|RRRRIICCFF
|RRRRIICCCF
|VVRRRCCFFF
|VVRCCCJFFF
|VVVVCJJCFE
|VVIVCCJJEE
|VVIIICJJEE
|MIIIIIJJEE
|MIIISIJEEE
|MMMISSJEEE
|""".trimMargin()
private val example4 =
"""
|EEEEE
|EXXXX
|EEEEE
|EXXXX
|EEEEE
|""".trimMargin()
private val example5 =
"""
|AAAAAA
|AAABBA
|AAABBA
|ABBAAA
|ABBAAA
|AAAAAA
|""".trimMargin()
}
}

0 comments on commit 31ed7fe

Please sign in to comment.