Extend sort with a weighted function

Hi, I am trying to extend the sort function with a weight applied to each element of the data before it gets fed into the compare function.

So what I have tried to do is the following:

  1. create an extended compare function

Inline image

  1. call the primitive lst_sort function with the weighted compare function.

Inline image

But I am failing. This is one example:

Inline image

I have created the script pic for you to take a look to see what mistakes I have made in this process.

Thank you all.

Your image urls can't have blob at the beginning. Blobs get deleted. You should instead, download the image, the upload it to the forum, by dragging and dropping it into the text field, or by clicking on the image button.

Just so you know, I can't see the images.

Sorry, just noticed that the images were not uploaded correctly. I am trying again to see whether this time works.

I tried again, maybe due to some limitations, it's not allowing me to upload for the moment.

I did uploaded them to my mega drive, here are the links:

  1. Weighted compare function
    mega.nz/file/DY10hRII#t8In8qjYEW-B15d0PtazCnFGBu-LxC7x9jvt7zXEKyk

  2. Weighted Sort function:
    mega.nz/file/aB8WkRbT#YEczfivHEjDHSrZRSTHhlgHhA-9038jpmJfnHvW1XKg

  3. One test case:

mega.nz/file/GQMCxSLD#oAx_FJGZoHvPvs5lB5W1WM2cHCL4NTrcpQ6AY7zd6iA

I am new in posting here, so sorry for the extra trouble. ( I am not allowed to post links either, so have add https with : and // in front of those links.

Thanks in advance for any help that you might be able to provide.

oh wait, it might be a limitation new users have. I can't keep track of what new users can and can't do. They change pretty often (at one point, new users couldn't create new topics, which is kind of funny, because usually new users come to ask questions).

Don't worry, you'll be able to have the limitations removed when you get trust level 1 (trust level 0 is pretty much just to keep away spammers).


Anyway, the links work fine.

I've looked at it, and I think I found the problem.

You need to put something in the a and b slots in the weightedComparFn block.

Don't you think he has to put it in a ring instead? He wants the two inputs empty, but it's the function that's the input.

@sm2art: Right-click on that weighted compare fn block and choose "ringify."

By the way, one of the virtues of a block-based programming language is that block names can be more than one word, so there's no need to use hideous camel case.

I actually didn't know that it was meant to be a ring.

C'mon, it's the sort function; its input has to be a comparison function. :~)

By the way, this is one more reason why we keep saying people should use the library blocks instead of the PRIMITIVE block. The library block is
untitled script pic
which has a ring built in! Whereas the PRIMITIVE block is generic and can't have input types built in.

I agree with you. I never use the PRIMITIVE blocks for functions that are in libraries. I don't know how the functions work, and it's much easier for someone to understand what the code is doing if it uses library blocks.

I figured out the problem, in calling the weighted compare function in the sort function, one has to use the diamond ring block. Thanks @bh for your insight and @ego for your kind help.

I had the hunch that something on that line has to be done.

Now, I am still experimenting how to write the help function (in this case, the compare function, but in general, could be just function block) right inside the custom block one is writing, that way, the code is cleaner. So far, I has not made much progress, I think it's also my limited knowledge of ringnify.

Thanks a bunch.

We don't have blocks that are local to other blocks. (It's on my someday list, but I think Jens is skeptical.) As of the 8.0 release, you can define a block inside another block (see Chapter X of the Reference Manual) but that definition will be global or sprite-local, not script-local.

P.S. But of course you could put the entire body of the helper block inside the grey ring if you want.

Thanks @bh for your kind explanation.

I tried the local compare function (as a local variable) approach, and surprisingly it's working, and I think it's local, could you please take a look and see whether it's legit?

I was about to give up after tried many many times, but I have to put another diamond ring around compare before I feed it into the library sort function, and voila, it worked. Here is the link to the mega drive:

mega.nz/file/uUNlTLxY#4EDVgHUeMo6vTAEiaYtckqanc-UCwhNFHN9cAq5eUWE

Appreciate your kind help.

Hmm, that's strange, I don't think there should be a ring around the COMPARE variable block in the call to SORT. It's the value of that variable that's the function you want to call to compare values.

Yes @bh,

That was my thought as well. However if I didn't put an additional diamond ring around the compare function before feeding it into the library sort function it would fail.

I was trying to ask you whether it's a feature or a bug?

Thanks.

I don't believe it. It works for me:




The last expression reports the input list in the reverse of its original order, because the function that is the value of variable FOO counts as truthy.

Maybe it's something about your weighting function? I couldn't tell what that is, from your picture.

i envy them, as i had to wait, and wait, AND THEN I FORGOT

@bh,

Yes, your "too" function works just fine without the additional diamond ring, however, my compare function does not work the same, your suspicion of something to do with the weight function might be the reason, although I could not figure out the reason.

Basically, I am applying a weight function before the normal compare. I could accomplish it in some other ways, but this is the most direct and general method in my way of thinking. For example, I could apply a map to the original list using the weight function, and sort it to get the sorted indices list, such as using the APL grade up or grade down function, and get the result by re-indexed the original list.

By the way, could you first try to use the script pic to get my code into a snap project? Due to the restriction, it's a little complicated on my end. You will notice without using the additional diamond ring, it will pop up an error.

I did that, but didn't find an example call, so I couldn't watch it fail. If you give me either a script pic of an example call or just instructions about what to try, I can look at it further.

Thanks @bh,

first of all, now I understand by adding the additional ring will truthy the result, since my original test case (in the 2nd post) was constructed to have a reverse order, I thought it was working, but it was not,

but as I said, without the diamond ring, it will have an error pop up. Here is the test case #2:

Sort Generalized Test Case #2

When I used the external function, it will work. I will use the external function as a work around until I figure out the reason through your help.

And looks like the restriction is already gone... :grinning:

Wait, you can't use a random value as the "weighted function" and expect it to work! Each value participates in comparisons more than once. (If it's a good sort algorithm, on average each value participates in O(lg N) comparisons where N is the length of the list.) If your weighted "function" gives different results when called repeatedly with the same input, it's not a surprise if the sort blows up.