Fixing Unordered combinations custom block

Hey bh!

Thanks for your help! Yes I'm 25 years old. "M" mean male. I actually have a Math/Stats Education degree, and I'm taking some CS courses to get a CS Teaching Endorsement, and my first class is based on the Berkley BJC labs. I finished all of the coursework in a few weeks and I'm just trying some more experiments in Snap!.

TL:DR I just now used your comments to fix my bug, and I feel like I understand my bug and how to fix it in the future. Your detailed answer in the FAQ question about I copied a list to another variable, and then when I change the copy, it changes the original too! also helped me understand more fully what you were explaining. I also browsed the Snap! manual pages 48 and 49.

I thought that I understood the list structure mechanics before, but this bug helped me understand them even more. I remember early on in the BJC labs that we had to use the Append block, otherwise when we alter the result then the original list changes also. Essentially, I overused SET list block, mostly because I was thinking I had to use APPEND for everything. Really, I should use append only when I want to make a new object, but use the list mutation commands like ADD when I want to change an existing list. The commands ADD, INSERT, DELETE, REPLACE are used to change an existing list (the mutation commands, which are the imperative style).

Other blocks like APPEND, ALL BUT FIRST OF, IN FRONT OF, make new lists that have no effect on lists that were pointed to earlier by another variable. These are the functional style blocks for lists.

Maybe I didn't explain those very well, but I'm getting there. :slight_smile:

Additionally, I'm not so sure I understand what you are saying when you say "Calling APPEND with just one input reports that input unchanged. So in the SET RUNNINGLIST instruction you can just say (APPEND (RUNNING LIST) (LIST (UPDATOR LIST)))". Without the APPEND around UPDATOR LIST, then when I later DELETE last OF (UPDATOR LIST), then the running list content changes also, which is not what I intended. But it's fixed now anyway, so I'm not too worried about that part.

Here's my new script, with only the changes necessary to fix it, no other changes:

tuple generator (fixed) script pic
tuple generator (fixed) script pic(1)

I still had to use one Append block when adding the Updator List to the Running list, because otherwise the Running list contents would be deleted later on... like I was saying before.

Here's my first attempt at creating a functional version of the same block:
Gets stuck in an infinite loop.

functional tuple generator, attempt 1, infinite loop

This one was close to working, but would get stuck in an infinite loop because the pink UNORDERED... block would keep increasing the minimum past the maximum infinitely.

Here is my second attempt at creating a functional version:
Works as intended.

function tuple generator, attempt 2 fixed

This one works as intended. I now have two if checks near the start, so that if the procedure is ran with a minimum greater than the maximum, then an empty list is reported and no further nesting is done. (Is it still called nesting with the functional style? This reminds me of fractal structures.) I have to be careful with the order of the if statements... in the pink MAP block, for the tuples in which the last number is equal to the Max, that number still needs to be put IN FRONT OF the empty list, and the empty list needs to come from list reported by the red UNORDERED... block that follows, calling with min+1>max.

Carefully reading page 70 of the Snap! manual also helped me a lot with this. It probably took me about 40 minutes of solid thinking to understand the script there, but I love learning and this is just great! :slight_smile:

Anyways, that's a lot to think about and it was really fun solving this puzzle in two very different ways! I appreciate the encouragement and advice, bh!

I know that "unordered combinations" are called "combinations", but seeing as there is a primitive block called "combinations" already, I figured I would be specific. I remember learning about permutations and combinations way back in 9th grade. Good times! I might start on a Permutations block... I can already do that imperatively using my custom predicate <Does (LIST) repeat?>... but I wonder if I can do it functionally? I'm not sure, this is going to take some practice.

I saved both custom "Unordered Combinations" blocks. I went a little further and created another block called "Combinations of %List picking %n at a time". Actually, I tried to create two blocks, one Imperative style and one Functional style. The idea is the same, but now you can use a list of anything, not just integers from Min to Max. These new blocks rely on the tuple generator blocks, but they could be combined with a bit of effort. Here are my two combination blocks:

Imperative:
Combinations from any list (Imperative)

Functional:
Combinations from any list (Functional)

Having tested all four of these blocks, the Functional blocks are much quicker to run than the imperative blocks. This is confirming of the ideas you set forth in the FAQ question I mentioned earlier, that the Functional style often runs in linear time, but the Imperative style often runs in quadratic time.

I'm nearly wrapped up with this project... but I'd love any last comments you or another person might have about my attempts at the functional style of list generating.

Thanks!

Mr. Ogborn

P.S. The FAQ and Manual are great!