Advent of Code 2023 day 8
12/08/2023, 5:00 AMMarcin Wisniowski
12/08/2023, 5:29 AMMarcin Wisniowski
12/08/2023, 5:30 AMMarcin Wisniowski
12/08/2023, 5:31 AMleastCommonMultiple
from previous years helped in this one!Jan Durovec
12/08/2023, 5:41 AMTimmy
12/08/2023, 5:55 AMbj0
12/08/2023, 5:55 AMbj0
12/08/2023, 5:56 AMInt
...Lidonis Calhau
12/08/2023, 5:57 AMSergei Petunin
12/08/2023, 5:58 AMlcm
function from last yearbj0
12/08/2023, 5:59 AMbj0
12/08/2023, 6:00 AMephemient
12/08/2023, 6:09 AMEndre Deak
12/08/2023, 6:15 AMJonathan Kolberg
12/08/2023, 6:15 AMJonathan Kolberg
12/08/2023, 6:16 AMephemient
12/08/2023, 6:16 AMJonathan Kolberg
12/08/2023, 6:18 AMEndre Deak
12/08/2023, 6:20 AMephemient
12/08/2023, 6:21 AMephemient
12/08/2023, 6:24 AMMichael Bรถiers
12/08/2023, 6:31 AMephemient
12/08/2023, 6:31 AMcheck
for that in my solution, https://github.com/ephemient/aoc2023/commit/0b791a71ea5c9ee00307fbe47dc41044ddc1825eMichael de Kaste
12/08/2023, 6:32 AMephemient
12/08/2023, 6:34 AMritesh
12/08/2023, 6:36 AMEndre Deak
12/08/2023, 6:36 AMMichael de Kaste
12/08/2023, 7:06 AMNorbert Kiesel
12/08/2023, 7:13 AMNorbert Kiesel
12/08/2023, 7:14 AMNeil Banman
12/08/2023, 7:15 AMNeil Banman
12/08/2023, 7:20 AMit turns out that (at least for my input) LCM wasn't necessary, the resulting path sizes were coprime.This was the case in last year's "LCM" problem too, Day 11.
Neil Banman
12/08/2023, 7:22 AMI'm afraid that this only works if the 1st node ending with Z on each path is the one where the loop will eventually stop.Like many on this thread, I had the same fear. But then I told myself that it's a day 8 and that wasn't very likely to be the case.
andriyo
12/08/2023, 7:25 AMgenerateSequence()
this time. and of course I've become master of `fold`ing. It's my favorite operation now ๐ I had to use it even to replicate count() since the count() doesn't work for our favorite data type Long
.
https://github.com/andriyo/advent-of-code-kotlin-2023/blob/main/src/Day08.ktLidonis Calhau
12/08/2023, 7:27 AMreduce(Long::times)
is easier that fold
andriyo
12/08/2023, 7:29 AMMichael de Kaste
12/08/2023, 7:30 AM56643 -> (56643)
2412 -> (2412)
12345 -> (12345)
9862 -> (9862)
32521 -> (32521)
53212 -> (53212)
instead of the expected
56643 -> repeat(2541, 2352, 1634, 56, 8756)
2412 -> repeat(2542, 2381, 2634, 34, 241)
12345 -> repeat(1541, 2951, 3634, 81, 1252)
9862 -> repeat(7541, 2371, 4634, 97, 1251)
32521 -> repeat(2531, 7351, 5634, 23, 1257)
53212 -> repeat(2581, 4351, 6634, 13, 99)
I'm pretty mad at myself because the follow algorithm will never find 18024643846273 in a reasonable time...Lidonis Calhau
12/08/2023, 7:32 AMandriyo
12/08/2023, 7:35 AMfold
is easier to fall back on though since it's pretty much does everythingphldavies
12/08/2023, 7:51 AMlcm
function ready to hand certainly helps!
I did try brute-forcing it while I modified the code to use LCM but my code change unsurprisingly got there first ๐Dan Fingal-Surma
12/08/2023, 7:54 AMNorbert Kiesel
12/08/2023, 7:59 AMcheck(firstEnd == node) { "Not at same node" }
check(firstCount.rem(count - firstCount) == 0L) { "Not a valid cycle length" }
phldavies
12/08/2023, 7:59 AMvar
Performance is worse than mutable ๐
year 2023 day 8 part 1
Default took 801.796us (1.00x): 16343
Immutable took 983.66us (1.23x): 16343
year 2023 day 8 part 2
Default took 2.757020ms (1.00x): 15299095336639
Immutable took 4.056470ms (1.47x): 15299095336639
Dan Fingal-Surma
12/08/2023, 8:00 AMphldavies
12/08/2023, 8:04 AMiterator
the way you have is consuming a mutable data type. Running your sequence twice would fail due to it relying on uncontrolled (from it's perspective) state. You may want to look into runningFold
to avoid this ๐Dan Fingal-Surma
12/08/2023, 8:05 AMDan Fingal-Surma
12/08/2023, 8:06 AMNorbert Kiesel
12/08/2023, 8:08 AMreturn startNodes.map { steps(it) }.reduce { acc, c -> lcm(acc, c) }
to compute the lcmDan Fingal-Surma
12/08/2023, 8:08 AMtailrec fun gcd(x: Long, y: Long): Long = if (y == 0L) x else gcd(y, x % y)
fun lcm(x: Long, y: Long): Long = (x * y) / gcd(x, y)
Dan Fingal-Surma
12/08/2023, 8:08 AMJakub Gwรณลบdลบ
12/08/2023, 8:09 AMNorbert Kiesel
12/08/2023, 8:09 AMx / gcd(x, y) * y
to reduce the risk of overflowNeil Banman
12/08/2023, 8:10 AMNeil Banman
12/08/2023, 8:10 AMvar
befouling my code.ephemient
12/08/2023, 8:14 AMgcd
ephemient
12/08/2023, 8:15 AMNeil Banman
12/08/2023, 8:17 AMvars
are left and right indexes for finding the numbers in the parts bin. There's an easy functional substitution but I think the while loop incrementer is clearer. So I guess they'll stay.Dan Fingal-Surma
12/08/2023, 8:19 AMDan Fingal-Surma
12/08/2023, 8:20 AMnvbahool
12/08/2023, 8:20 AMDan Fingal-Surma
12/08/2023, 8:24 AMDan Fingal-Surma
12/08/2023, 8:30 AMephemient
12/08/2023, 8:39 AMephemient
12/08/2023, 8:39 AMandriyo
12/08/2023, 8:42 AMrunningFold
but thanks for suggestion!andriyo
12/08/2023, 8:50 AMvar
or recursive functions (just because) so, behold: the sequence
based implementation of LCM!
I feel like sequenceGenerator is like writing a tail recursive function without writing a tail recursive function. I know, i know it's overkill but just for funphldavies
12/08/2023, 8:50 AMDeepRecursiveFunction
andriyo
12/08/2023, 8:54 AMJaap Beetstra
12/08/2023, 9:24 AML
11A = (11B, 11B)
11B = (11C, 11C)
11C = (11D, 11D)
11D = (11Z, 11Z)
11Z = (11B, 11B)
22A = (22B, 22B)
22B = (22C, 22C)
22C = (22D, 22D)
22D = (22E, 22E)
22E = (22Z, 22Z)
22Z = (23Z, 23Z)
23Z = (22C, 22C)
Tomasz Linkowski
12/08/2023, 9:26 AMSergei Petunin
12/08/2023, 9:28 AMTomasz Linkowski
12/08/2023, 9:32 AMrunningFold
very useful for making it immutable ๐
fun DesertMap.countSteps(startBranch: Branch, endNodeCondition: (String) -> Boolean): Int =
generateSequence { turns }.flatten()
.runningFold(startBranch, this::nextBranch)
.takeWhile { branch -> !endNodeCondition(branch.node) }
.count()
kingsley
12/08/2023, 11:06 AMphldavies
12/08/2023, 11:32 AMgenerateSequence { turns }.flatten()
to my sequence { while(true) yieldAll(turns) }
ephemient
12/08/2023, 11:35 AMgenerateSequence {}.flatMap { turns }
but that probably reads more confusingly than either of the above ๐Davio
12/08/2023, 12:00 PMDavio
12/08/2023, 12:01 PMreturn elements.filter { it.isStartElement }.map {
getCycleLength(it)
}.reduce { acc, l ->
lcm(acc, l)
}
But I'm sure there are inputs for which it would not work, oh well ๐Davio
12/08/2023, 12:01 PMDavio
12/08/2023, 12:06 PMTomasz Linkowski
12/08/2023, 12:12 PMrunningFold
because someone here made me realize that the condition can be checked after the last turn only:
fun DesertMap.countSteps(startBranch: Branch, endNodeCondition: (String) -> Boolean): Int =
generateSequence(startBranch) { branch -> turns.fold(branch, this::nextBranch) }
.takeWhile { branch -> !endNodeCondition(branch.node) }
.count() * turns.size
Jaap Beetstra
12/08/2023, 12:13 PM0: [11A, 22A] 1: [11B, 22B] 2: [11C, 22C] 3: [11D, 22D]
4: [11Z, 22E] 5: [11B, 22Z] 6: [11C, 23Z] 7: [11D, 22C]
8: [11Z, 22D] 9: [11B, 22E] 10: [11C, 22Z] 11: [11D, 23Z]
12: [11Z, 22C] 13: [11B, 22D] 14: [11C, 22E] 15: [11D, 22Z]
16: [11Z, 23Z]
Vamsi
12/08/2023, 12:14 PMTomasz Linkowski
12/08/2023, 12:18 PMDavio
12/08/2023, 12:21 PMJaap Beetstra
12/08/2023, 12:21 PMJaap Beetstra
12/08/2023, 12:23 PMA
is equal to the number ending in Z
. My test data doesn't match that part, but I think it's not enough to exclude the situationJaap Beetstra
12/08/2023, 12:24 PMAndreu
12/08/2023, 12:29 PMTomasz Linkowski
12/08/2023, 12:47 PML
11A = (11B, 11B)
11B = (11C, 11C)
11C = (11D, 11D)
11D = (11Z, 11Z)
11Z = (11B, 11B)
22A = (22B, 22B)
22B = (22C, 22C)
22C = (22D, 22D)
22D = (22E, 22E)
22E = (22Z, 22Z)
22Z = (22B, 22B)
which gives this result (at step 16 we have 22B so we have to iterate further till step 20):
0: [11A, 22A] 1: [11B, 22B] 2: [11C, 22C] 3: [11D, 22D]
4: [11Z, 22E] 5: [11B, 22Z] 6: [11C, 22B] 7: [11D, 22C]
8: [11Z, 22D] 9: [11B, 22E] 10: [11C, 22Z] 11: [11D, 22B]
12: [11Z, 22C] 13: [11B, 22D] 14: [11C, 22E] 15: [11D, 22Z]
16: [11Z, 22B] 17: [11B, 22C] 18: [11C, 22D] 19: [11D, 22E]
20: [11Z, 22Z]
Jaap Beetstra
12/08/2023, 12:51 PMLR
11A = (11B, 11C)
11B = (11C, 11D)
11C = (11D, 11A)
11D = (11Z, 11A)
11Z = (11B, 11D)
22A = (22B, 22B)
22B = (22C, 22C)
22C = (22D, 22D)
22D = (22Z, 22Z)
22Z = (22A, 22B)
kqr
12/08/2023, 12:51 PMYou had the camel follow the instructions, but you've barely left your starting position
PoisonedYouth
12/08/2023, 12:52 PMTomasz Linkowski
12/08/2023, 12:59 PMCharles Flynn
12/08/2023, 1:19 PMephemient
12/08/2023, 1:39 PMephemient
12/08/2023, 1:40 PMTolly Kulczycki
12/08/2023, 2:42 PMCharles Flynn
12/08/2023, 4:01 PMephemient
12/08/2023, 4:04 PMephemient
12/08/2023, 4:05 PMMarcin Wisniowski
12/08/2023, 5:00 PMMichael de Kaste
12/08/2023, 5:20 PMNeil Banman
12/08/2023, 5:30 PMNeil Banman
12/08/2023, 5:30 PMandriyo
12/08/2023, 6:01 PMNeil Banman
12/08/2023, 6:02 PMephemient
12/08/2023, 6:04 PM[0-9A-Z]{3}
quite like thatPaul Woitaschek
12/08/2023, 6:21 PMjoney
12/08/2023, 6:37 PMandriyo
12/08/2023, 6:54 PMgenerateSequence { "ABC".toList() }.flatten().map { it.println() }.count()
should be burned at the stake for witchcraft ๐ still can't get my head around how it works exactly to produce infinite sequence without stack overflowPaul Woitaschek
12/08/2023, 7:10 PMandriyo
12/08/2023, 7:17 PMGrzegorz Aniol
12/08/2023, 7:18 PM