I find the Jellyfin webapp a pretty bad experience on mobile, compared to FinDroid.
I really like the webapp on my LG webOS TV (especially good with the Magic Remote) though.
So I guess it kind of depends on the platform.
I find the Jellyfin webapp a pretty bad experience on mobile, compared to FinDroid.
I really like the webapp on my LG webOS TV (especially good with the Magic Remote) though.
So I guess it kind of depends on the platform.
Jellyfin did some work on integrating the Skip Intros plugin a lot better, AFAIK you just have to enable it once on your server and then once in the settings of all Jellyfin web players.
As for apps, there are some good native third party apps which I mentioned here.
Was this with the first party Jellyfin app or with Swiftfin?
If it was with the first party app, I'd definitely recommend giving Swiftfin a try.
Jellyfin has native apps for Android, Android TV and iOS.
Does Plex offer native apps (that aren't just stripped down browsers) for more platforms?
AFAIK you can enable the snapcast server and then use an app like SnapCast to stream to your mobile devices.
I also really liked day 17, because at one point the solution for part 2 just clicked and now it makes so much sense.
I think my favorite was the full adder on day 24. Even though I only solved part 2 manually, it was still a lot of fun to reverse an actual full adder and get familiar with all the required logic gates.
I also solved part2 manually today, by outputting the correct addition and program output in binary and then reversing the path for all wrong outputs.
Then I just had to compare that to the formulas for a full adder and I found my swaps pretty quickly that way.
I did all of this in Kotlin and on paper, with a handy helper method to construct the paths.
It's at the very bottom of this file on Github.
I suspect that comparing the bits and then comparing the paths to the full adder formulas can also be done 'automatically' decently easily, but I was too lazy to implement that today.
Part1 was pretty simple, just check all neighbors of a node for overlap, then filter out triples which don't have nodes beginning with 't'.
For part2, I seem to have picked a completely different strategy to everyone else. I was a bit lost, then just boldly assumed, that if I take overlap of all triples with 1 equal node, I might be able to find the answer that way. To my surprise, this worked for my input. I'd be very curious to know if I just got lucky or if the puzzle is designed to work with this approach.
The full code is also on GitHub.
::: spoiler Solution
class Day23 : Puzzle {
private val connections = ArrayList<Pair<String, String>>()
private val tripleCache = HashSet<Triple<String, String, String>>()
override fun readFile() {
val input = readInputFromFile("src/main/resources/day23.txt")
for (line in input.lines()) {
val parts = line.split("-")
connections.add(Pair(parts[0], parts[1]))
}
}
override fun solvePartOne(): String {
val triples = getConnectionTriples(connections)
tripleCache.addAll(triples) // for part 2
val res = triples.count { it.first.startsWith("t") || it.second.startsWith("t") || it.third.startsWith("t") }
return res.toString()
}
private fun getConnectionTriples(connectionList: List<Pair<String, String>>): List<Triple<String, String, String>> {
val triples = ArrayList<Triple<String, String, String>>()
for (connection in connectionList) {
val connectionListTemp = getAllConnections(connection.first, connectionList)
for (i in connectionListTemp.indices) {
for (j in i + 1 until connectionListTemp.size) {
val con1 = connectionListTemp[i]
val con2 = connectionListTemp[j]
if (Pair(con1, con2) in connectionList || Pair(con2, con1) in connectionList) {
val tripleList = mutableListOf(connection.first, con1, con2)
tripleList.sort()
triples.add(Triple(tripleList[0], tripleList[1], tripleList[2]))
}
}
}
}
return triples.distinct()
}
private fun getAllConnections(connection: String, connectionList: List<Pair<String, String>>): List<String> {
val res = HashSet<String>()
for (entry in connectionList) {
when (connection) {
entry.first -> res.add(entry.second)
entry.second -> res.add(entry.first)
}
}
return res.toList()
}
override fun solvePartTwo(): String {
val pools = getPools(connections)
println(pools)
val res = pools.maxByOrNull { it.size }!!
return res.joinToString(",")
}
// will get all pools with a minimum size of 4
// this method makes some naive assumptions, but works for the example and my puzzle input
private fun getPools(connectionList: List<Pair<String, String>>): List<List<String>> {
val pools = ArrayList<List<String>>()
val triples = tripleCache
val nodes = connectionList.map { listOf(it.first, it.second) }.flatten().toHashSet()
for (node in nodes) {
val contenders = triples.filter { it.first == node || it.second == node || it.third == node }
if (contenders.size < 2) continue // expect the minimum result to be 4, for efficiency
// if *all* nodes within *all* triples are interconnected, add to pool
// this may not work for all inputs!
val contenderList = contenders.map { listOf(it.first, it.second, it.third) }.flatten().distinct()
if (checkAllConnections(contenderList, connectionList)) {
pools.add(contenderList.sorted())
}
}
return pools.distinct()
}
private fun checkAllConnections(pool: List<String>, connectionList: List<Pair<String, String>>): Boolean {
for (i in pool.indices) {
for (j in i + 1 until pool.size) {
val con1 = pool[i]
val con2 = pool[j]
if (Pair(con1, con2) !in connectionList && Pair(con2, con1) !in connectionList) {
return false
}
}
}
return true
}
}
I did try that at first, but it didn't really work the way I wanted it to. That's probably also because our implementation from school was a bit odd.
I was pretty neutral towards Ubuntu, up until an automatic system update removed my deb Firefox and replaced it with the snap version, even though I specifically set the apt repo to a higher priority.
The entire reason I left Windows is because I don't want (for example) Edge shoved down my throat after every update, and yet Ubuntu has gone and done the exact same thing with snaps.
After literal hours of fighting, the only solution I found was to fully disable automatic updates. With Pop OS I have all the benefits of Ubuntu, but I also get a company (System76) that does cool stuff and doesn't try shoving snaps down my throat.
I also use Posteo, one thing to note though is that Posteo doesn't (and probably won't any time soon) support custom domains. If that doesn't bother you, it's a great choice.
The other alternative I found during my research, which doesn't have that limitation, is mailbox.org.
You actually can still use it, there's some folks on reddit trying their best to keep it going. App support is very poor though.