• 14 Posts
  • 246 Comments
Joined 2 years ago
cake
Cake day: June 17th, 2023

help-circle

  • 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.


  • Kotlin

    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.

    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
        }
    }
    



  • This program is a client for the very solid Tvheadend TV streaming server. Tvheadend supports pretty much any source you can think of, but is a little more complicated to setup.

    Tvheadend is a selfhosted service meant to be run on your own server with your own TV dongles / IPTV channels / etc.

    If you only want to watch TV on your PC, doing so with something like Kodi is probably a better idea, as Kodi also supports USB tuners and is simpler to setup (doesn’t require a separate server).


  • 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.




  • You can absolutely re-encode h265 video, but you can’t do it losslessly. In the end, it’s always a balance between quality and filesize.

    I decided for myself, that 1080p30 crf28 h265 is good enough for home video, which lead to a 50% to 80% storage space reduction on videos from my phone.

    If you don’t obsess over quality, I would highly recommend just messing around with ffmpeg a little bit and decide how much quality you’re willing to lose in order to save disk space. When you’re happy with your settings, you can either use ffmpeg itself or some fancy batch program like Tdarr to transcode all (or parts of) your video library.

    My goto command is:
    for file in *.mp4; do ffmpeg -i "$file" -movflags use_metadata_tags -map_metadata 0 -vcodec libx265 -crf 28 -vf scale=1920:-1 -r 30 "${file%.*}_transcoded.mp4"; done




  • My personal gripe with mobile Firefox is searching by using the address bar.

    I have had countless times where I put in my search prompt, followed by pressing the little X all the way on the right and thus clearing the address bar. My brain just really expects an enter button to be there.

    I think my current record is entering a search term and then clearing it literally directly 3 times in a row, getting more and more confused each time.







  • eco_gametoich_iel@feddit.orgich👴🏿🏫 iel
    link
    fedilink
    arrow-up
    1
    ·
    5 months ago

    Bei uns werden die knallhart eingehalten. Das ist dann so nen ‘boa ja taktisch gesehen wäre das perfekt, aber ich darf dich erst in 8 Runden wieder angreifen’. So bilden sich dann ganz zügig die 2 Großmächte die alle anderen platt machen.


  • Indeed, they all use UFS 3.1 (so does the 128 GB Galaxy S23 though). I have never looked at storage type and my Pixel 6 doesn’t feel slow in any way.

    I have no idea what you mean with the camera, it is one of the best Android cameras out there. This is also true when running Graphene OS, as long as you download the ‘Pixel Camera’ app from either the Google Play store or APK sites (must download as an APK bundle then!).


  • AFAIK you nailed the differences between NewPipe and NewPipeX.

    As for FairEmail, I’ve used it for well over a year without paying and it’s been great (I plan on buying the pro version soon). It has kind of a pay what you want model, technically you can unlock all features for literally 10 cents.

    I’m not that knowledgeable on security for hosting services with external access either, I’m sure there are some great YouTube videos out there.
    A Raspberry Pi should be perfectly fine for hosting something like Seafile or Nextcloud though (Nextcloud might be a pain in the butt to host).

    DP altmode means being able to output HDMI over your phone’s USB-C port, the Pixels are famous for missing that feature. But I believe from Pixel 8 onwards it was added again, if this is important for you you should do your own research on it though.














Moderates