@ace@lemmy.ananace.dev avatar

ace

@ace@lemmy.ananace.dev

Just another Swedish programming sysadmin person.
Coffee is always the answer.

And beware my spaghet.

This profile is from a federated server and may be incomplete. Browse more on the original instance.

Make Inkscape installed through Flatpak callable in the terminal as 'inkscape'?

I have a Python-package that calls Inkscape as part of a conversion process. I have it installed, but through Flatpak. This means that calling inkscape does not work in the terminal, but rather flatpak run org.inkscape.Inkscape. I need the package to be able to call it as inkscape....

ace, (edited )
@ace@lemmy.ananace.dev avatar

Flatpak already creates executable wrappers for all applications as part of regular installs, though they’re by default named as the full package name.

For when inkscape has been installed into the system-wide Flatpak installation, you could simply symlink it like; ln -s /var/lib/flatpak/exports/bin/org.inkscape.Inkscape /usr/local/bin/inkscape

For the user-local installation, the exported runnable is in ~/.local/share/flatpak/exports/bin instead.

Gentoo goes Binary (packages) (www.gentoo.org)

To speed up working with slow hardware and for overall convenience, we’re now also offering binary packages for download and direct installation! For most architectures, this is limited to the core system and weekly updates - not so for amd64 and arm64 however. There we’ve got a stunning >20 GByte of packages on our mirrors,...

ace,
@ace@lemmy.ananace.dev avatar

The official binhost project has been an experimental thing until now, I’ve personally been using it for the year on multiple machines, but it’s not been something that you can just enable. And it’s definitely not been something that’s come pre-prepared in the stage 3.

ace,
@ace@lemmy.ananace.dev avatar

“We interrupt your regular scheduling to bring you this additional bit of Factorio hype.”

ace,
@ace@lemmy.ananace.dev avatar

I can already imagine so many fun ways this could be used.

ace,
@ace@lemmy.ananace.dev avatar

A lot of that data doesn’t actually exist, ostree hardlinks data blobs internally, so the actual size on disk is much smaller than most disk usage tools will show.

ace,
@ace@lemmy.ananace.dev avatar

Flatpak uses OSTree - a git-like system for storing and transferring binary data (commonly referred to as ‘blobs’), and that system works by addressing such blobs by hashes of their content, using Linux hardlinks (multiple inodes all referring to the same disk blocks) to refer to the same data everywhere it’s used.

So basically, whenever Flatpak tells OSTree to download something, it will only ever store only copy of that same object (.so-file, binary, font, etc), regardless of how many times it’s used by applications across the install.
Note that this only happens internally in the OSTree repo - i.e. /var/lib/flatpak or ~/.local/share/flatpak, so if you have multiple separate Flatpak installations on your system then they can’t automagically de-duplicate data between each other.

What is the difference between a room ID with a ! or a # from another server's perspective (and other questions)?

What is the difference between a room id of !example391:server.com and #example:server.com for a user at server2.com? Is there also a way to assign an internal address starting with a #? Everytime I try to make it internal only, it becomes external at the same time. I also noticed that Element allows me to assign custom room...

ace, (edited )
@ace@lemmy.ananace.dev avatar

The # is a room alias, only ! denotes a room ID.

Room IDs are the main identifier for a room, while one or more aliases can also be assigned to it for discovery purposes.
Any server can assign aliases - and therefore also serve the room discovery, but only if the room admins allow them.

Using the Matrix HQ room as an example; #matrix:matrix.org is the canonical alias for the room, mapping to !OGEhHVWSdvArJzumhm:matrix.org.
If you want to join the room, you either need to know the ID and some information on which servers are currently part of the room, or you need to know a room alias - which can be used to query the server owning it in order to receive the information on the room and how to join it.

For example; (%23 is the HTTP entity for #, since # would otherwise be handled as a client part of the URL)


<span style="color:#323232;">$ curl -q 'https://matrix.org/_matrix/client/v3/directory/room/%23matrix:matrix.org' | jq '.room_id, .servers[0,1]'
</span><span style="color:#323232;">"!OGEhHVWSdvArJzumhm:matrix.org"
</span><span style="color:#323232;">"matrix.org"
</span><span style="color:#323232;">"artemislena.eu"
</span>
ace,
@ace@lemmy.ananace.dev avatar

Valve did purchase the for-profit MoltenVK layer and had it open-sourced under the Khronos umbrella, so they’ve already been happy to provide people a Vulkan-on-Metal solution for those who want to support Apple without an entirely separate rendering engine.

ace,
@ace@lemmy.ananace.dev avatar

I’ve been personally using KDEs Itinerary app, but it might not be what you’re looking for

ace,
@ace@lemmy.ananace.dev avatar

The squeezing component in part 2 made this really interesting.

I had a thought on a naïve solution consisting of expanding the input grid, painting all the walked pipes, and then doing a flood fill from the outside of the expanded map. There are a lot cleverer ways to do it, but the idea stuck with me and so…

The code’s a bit of a mess, but I actually kind of like the result. It visualizes really well and still runs both parts in under 8 seconds, so it’s not even particularly slow considering how it does it.

E.g;
Picture of solution output

:::spoiler Ruby A snippet from the expansion/flood fill;


<span style="font-weight:bold;color:#a71d5d;">def </span><span style="font-weight:bold;color:#795da3;">flood_fill</span><span style="color:#323232;">(used: [])
</span><span style="color:#323232;">  new_dim </span><span style="font-weight:bold;color:#a71d5d;">= </span><span style="color:#323232;">@dim </span><span style="font-weight:bold;color:#a71d5d;">* </span><span style="color:#0086b3;">3
</span><span style="color:#323232;">  new_map </span><span style="font-weight:bold;color:#a71d5d;">= </span><span style="color:#62a35c;">Array</span><span style="color:#323232;">.</span><span style="font-weight:bold;color:#a71d5d;">new</span><span style="color:#323232;">(new_dim.size, </span><span style="color:#183691;">'.'</span><span style="color:#323232;">)
</span><span style="color:#323232;">
</span><span style="color:#323232;">  </span><span style="color:#62a35c;">puts </span><span style="color:#183691;">"Expanding #{</span><span style="color:#323232;">@dim</span><span style="color:#183691;">} to #{new_dim}, with #{used.size} visited pipes." </span><span style="font-weight:bold;color:#a71d5d;">if </span><span style="color:#323232;">$args.verbose
</span><span style="color:#323232;">
</span><span style="color:#323232;">  </span><span style="font-style:italic;color:#969896;"># Mark all real points as inside on the expanded map
</span><span style="color:#323232;">  (</span><span style="color:#0086b3;">0</span><span style="font-weight:bold;color:#a71d5d;">..</span><span style="color:#323232;">(@dim.y </span><span style="font-weight:bold;color:#a71d5d;">- </span><span style="color:#0086b3;">1</span><span style="color:#323232;">)).each </span><span style="font-weight:bold;color:#a71d5d;">do </span><span style="color:#323232;">|y|
</span><span style="color:#323232;">    (</span><span style="color:#0086b3;">0</span><span style="font-weight:bold;color:#a71d5d;">..</span><span style="color:#323232;">(@dim.x </span><span style="font-weight:bold;color:#a71d5d;">- </span><span style="color:#0086b3;">1</span><span style="color:#323232;">)).each </span><span style="font-weight:bold;color:#a71d5d;">do </span><span style="color:#323232;">|x|
</span><span style="color:#323232;">      expanded_point </span><span style="font-weight:bold;color:#a71d5d;">= </span><span style="color:#0086b3;">Point</span><span style="color:#323232;">.</span><span style="font-weight:bold;color:#a71d5d;">new</span><span style="color:#323232;"> x </span><span style="font-weight:bold;color:#a71d5d;">* </span><span style="color:#0086b3;">3 </span><span style="font-weight:bold;color:#a71d5d;">+ </span><span style="color:#0086b3;">1</span><span style="color:#323232;">, y </span><span style="font-weight:bold;color:#a71d5d;">* </span><span style="color:#0086b3;">3 </span><span style="font-weight:bold;color:#a71d5d;">+ </span><span style="color:#0086b3;">1
</span><span style="color:#323232;">      new_map[expanded_point.y </span><span style="font-weight:bold;color:#a71d5d;">*</span><span style="color:#323232;"> new_dim.x </span><span style="font-weight:bold;color:#a71d5d;">+</span><span style="color:#323232;"> expanded_point.x] </span><span style="font-weight:bold;color:#a71d5d;">= </span><span style="color:#183691;">'I'
</span><span style="color:#323232;">    </span><span style="font-weight:bold;color:#a71d5d;">end
</span><span style="color:#323232;">  </span><span style="font-weight:bold;color:#a71d5d;">end
</span><span style="color:#323232;">
</span><span style="color:#323232;">  </span><span style="font-style:italic;color:#969896;"># Paint all used pipes onto the expanded map
</span><span style="color:#323232;">  used.each </span><span style="font-weight:bold;color:#a71d5d;">do </span><span style="color:#323232;">|used_p|
</span><span style="color:#323232;">    expanded_point </span><span style="font-weight:bold;color:#a71d5d;">= </span><span style="color:#0086b3;">Point</span><span style="color:#323232;">.</span><span style="font-weight:bold;color:#a71d5d;">new</span><span style="color:#323232;"> used_p.x </span><span style="font-weight:bold;color:#a71d5d;">* </span><span style="color:#0086b3;">3 </span><span style="font-weight:bold;color:#a71d5d;">+ </span><span style="color:#0086b3;">1</span><span style="color:#323232;">, used_p.y </span><span style="font-weight:bold;color:#a71d5d;">* </span><span style="color:#0086b3;">3 </span><span style="font-weight:bold;color:#a71d5d;">+ </span><span style="color:#0086b3;">1
</span><span style="color:#323232;">
</span><span style="color:#323232;">    new_map[expanded_point.y </span><span style="font-weight:bold;color:#a71d5d;">*</span><span style="color:#323232;"> new_dim.x </span><span style="font-weight:bold;color:#a71d5d;">+</span><span style="color:#323232;"> expanded_point.x] </span><span style="font-weight:bold;color:#a71d5d;">= </span><span style="color:#183691;">'#'
</span><span style="color:#323232;">    offsets </span><span style="font-weight:bold;color:#a71d5d;">= </span><span style="color:#323232;">@links[used_p].connections
</span><span style="color:#323232;">    offsets.shift
</span><span style="color:#323232;">
</span><span style="color:#323232;">    offsets.each </span><span style="font-weight:bold;color:#a71d5d;">do </span><span style="color:#323232;">|offs|
</span><span style="color:#323232;">      diff </span><span style="font-weight:bold;color:#a71d5d;">=</span><span style="color:#323232;"> offs </span><span style="font-weight:bold;color:#a71d5d;">-</span><span style="color:#323232;"> used_p
</span><span style="color:#323232;">      new_map[(expanded_point.y </span><span style="font-weight:bold;color:#a71d5d;">+</span><span style="color:#323232;"> diff.y) </span><span style="font-weight:bold;color:#a71d5d;">*</span><span style="color:#323232;"> new_dim.x </span><span style="font-weight:bold;color:#a71d5d;">+ </span><span style="color:#323232;">(expanded_point.x </span><span style="font-weight:bold;color:#a71d5d;">+</span><span style="color:#323232;"> diff.x)] </span><span style="font-weight:bold;color:#a71d5d;">= </span><span style="color:#183691;">'#'
</span><span style="color:#323232;">    </span><span style="font-weight:bold;color:#a71d5d;">end
</span><span style="color:#323232;">  </span><span style="font-weight:bold;color:#a71d5d;">end
</span><span style="color:#323232;">
</span><span style="color:#323232;">  </span><span style="color:#62a35c;">puts </span><span style="color:#183691;">"Flooding expanded map..." </span><span style="font-weight:bold;color:#a71d5d;">if </span><span style="color:#323232;">$args.verbose
</span><span style="color:#323232;">
</span><span style="color:#323232;">  </span><span style="font-style:italic;color:#969896;"># Flood fill the expanded map from the top-left corner
</span><span style="color:#323232;">  to_visit </span><span style="font-weight:bold;color:#a71d5d;">= </span><span style="color:#323232;">[</span><span style="color:#0086b3;">Point</span><span style="color:#323232;">.</span><span style="font-weight:bold;color:#a71d5d;">new</span><span style="color:#323232;">(</span><span style="color:#0086b3;">0</span><span style="color:#323232;">, </span><span style="color:#0086b3;">0</span><span style="color:#323232;">)]
</span><span style="color:#323232;">  </span><span style="font-weight:bold;color:#a71d5d;">until</span><span style="color:#323232;"> to_visit.empty?
</span><span style="color:#323232;">    at </span><span style="font-weight:bold;color:#a71d5d;">=</span><span style="color:#323232;"> to_visit.shift
</span><span style="color:#323232;">    new_map[at.y </span><span style="font-weight:bold;color:#a71d5d;">*</span><span style="color:#323232;"> new_dim.x </span><span style="font-weight:bold;color:#a71d5d;">+</span><span style="color:#323232;"> at.x] </span><span style="font-weight:bold;color:#a71d5d;">= </span><span style="color:#183691;">' '
</span><span style="color:#323232;">
</span><span style="color:#323232;">    (</span><span style="font-weight:bold;color:#a71d5d;">-</span><span style="color:#0086b3;">1</span><span style="font-weight:bold;color:#a71d5d;">..</span><span style="color:#0086b3;">1</span><span style="color:#323232;">).each </span><span style="font-weight:bold;color:#a71d5d;">do </span><span style="color:#323232;">|off_y|
</span><span style="color:#323232;">      (</span><span style="font-weight:bold;color:#a71d5d;">-</span><span style="color:#0086b3;">1</span><span style="font-weight:bold;color:#a71d5d;">..</span><span style="color:#0086b3;">1</span><span style="color:#323232;">).each </span><span style="font-weight:bold;color:#a71d5d;">do </span><span style="color:#323232;">|off_x|
</span><span style="color:#323232;">        </span><span style="font-weight:bold;color:#a71d5d;">next if </span><span style="color:#323232;">(off_x.zero? </span><span style="font-weight:bold;color:#a71d5d;">&</span><span style="color:#323232;">amp;</span><span style="font-weight:bold;color:#a71d5d;">&</span><span style="color:#323232;">amp; off_y.zero?) </span><span style="font-weight:bold;color:#a71d5d;">|| !</span><span style="color:#323232;">(off_x.zero? </span><span style="font-weight:bold;color:#a71d5d;">||</span><span style="color:#323232;"> off_y.zero?)
</span><span style="color:#323232;">
</span><span style="color:#323232;">        off_p </span><span style="font-weight:bold;color:#a71d5d;">=</span><span style="color:#323232;"> at </span><span style="font-weight:bold;color:#a71d5d;">+ </span><span style="color:#0086b3;">Point</span><span style="color:#323232;">.</span><span style="font-weight:bold;color:#a71d5d;">new</span><span style="color:#323232;">(off_x, off_y)
</span><span style="color:#323232;">        </span><span style="font-weight:bold;color:#a71d5d;">next if</span><span style="color:#323232;"> off_p.x </span><span style="font-weight:bold;color:#a71d5d;">&</span><span style="color:#323232;">lt; </span><span style="color:#0086b3;">0 </span><span style="font-weight:bold;color:#a71d5d;">||</span><span style="color:#323232;"> off_p.y </span><span style="font-weight:bold;color:#a71d5d;">&</span><span style="color:#323232;">lt; </span><span style="color:#0086b3;">0</span><span style="color:#323232;"> 
</span><span style="color:#323232;">          </span><span style="font-weight:bold;color:#a71d5d;">||</span><span style="color:#323232;"> off_p.x </span><span style="font-weight:bold;color:#a71d5d;">>=</span><span style="color:#323232;"> new_dim.x </span><span style="font-weight:bold;color:#a71d5d;">||</span><span style="color:#323232;"> off_p.y </span><span style="font-weight:bold;color:#a71d5d;">>=</span><span style="color:#323232;"> new_dim.y 
</span><span style="color:#323232;">          </span><span style="font-weight:bold;color:#a71d5d;">||</span><span style="color:#323232;"> to_visit.</span><span style="color:#62a35c;">include?</span><span style="color:#323232;">(off_p)
</span><span style="color:#323232;">
</span><span style="color:#323232;">        val </span><span style="font-weight:bold;color:#a71d5d;">=</span><span style="color:#323232;"> new_map[off_p.y </span><span style="font-weight:bold;color:#a71d5d;">*</span><span style="color:#323232;"> new_dim.x </span><span style="font-weight:bold;color:#a71d5d;">+</span><span style="color:#323232;"> off_p.x]
</span><span style="color:#323232;">        </span><span style="font-weight:bold;color:#a71d5d;">next unless </span><span style="color:#183691;">%w[. I]</span><span style="color:#323232;">.</span><span style="color:#62a35c;">include?</span><span style="color:#323232;"> val
</span><span style="color:#323232;">
</span><span style="color:#323232;">        to_visit </span><span style="font-weight:bold;color:#a71d5d;">&</span><span style="color:#323232;">lt;</span><span style="font-weight:bold;color:#a71d5d;">&</span><span style="color:#323232;">lt; off_p
</span><span style="color:#323232;">      </span><span style="font-weight:bold;color:#a71d5d;">end
</span><span style="color:#323232;">    </span><span style="font-weight:bold;color:#a71d5d;">end
</span><span style="color:#323232;">  </span><span style="font-weight:bold;color:#a71d5d;">end
</span><span style="color:#323232;">
</span><span style="color:#323232;">  </span><span style="font-weight:bold;color:#a71d5d;">return</span><span style="color:#323232;"> new_map, new_dim
</span><span style="font-weight:bold;color:#a71d5d;">end
</span>

:::

ace,
@ace@lemmy.ananace.dev avatar

With the fully expanded map for the actual input it ends up working a 420x420 tile grid, and it has to do both value lookups as well as mutations into that, alongside inclusion testing for the search array (which could probably be made cheaper by building it as a set). It ends up somewhat expensive simply on the number of tests.

The sample I posted the picture of runs in 0.07s wall time though.

ace, (edited )
@ace@lemmy.ananace.dev avatar

There’s a next if […] to_visit.include?(off_p), and I also only visit points that haven’t been flood filled yet (next unless %w[. I].include? val), so there shouldn’t be any superfluous testing going on.

Went back and did a quick test of thing, and yep, converting the to_visit array to a set pulls execution time down to ~600ms. But the code becomes much messier.
Going to move the mutation of the map down to the point where I pick a point for visitation instead, so I can re-use the check for already flooded tiles instead.

ace,
@ace@lemmy.ananace.dev avatar

The naïve and unoptimized version ran in under 4 seconds for me, that’s nowhere near “Time to knuckle down and actually optimize this” territory.

ace,
@ace@lemmy.ananace.dev avatar

Well, this one ended up being a really nice and terse solution when done naïvely, here with a trimmed snippet from my simple solution;

:::spoiler Ruby


<span style="color:#62a35c;">puts </span><span style="color:#183691;">"Part 1:"</span><span style="color:#323232;">, @races.map </span><span style="font-weight:bold;color:#a71d5d;">do </span><span style="color:#323232;">|race|
</span><span style="color:#323232;">  (</span><span style="color:#0086b3;">0</span><span style="font-weight:bold;color:#a71d5d;">..</span><span style="color:#323232;">race[</span><span style="color:#0086b3;">:time</span><span style="color:#323232;">]).count { |press_dur| press_dur </span><span style="font-weight:bold;color:#a71d5d;">* </span><span style="color:#323232;">(race[</span><span style="color:#0086b3;">:time</span><span style="color:#323232;">] </span><span style="font-weight:bold;color:#a71d5d;">-</span><span style="color:#323232;"> press_dur) </span><span style="font-weight:bold;color:#a71d5d;">></span><span style="color:#323232;"> race[</span><span style="color:#0086b3;">:distance</span><span style="color:#323232;">] }
</span><span style="font-weight:bold;color:#a71d5d;">end</span><span style="color:#323232;">.inject(</span><span style="color:#0086b3;">:*</span><span style="color:#323232;">)
</span><span style="color:#323232;">
</span><span style="color:#323232;">full_race_time </span><span style="font-weight:bold;color:#a71d5d;">= </span><span style="color:#323232;">@races.map { |r| r[</span><span style="color:#0086b3;">:time</span><span style="color:#323232;">].</span><span style="color:#62a35c;">to_s </span><span style="color:#323232;">}.join.</span><span style="color:#62a35c;">to_i
</span><span style="color:#323232;">full_race_dist </span><span style="font-weight:bold;color:#a71d5d;">= </span><span style="color:#323232;">@races.map { |r| r[</span><span style="color:#0086b3;">:distance</span><span style="color:#323232;">].</span><span style="color:#62a35c;">to_s </span><span style="color:#323232;">}.join.</span><span style="color:#62a35c;">to_i
</span><span style="color:#323232;">
</span><span style="color:#62a35c;">puts </span><span style="color:#183691;">"Part 2:"</span><span style="color:#323232;">, (</span><span style="color:#0086b3;">0</span><span style="font-weight:bold;color:#a71d5d;">..</span><span style="color:#323232;">full_race_time).count { |press_dur| press_dur </span><span style="font-weight:bold;color:#a71d5d;">* </span><span style="color:#323232;">(full_race_time </span><span style="font-weight:bold;color:#a71d5d;">-</span><span style="color:#323232;"> press_dur) </span><span style="font-weight:bold;color:#a71d5d;">></span><span style="color:#323232;"> full_race_dist }
</span>

:::

ace,
@ace@lemmy.ananace.dev avatar

Writing and debugging 4D code is… interesting.

When your code can’t just run forwards and backwards, but also left and right, up and down, and even inwards and outwards.

ace,
@ace@lemmy.ananace.dev avatar

“It’s a ndiswrapper miracle!” - a statement only uttered by the completely deranged.

ace,
@ace@lemmy.ananace.dev avatar

Not really, WSL seems like it was mainly supposed to stop people leaping ship to be able to develop Node without the horribly painful Windows JS experience. And wouldn’t you know it, Microsoft has been making their own JavaScript language in Typescript.

ace,
@ace@lemmy.ananace.dev avatar

Let me tell you about Bumblebee and their issue , though that one’s even worse seeing as installing system packages are done as root.

(Their install/update commands included rm -rf /usr /lib/nvidia-current/xorg/xorg)

  • All
  • Subscribed
  • Moderated
  • Favorites
  • provamag3
  • kavyap
  • DreamBathrooms
  • osvaldo12
  • magazineikmin
  • InstantRegret
  • everett
  • Youngstown
  • ngwrru68w68
  • slotface
  • rosin
  • GTA5RPClips
  • tester
  • PowerRangers
  • anitta
  • thenastyranch
  • mdbf
  • ethstaker
  • cisconetworking
  • Durango
  • vwfavf
  • normalnudes
  • tacticalgear
  • khanakhh
  • modclub
  • cubers
  • Leos
  • megavids
  • All magazines