Relevance Challenge December 2019: Reversing a Tuple

It’s been a while since a Relevance Challenge was posted, so here’s a fun one that I came across in a discussion today.

Suppose one has a tuple result of tuple ("a", "a", "c", "b"). Is it possible, and in how many ways, can this be reversed to give a result of ("b", "c", "a", "a")?

Using set or unique values will sort strings and give unique values; in this case we wish to reverse without sorting, and keep duplicate values.

Private message me with your solutions, and I’ll post solutions next week along with the winning 'Fixers !

So far three unique solutions have been provided.

Working solutions thus far have been posted by:
@brolly33
@alinder
@jgstew
@amitkumsingh
@strawgate

Next Challenges:

Previous Challenges:

7 Likes

Welcome back, everyone, it’s time to post the solutions that the community presented to this challenge, and open it up for further discussion, so please do let the collaboration begin! There were four distinct solutions presented, discussion below.

There were actually several solutions posted for this, and I love hearing about the different ways we can accomplish the same task.

In each Solution below, click the “Details” to expand the description and view the relevance.

Solution 1 - Tuple Strings and Indexing

This challenge began with an internal collaboration between @alinder, @brolly33, and @jgstew, who posted forms of the following-

This challenge began with an internal collaboration between @alinder, @brolly33, and @jgstew, who posted forms of the following:

q: concatenation ", " of items 1 of items 1 of (integers in (maxima of indexes of tuple items of it,0), (index of it, string of it ) of tuple items of it) whose (item 0 of it = item 0 of item 1 of it) of tuple string of ("a" ; "a" ; "b"; "c")
A: c, b, a, a

Note that this solution starts with a plural, which is slightly different from a tuple and was based on their earlier conversation -

q: ("a" ; "a" ; "b"; "c")
A: a
A: a
A: b
A: c
T: 0.180 ms
I: plural string

q: ("a" , "a" , "b", "c")
A: a, a, b, c
T: 0.160 ms
I: singular ( string, string, string, string )

In any case, very early in this solution they convert the plural into a “tuple string”. Both a plural collection of strings, and a tuple of strings, can be converted to the “tuple string” type, and follow the rest of this solution:

q: tuple string of ("a" ; "a" ; "b"; "c")
A: a, a, b, c
T: 0.230 ms
I: singular string

q: ("a", "a", "b", "c") as string
A: a, a, b, c
T: 0.183 ms
I: singular string

And, these operators handle any conversions needed - for instance if one of the strings had an embedded comma, it gets wrapped in parentheses, and displays this way in the debugger -

q: tuple string of ("a" ; "a %22complex string, with a comma%22" ; "b"; "c")
A: a, ( a "complex string, with a comma" ), b, c
T: 0.133 ms
I: singular string

q: ("a", "a %22complex string, with a comma%22", "b", "c") as string
A: a, ( a "complex string, with a comma" ), b, c
T: 0.066 ms
I: singular string

Once it’s converted into a “tuple string” type, we can refer to its “tuple items”. A “tuple item” has several properties, including the item itself, as well as its index, which is crucial to the next piece of the solution:

q: (index of it, it) of tuple items of tuple string of ("a" ; "a" ; "b"; "c")
A: 0, a
A: 1, a
A: 2, b
A: 3, c
T: 0.138 ms
I: plural ( integer, tuple item )

The integers in (<integer>, <integer>) gives us a counting list of numbers, and can work backwards from the end -

q: integers in (3,0)
A: 3
A: 2
A: 1
A: 0
T: 0.038 ms
I: plural integer

We can loop from the last index, back to the first index

q: (integers in (maxima of indexes of tuple items of it,0), (index of it, string of it ) of tuple items of it) of tuple string of ("a" ; "a" ; "b"; "c")
A: 3, ( 0, a )
A: 3, ( 1, a )
A: 3, ( 2, b )
A: 3, ( 3, c )
A: 2, ( 0, a )
A: 2, ( 1, a )
A: 2, ( 2, b )
A: 2, ( 3, c )
A: 1, ( 0, a )
A: 1, ( 1, a )
A: 1, ( 2, b )
A: 1, ( 3, c )
A: 0, ( 0, a )
A: 0, ( 1, a )
A: 0, ( 2, b )
A: 0, ( 3, c )
T: 0.347 ms
I: plural ( integer, ( integer, string ) )

And then filter out to only the tuple, here “item 1 of it” has an index matching our loop iterator, here “item 0 of it”. Then we select only the string value of the tuple, here “item 1 of item 1 of it”, and concatenate those plural results back together -

q: concatenation ", " of 
items 1 of items 1 of 
(        /* loop starting from the last index and counting down to index 0 */ 
    integers in (maxima of indexes of tuple items of it,0), 
    (index of it, string of it ) of 
        /* use tuple items so we can get indexes */ 
    tuple items of it
) whose 
 (
        /* Keep only the item whose index matches our 'integers in (X,0)' countdown */
     item 0 of it = item 0 of item 1 of it
 ) of 
    /* use a tuple string so we can convert to tuple items */  
tuple string of ("a" ; "a" ; "b"; "c")
A: c, b, a, a
T: 0.701 ms
I: singular string

We also had the same basic form, but using number of tuple items of it - 1 rather than maximum of indexes of tuple items of it to find the highest index.

Solution 2 - Plurals of Tuple Strings

Using the same basic principle of indexing a tuple string, @strawgate responded with this simpler form of the same solution -

q: tuple string items (integers in (length of it,0)) of (it as string) of ("a","b","c","d")
A: d
A: c
A: b
A: a
T: 0.137 ms
I: plural string

At first glance, this looks very similar, but saves the lookup of “tuple string items” to the end. The first step converts it to a string -

q: (it as string) of ("a","b","c","d")
A: a, b, c, d
T: 0.049 ms
I: singular string

The length of this is not the same as tuple indexing - the length of the string is “10”, as it includes both the spaces and the commas -

q: length of (it as string) of ("a","b","c","d")
A: 10
T: 0.056 ms
I: singular integer

We can refer here to each tuple string item within a string by its index, and note that while ‘tuple string item 8 of it’ gives an error (because there aren’t that many in the tuple), the plural ‘tuple string items 8 of it’ just gives an empty result rather than an error. Using plurals is often useful to discard empty results without yielding an error -

q: tuple string item 1 of (it as string) of ("a","b","c","d")
A: b
T: 0.225 ms
I: singular string

q: tuple string item 8 of (it as string) of ("a","b","c","d")
E: Singular expression refers to nonexistent object.

q: tuple string items 8 of (it as string) of ("a","b","c","d")
T: 0.170 ms
I: plural string

In Strawgate’s solution, he takes the full length of the tuple string (10), counts down from that using integers in (10, 0), keeps the results with a matching tuple string items X of it. This silently discards the non-matching tuple string items 10 through 4 which have no results, and keeps tuple string items 3 through 0. These can of course be concatenated back together to get the same form of result as we saw in solution 1:

q: concatenation ", " of tuple string items (integers in (length of it,0)) of (it as string) of ("a","b","c","d")
A: d, c, b, a
T: 0.157 ms
I: singular string

Solution 3 - Double-Reversal

A second submission from @jgstew puts a unique twist on it -

concatenations of characters (integers in (number of characters of it - 1, 0)) of concatenations " ," of ( concatenations of characters (integers in (number of characters of it - 1, 0)) of it) of tuple string items of (it as string) of ("abc", "xyzabc")

This works by taking the individual items, and splitting them into a plural group of ‘tuple string items’; reverse each string individually, join them together, and then reverse the combined string - which reverses the order of the two strings relative to each other, but puts the individual string characters back in the original order. Note when combining the strings together he concatenates with " ," rather than the ", " combination we usually see (a space followed by a comma, rather than a comma followed by a space) - so when he reverses the string it goes back to the form we usually see)

q: tuple string items of (it as string) of ("abc", "xyzabc")
A: abc
A: xyzabc
T: 0.830 ms
I: plural string

q: ( concatenations of characters (integers in (number of characters of it - 1, 0)) of it) of tuple string items of (it as string) of ("abc", "xyzabc")
A: cba
A: cbazyx
T: 0.778 ms
I: plural string

q: concatenations " ," of ( concatenations of characters (integers in (number of characters of it - 1, 0)) of it) of tuple string items of (it as string) of ("abc", "xyzabc")
A: cba ,cbazyx
T: 0.571 ms
I: plural string

q: concatenations of characters (integers in (number of characters of it - 1, 0)) of concatenations " ," of ( concatenations of characters (integers in (number of characters of it - 1, 0)) of it) of tuple string items of (it as string) of ("abc", "xyzabc")
A: xyzabc, abc
T: 0.351 ms
I: plural string

Solution 4 - Counting Items

@amitkumsingh took a simpler approach, which is often best when approaching a problem. There was actually nothing in the challenge indicating that exact number of items might not be known, so this is a perfectly valid solution:

q: (item 3 of it, item 2 of it, item 1 of it, item 0 of it) of ("a","b","c","d")
A: d, c, b, a
T: 0.055 ms
I: singular ( string, string, string, string )

Further discussion - Reversing a String

Because this also came up in our private messaging, I wanted to include a solution to reversing a simple string. This is a repost from a much older BigFix forum, and because usernames weren’t tracked on those old posts I don’t know to whom I should give credit, but this is definitely not my own -

Q: concatenation of characters(lengths of following texts of positions of it ) of ("abcdefg")
A: gfedcba
T: 0.146 ms
I: singular string

A second solution to reversing a simple string is the method @JGStew used to reverse the individual strings in his second solution - a string has a certain number of characters, and you can iterate through them using 'integers in (X, 0)`

q: concatenation of characters (integers in (number of characters of it - 1, 0)) of ("abc")
A: cba
T: 0.099 ms
I: singular string

Thanks to everyone who participated in this challenge, and I hope the rest of you lurking learn as much from it as I did! Stay tuned as I plan to post a bonus End-of-Year Relevance Challenge later today…

5 Likes