@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
Nice stuff!
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.
let j=(i+3)%8in3<<j|3>>8-j
Though to be fair, that would have ended up being longer anyway.
Fair comment … of course I should have said the bits that overflow on shifting. Your example demonstrates nicely this function; thanks!
This shows my complete, blind faith in you!.. Happily copy&pasting anything you post … which also answers the question, “If @Pharap jumped off to an undefined address… would you ?!” …
Nice! I assumed this was a standard… I just never tried clicking those binary digits until last year. Also loving your ‘Vapourwave’ magenta theme!
Whether they overflow or not depends on how big the datatype being operated on is…
Arithmetic operators don’t actually work on types smaller than int and on Arduboy int is 16 bits, so technically in this case the bits shifted out by the right shift are automatically discarded, but the bits shifted to the left are actually moved into the upper byte and aren’t discarded until the result is implicitly cast back to uint8_t.
(I know, I’m being pedantic, but no more so than the compiler would be.)
After all, if you right shift a negative value when using a signed type (like int) you could get a nasty surprise if you were expecting zeroes to be shifted in. (It’s only safe here because 3 isn’t negative.)
The tragic thing is that this was one of the few times I actually tested rather than just blindly throwing code up. Alas, my testing methodology was flawed.
Everybody follow me down this nop slide(!)
I promise there’s nothing nasty at the bottom(!)
For a moment I read that as ‘vapourware’ and felt my unfinished projects stare back at me.
There’s no special aesthetic involved, I just particularly like purple.
If I had an aesthetic, it would probably be ‘Victorian’.
(And now I’ve gone down an aesthetics rabbit hole…)