Bubble sort doesn't click for me easily. I think it's because the terminating condition seems uglier than Selection sort or Insertion sort. I always have a little voice in the back of my mind, "Is this outer loop guaranteed to terminate?"
1,498 karma · joined September 21, 2019
Bubble sort doesn't click for me easily. I think it's because the terminating condition seems uglier than Selection sort or Insertion sort. I always have a little voice in the back of my mind, "Is this outer loop guaranteed to terminate?"
Both Insertion sort and Bubble sort are O(N^2). Both are stable sorts. Insertion sort consumes only about 10-20 bytes more flash memory than Bubble sort. It's hard to think of situations where Bubble sort would be preferred over Insertion sort.
Shell sort is vastly superior if you can afford an extra 40-100 bytes of flash memory. (It's not too much more complicated than Insertion sort, but sometimes, we don't have 100 extra bytes.) It is O(N^k), where k ≈ 1.3 to 1.5. As soon as N ⪆ 30, Shell sort will start clobbering Insertion sort. For N ≈ 1000, Shell sort is 10X faster than Insertion sort, which in turn is 6X faster than Bubble sort. Unfortunately Shell sort is not stable.
Comb sort has a similar O(N^k) runtime complexity as Shell sort. But it seems slower than Shell sort by a constant factor. Comb sort is also not stable. I cannot think of any reason to use Comb sort over Shell sort.
Quick sort is not much faster than Shell until about N ≈ 300. Above that, the O(N*log(N) of Quick sort wins over the O(N^k) of Shell sort. But Quick sort is not stable.
Merge sort is stable and runs in O(N*log(N)), but it consumes an extra O(N) of RAM, which may be impossible on a microcontroller. You may be forced back to Insertion sort for a stable sort.
Looks like the original repo of syncthing-android, (https://github.com/Catfriend1/syncthing-android), which was maintained by @Catfriend1, now redirects to the one maintained by @researchxxl (https://github.com/researchxxl/syncthing-android).
The problem seems to be that no one in the syncthing community knows who @researchxxl is. The account was created only 3 weeks ago. There was no communication about how the transfer took place. Was the transfer actually authorized? Did @Catfriend1 get hacked? People are worried about a backdoor hijack attack similar to the XZ libary.
There's a long discussion at https://forum.syncthing.net/t/does-anyone-know-why-syncthing.... It is too long and complex for me to follow. (I tried to get an LLM to summarize that thread for me, but the output was not helpful.)
It is unclear what sycnthing-android users are supposed to do right now. I am staying at version 1.30.0.4 until things become more clear.
[Edit: The GitHub repos are called "syncthing-android". The Android apps are called "Syncthing-Fork" or "Syncthing-Fork Wrapper", which adds to the confusion.]
If I recall, there used to be a syncthing-android app on Google PlayStore. That was discontinued by @imsodin in Oct 2024 (https://forum.syncthing.net/t/discontinuing-syncthing-androi...).
There was a version of sycnthing-android on F-Droid. I don't remember who maintained that. I have version 1.30.0.4 installed. But I cannot find any information about that version anymore.
The current version on F-Droid is 2.0.12.1. That seems to be maintained by a fellow named @researchxxl. Apparently @researchxxl claims to have inherited the source code and signing keys from a person named @Catfriend1 (Not sure who that is, the maintainer of version 1.30.0.4?)
There is another fellow named @nel0x who seems to be maintaining a different version of synchthing-android? (Edit: Here it is, https://github.com/nel0x/syncthing-android, which says that it is a fork of the one maintained by @Catfriend1).
Another common tell: I wake up in the morning in the US/Pacific time zone, and see the European writers on HN using "I have ran" instead of "I have run".
I finally bought one from iFixit.com. Far more expensive than eBay, but the battery actually worked great for about a year. Then about a month after the 1-year warranty expired, it degraded noticeably (maybe to 80%) with only about 100-200 charge cycles. Even iFixIt cannot source a battery as good as the original Apple.
Right now, it's at 65% capacity after 584 charge cycles, after 4.5 years of service. I will probably go back to iFixIt. At least I'll get one year of full capacity from them, instead of the fake or DOA ones from eBay.
For example, the fan did not work out of the box. I had to install something called 'macfanctld'.
Sleep did not work, it would wake up as soon as it went to sleep. I had to install something called a 'suspend-fix.service' hack.
Brightness control was flaky. It would always wake up at the lowest brightness setting. Disabling auto-dimming caused it to wake up at the highest brightness.
In addition to the Classic option that is shown only after hitting "Cancel", they also had a secret "Microsoft 365 Basic" option for $20/year. It includes no Office products, but provides 100 GB of OneDrive. Which is all I needed. So Microsoft is getting $20/year from me that they don't deserve.
Why do I pay them even $20/year? It's insurance against the same kind of BS from Google. I back up my Google Drive to OneDrive.
Sure, you can choose to write everything yourself, but you are limiting the size, scope, and complexity of the problems that you can solve. We have to stand upon the shoulders of others to get stuff done.
I don't like the thought of providing Google thousands of personal photos for their AI training. Which will eventually leak to gov't agencies, fraudsters, and criminals.
For example, I don't particularly like Python as a language, but I will use it because it has 677,633 packages in PyPI.
Edit: Missed the "locally" part. Sorry no suggestions. Maybe Garmin has something?
I also need to sell my Google Chromecast with Google TV 4K. Brand new, still in its shrink wrap. Bought it last year, to replace a flaky Roku. It was a flaky HDMI cable instead. I trust Roku more than Google for hardware support.
As I understand, low-E reflects solar thermal infrared radiation (3-8 microns, 37-100 THz), while letting through visible light. I don't think it affects 5 GHz radio waves very much.
But yeah, it would be very satisfying to finally wire the house with ethernet.
Google Picasa: Everything local, so fast, so good. I'm never going to give my photos to G Photos.
Google Hangouts: Can't keep track of all the Google chat apps. I use Signal now.
Google G Suite Legacy: It was supposed to be free forever. They killed it, tried to make me pay. I migrated out of Google.
Google Play Music: I had uploaded thousands of MP3 files there. They killed it. I won't waste my time uploading again.
Google Finance: Tracked my stocks and funds there. Then they killed it. Won't trust them with my data again.
Google NFC Wallet: They killed it. Then Apple launched the same thing, and took over.
Google Chromecast Audio: It did one thing, which is all I needed. Sold mine as soon as they announced they were killing it.
Google Chromecast: Wait, they killed Chromecast? I did not know that until I started writing this..
My dev laptop is about 10 m (30 ft) away from the wifi access point, but goes through about 6 walls diagonally, due to some weird layout, and 2.4 GHz is way faster.
The house has some thick walls.
Same with phones. As soon as I'm in a different room, 2.4 GHz is faster. So I just keep things on 2.4.
Yeah, I've been planning to wire the house with Cat-6 into every room and add some access points. It's been on the backlog for 6 years..
I would prefer to write in assembly language than write in Forth. Which is what I have done with one of my current projects.
With assembly language, there is a good chance that a random person with some minimal programming skills would understand my program if I were hit by a bus. With Forth, I think the chances of that are close to zero.
Lots of good info, thank you. I don't think I will fully understand what you wrote until I implement a Forth interpreter myself.
So a side question: If most Forth "interpreters" are compilers, how does a Forth interpreter work in a Harvard architecture microprocessor (with separate memory space for data and instructions) instead of a Von Neumann architecture with a unified memory layout? In other words, in a Harvard architecture (e.g. AVR microcontrollers), the Forth compiler will live in read-only flash ROM, and it cannot generate machine code into RAM and execute it, because the data memory is not executable.
But you are saying that the Forth version is simpler than C version which will kinda look like this after it's compiled (Z80 assembly code, it's in my head right now):
ld a, (variableN)
cp 42
ld hl, StringHey
call z, Printf
...
StringHey:
.db "hey!", 0
I find that hard to believe, but I accept that you believe that.Nowadays almost nothing is written in Forth. That's the problem with Forth. Even on 8-bit Arduino microcontrollers with 2kiB of RAM, we write programs in C++ (with a little bit of C, on top of hand-coded AVR assembly).
Yes, I think control-flow is easier to understand in assembly language than the implementation you showed in Forth. :-)
If understanding this special IMMEDIATE mode is required to understand the Forth interpreter for something as fundamental as control-flow, it seems fair to say that Forth is not a simple language. It's not just an advanced programmable RPN calculator An RPN calculator has a program counter, which makes control-flow easy to understand.
In comparison, C is a high level language, but the mapping from C code to assembly language is relatively simple. (Yes, compiler optimizations against the C "abstract machine" can make the resulting code completely obscure. But if we turn off optimization, the resulting assembly code matches the C code fairly directly.)
Are you saying that the Forth interpreter is a 2-pass interpreter? Or does the interpreter go into a special IMMEDIATE mode upon hitting the IF keyword, then it just consumes subsequent tokens without doing any dispatching, until it hits the THEN token? It sounds like nested IF-THEN-ELSE becomes tricky to handle.
How does the FORTH interpreter handle loops? Does the interpreter hit the WHILE token, goes into IMMEDIATE mode, remembers the location of the WHILE, then dispatches all the subsequent code, until it hits the REPEAT token, then branches back to the WHILE?
My mental model of Forth is that there is a simple parser that consumes space-delimited keywords. The interpreter looks up that keyword in a dictionary, which gives the address of the machine code that handles that word. The interpreter either makes a subroutine call to that address (subroutine threaded), or jumps to that address (called "direct threaded" if I recall, where the handler jumps back to the interpreter instead of executing a RET).
But that's where my mental model of Forth breaks down, because IF-THEN-ELSE cannot be implemented in that model. So there must be something else fundamental in the Forth interpreter that I don't understand.
I've been reading about Forth for 30-40 years. The dual stack is easy to understand. My problem is that I cannot see how control flow works in Forth, e.g. a simple if-then-else.
I think that something as fundamental as an if-then-else should be obvious in a useful language. Heck, it's obvious in assembly language. But not in Forth.
Regarding Shorts, I have no YouTube history, but I still get Shorts. I hate them. You must be doing something else to disable them.