@sparr - I struggled to get the code to run for some reason- but glad I persisted! This is wonderful stuff! I like watching it slowly develop with a.setFrameRate = 1;. It’s great you provided such readable code- really helped. I golfed your code a little, to get it down to 361(!) characters. Perhaps a collaboration with @Mr.Blinky and @FManga could get that lower?..
It’s interesting that while @Mr.Blinky’s 7 characters (-i%2^85) is 3 characters smaller than @Pharap’s original (i&1?85:170), the compiled code is 102 bytes more! (14 → 116 bytes). I presume this is the use of modulus function?..
Of course, it highlights the issue of golfing a compiled languages, rather than interpreted languages
I’ve not considered using | in these statements… also I don’t think I ever explored multiple expressions (perhaps it feels like cheating!?.. ). I’m also waiting to find a good use for the ‘space-ship’ operator <=> …
I’m using that because after inspecting the binary encoding of 129 I noticed that you’re basically attempting to left-rotate 3 and offset the pattern.
x << n | x >> (c - n) is the idiom for a left-rotate, where:
x is the value to be rotated
n is the number of bits to rotate by
c is the target bit width
Effectively it shifts the bits left by n and right by the ‘inverse’ of n and combines the result, thus mimmicking a rotate once the outlier bits are discarded. Normally you’d need an & to mask off the excess, but in this case the implicit cast to uin8_t has the same effect.
The comma operator is 100% legal C++, even if it’s pretty much only ever useful for operator overloading and nasty tricks like this.
The += and %= trick would work without the comma operator, but you need at least one comma to ensure that the modification is sequenced before the rotate, otherwise you’ll fall foul of the fact the evaluation order of binary operator operands is unsequenced. (I.e. the compiler is allowed to evaluate them in whichever order it wants.)
Unfortunately that won’t work on Arduboy because it’s a C++20 feature.
Wow! Down to 17 characters! That’s amazing!
– I will need to try with other patterns now…
Update: Yes! It’s simple to change the constant 24 → 28 to change the line width. (A nice feature of macOS’s calculator in ‘Programmer’ view, is being able to click on binary digits and quickly get a value). Thanks so much @Pharap & @brow1067 !
Needless to say, I always test my noodling in Ardens (the coloured pixel grid is vital!).
… But I do miss the old emulator with built in compiler, to quickly iterate on these little challenges…
It’s not a perfect solution, but the desktop builds of Ardens watch the hex file and automatically reload and restart the sim when the file is modified. So you can iterate and build while watching Ardens in the background.
So you’re using the left shift to move the bits leftwards, discarding what would have been wrapped around, and then the right shift generates the part of the pattern that would have resulted from the wraparound.
Do it manually a few times and you’ll see what’s happening.
Ah, sorry, I forgot you were doing it inline rather than implementing the expression as a function.
I was depending on the assumption that i would be a fresh variable each time as if by:
When i is persistant as it is in a for loop, that means you can’t just modify it as I did there because it’ll break the loop condition early and skip steps.
It’s times like this I wish C++ had an equivalent of let x = y in e, like most functional/lambda-calculus-derived languages do, then I could have just declared a variable for the duration of the expression.
Though to be fair, that would have ended up being longer anyway.