I'm looking for a block that would do this
My 1st, buggy, attempt.
EDIT
2nd attempt
I believe this one now needs to be recursively calling itself to make several rotations at once.
@jens you posted for a few seconds and deleted retracted it too quickly for me to understand your solution.
p.s.
Isn't it strange that the in front of
block behaves the way it does? Shouldn't it merge lists, too?
I've come up with this
that's really nice! I'm working on a similar solution using hyperblocks, but I love yours! Maybe use modulo for the index, so it wraps around?
yeah, I noticed I had made a mistake, because Snap's list indices start at 1 instead of 0 .
in front of
doesn't concatenate two lists, it only pre-pends a single item to a list.
This is surprisingly hard, haha!
So I wrapped it in a call (to make it easy to feed the parameters in)
and then added in your modulo idea and now it rotates both ways
beautiful!
IN FRONT OF works the way it does because it's the underlying constructor for linked lists. A linked list is defined as either the empty list or a pair (basically, an array of two items) containing the first item of the list and a pointer to a smaller list (the ALL BUT FIRST OF the bigger list). IN FRONT OF takes the item and the smaller list as its inputs, and reports the newly constructed pair that represents the bigger list.
I think maybe Snap! is unique among programming languages in trying to give users a choice of contiguous arrays or linked lists without them having to think about how lists are constructed. Instead, if you use the Scratch-style imperative list commands (ADD, INSERT, REMOVE, REPLACE) you get an array, but if you use IN FRONT OF, ALL BUT FIRST OF, and ITEM 1 OF, then you get a linked list.
(Alan Kay used to talk about an abstract SEQUENCE object class in which each instance would decide dynamically how to represent itself internally depending on what messages you sent it, but I don't think that was ever really part of Smalltalk. But that was the inspiration for our mixed-mode lists.)
P.S. In the words and sentences library, the SENTENCE block does what you want, like append but treating atoms as if they were one-item lists.
Wait, what?!!! How did you come up with not having to use append
? This is crazy cool, I can't believe it!!! I wasn't even thinking about the dyadic hyper- feature of modulo, and about shifting the whole set of indices before mapping modulo over it, it's brilliant!
See, my own shabby experiments were all circling around only adjusting the offset number, not the whole list of indices. I'm soo not worthy
Thank you!
Another approach is to start by appending two copies of the original list and then just select the right subset. That way you don't need the ability of our ITEM to reorder the items. That's probably how an APL person would do it:
(⍴data)↑((⍴data)|num)↓data,data
The call to mod is needed only to handle negative rotations.
Great stuff @bh
I just happened to look at internals of library reverse and I thought - I wonder if same approach would be quicker/more elegant and it is
<blocks app="Snap! 6, https://snap.berkeley.edu" version="1"><block-definition s="reverse %'data' (2)" type="reporter" category="lists"><comment w="222.99999999999997" collapsed="false">Reports a new list containing the items of the input list, but in the opposite order.</comment><header></header><code></code><translations>ca:capgira _
</translations><inputs><input type="%l"></input></inputs><script><block s="doReport"><block s="reportListItem"><block s="reportNumbers"><block s="reportListLength"><block var="data"/></block><l>1</l></block><block var="data"/></block></block></script></block-definition></blocks>
Yes, for sure! This is method is waaaaaay faster. But - fine print ahead - since it uses hyperblocks it will also turn linked lists into arrays. It's a minor detail that I don't give much attention to, but if you're carefully designing around a purely functional style mixing these two internal representations of lists might have downsides.
Oh. That probably means most of my implementations of functions in the APL library are O(n^2) time. :~( It's not fair; recursive functions are so much easier to write than loops, especially for arbitrary-rank arrays.
Can you please explain this dense code so that non-geniuses and average fans of Snap! could understand it (if I understood it, I would probably call it 'elegant and succinct'; but because I don't understand it, I am calling it 'dense' ;~P ).
Thank you.
This is as 'dense' (see my reply to him above) as the Brian's code. Please explain...
Lets see if I can
(explanation of Brian's)
If you had a list [a b c d e] then
(length of data ) -1 would be 4
numbers from 0 to 4 would produce a list [0 1 2 3 4]
If you wanted to rotate 2 places then
[ 0 1 2 3 4] + 2 would give [2 3 4 5 6]
but mod 5 would change them to [2 3 4 0 1]
[2 3 4 0 1] + 1 gives [3 4 5 1 2]
items [3 4 5 1 2] of [a b c d e] are [c d e a b]
Does that make sense?
Explanation of my reverse
Lets assume data is a list [a b c d e]
length of data is 5 so
we get a list of numbers from 5 to 1 [5 4 3 2 1]
items [5 4 3 2 1] of [a b c d e] gives [e d c b a]
You probably took for granted that it is crystal clear (I think mathematicians use the word 'trivial' in such cases, or am I wrong?) to me that the symbol '+' here's not a 'normal' addition but a 'hyperized' '+'.
I needed to read it twice before it dawned on me.
@jens can you please please please use a different (block outline?) color in which to render the '+' sign when it is meant as hyper-variant? Red for example? Any color will do as long as it is different from the non-hyperized one.
Please!!!
@cymplecy thank you for your efforts and your kindness.