DennisMitchell / jellylanguage

Jelly is a recreational programming language inspired by J.
MIT License
860 stars 47 forks source link

Unique permutations, odd-even, group lengths #79

Closed dylannrees closed 6 years ago

dylannrees commented 6 years ago

Œ¡ unique permutations. Uses sympy's multiset permutations built-in. Œœ Odd-even. Same as s2Z. Œɠ Group lengths. Same as ŒgL€. Unlike Œg, this does not vectorize. If the argument is an integer, the lengths of groups of it's consecutive digits will be found.

Two details I wasn't sure about:

dylannrees commented 6 years ago

Thinking more about the second point, I think ldepth should be 1 and that make_digits = True should be removed or left as it is.

DennisMitchell commented 6 years ago

I'll think about the vectorization behavior. I'd rather remove ldepth = 1 than make_digits = True, but that's not really backwards-compatible.

DennisMitchell commented 6 years ago

I like the Œ¡ idea, but sympy.utilities.iterables.multiset_permutations seems way too slow.

Also, it always sorts the permutations. I see three choices:

  1. Do what SymPy does. Might be useful in general, but there's really no way of "going back" from sorting the permutations.

    Permutations of [1, 0, 0, 1] are
    [[0, 0, 1, 1], [0, 1, 0, 1], [0, 1, 1, 0], [1, 0, 0, 1], [1, 0, 1, 0], [1, 1, 0, 0]].

  2. Sort and rotate the argument to the first position.

    Permutations of [1, 0, 0, 1] are
    [[1, 0, 0, 1], [1, 0, 1, 0], [1, 1, 0, 0], [0, 0, 1, 1], [0, 1, 0, 1], [0, 1, 1, 0]].

  3. Order by first occurrence rather than value. That still performs some kind of sorting.

    Permutations of [1, 0, 0, 1] are [[1, 1, 0, 0], [1, 0, 1, 0], [1, 0, 0, 1], [0, 1, 1, 0], [0, 1, 0, 1], [0, 0, 1, 1]].

  4. Order by first occurrence and rotate the argument to the first position.

    Permutations of [1, 0, 0, 1] are
    [[1, 0, 0, 1], [0, 1, 1, 0], [0, 1, 0, 1], [0, 0, 1, 1], [[1, 1, 0, 0], [1, 0, 1, 0]].

DennisMitchell commented 6 years ago

I've implemented all four, for easier comparison: https://tio.run/##tVXbbqMwEH2Gr5i3QEVQafqEtn/RN4QQEZN2FHNZ27SNVvvtWY9tctk0aSqlUgJ4zvjEc84MGTb6te8W25XsW9DUImmgduil9qvQImrTDpt01CRIE6qUNMp6KVBNye0oNCnU1YCyHXWtqe8U1ArGQW0bXJl7Fin8HedhYG7wBMpsw8bGwoCaDxOSdfeCkcDORmEOWQJz@43DMHh/JYFgEEMRbAhFw4siLw0WrHoJa6AODBPjAa0sumaWEn65RZnDUmK95h3r6q0WfI5d1sRD//G4TEdBhxR26zwrEw95NvIBhqasfAJzE80ZCJ0qD5Mq5GVxJX1DkWc54m0k4Vpt5ufanIpzUZ0r5TmnTxCgULYwzkglvqFUGMX@oFatJ2DVdr/pFF1Mig69OuqzlLoGPyIU2MbAtfATl@N60Olf@LPuajUs37LD5F/rhkndu2EXnzXoPuurBuXMIwvsVuuAgzwb@YB3wD7mE3hgwC36@/HYjeILH1hql2nP8mODcFn6k0E49uDyIJy4cKUN53243SQZ4oNJOjNaVn8zWtzJrootFzwOXLF5nyf8MufLA18WfHlkgyV1OhqHtKq6usWqiqfY3ThEhdlxbz9ZGe8Q9x8TzQqbYkG4g@w@LmcJvIh@WQvuhT@zcZjl5nf@JtCN7RKlCWZ7mnj7Dw

up2 might be the most natural one. If there was a next permutation atom Ŋ, we could use ŊƬ to implement up2.

dylannrees commented 6 years ago

Is 3 the reverse of 1?

A fifth option would be to order by the initial index. [1, 0, 0, 1] would give [[1, 0, 0, 1], [1, 0, 1, 0], [1, 1, 0, 0], [0, 1, 0, 1], [0, 1, 1, 0], [0, 0, 1, 1]]. Same as getting the sorted permutations of [1, 2, 3, 4] then indexing each back into the initial list [1, 0, 0, 1]. TIO.

That being said I agree that the second option would be most useful in general. We could amend the code page again to make room for Ŋ or perhaps Ñ.

dylannrees commented 6 years ago

Slightly altering up2, this could be the next_perm function based on lexicographic sorting:

https://tio.run/##TZDdisIwEIWv06cY2JsW7LKysAtBn0SKVDp1h8QYJ1Hs03cnSZVCfpic75wk46f4d3Xf8zzgCA6f8eiRL3XAW6MrRbLDHmQ96E7K4SkV9@6MtUWXKWhhu4E2z6aq1HhlMEAOBJYERWO2m8R1sCtFp@HE2BvhRTeJM8dHb5e7CixiTqNVWsYzWZJolaSytd12m0Va0mg5SNKL0i9Ry6nOAtqAuuifjA/kgHVTKcZ4Z5fYOYjnIB/9ykM879eVlvymlnkmF@sgzoSvOirN@YDeezuRO8MPRLpggInQDkEyKJL8ipy/x/kf

DennisMitchell commented 6 years ago

After removing iseq = seq[:], that's exactly what I had in mind. It minor tweaking to handle the empty array and to avid clobbering the argument.

An alternative to a next permutation atom would be an all permutations quick.

DennisMitchell commented 6 years ago

I thought about it and neither Œɠ nor Œœ should vectorize.

Could the Œ¡ be removed for now? That way, I can merge the atoms that are already done.