Has anyone made/ is there a rotate list reporter

I'm looking for a block that would do this

image

My 1st, buggy, attempt.

rotate_block_to_debug

EDIT

2nd attempt
2nd_attempt_at_the_rotate_block

I believe this one now needs to be recursively calling itself to make several rotations at once.

2 Likes

@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

image

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?

1 Like

yeah, I noticed I had made a mistake, because Snap's list indices start at 1 instead of 0 :joy:.
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 :slight_smile:

2 Likes

beautiful!

This inspired me to use modulo together with ITEM. But I did have to correct for starting with 1.

2 Likes

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.

1 Like

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 :crazy_face:

2 Likes

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 :slight_smile:

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 :slight_smile:

<blocks app="Snap! 6, https://snap.berkeley.edu" version="1"><block-definition s="reverse %&apos;data&apos; (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 _&#xD;</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.

1 Like

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 :slight_smile:
(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?

1 Like

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]

1 Like

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.