Codegolf Rainbow : Sorting Colors with Reflection

9

Introduction:

After I posted two rainbow-related challenges: Codegolf Rainbow : Fun with Integer-Arrays 1 and Codegolf Rainbow : Draw in Black-and-White 2, the following comment was made by @ChrisM in the ASCII (Draw in Black-and-White) challenge:

Maybe you know this and it's by design (I know that rainbows are not rhombuses or ascii, too, and higher orders' positions get more complicated), but aren't the colours reversed in the 2nd rainbow?

And he's indeed right. When you see a double rainbow, the second one is actually a reflection of the first, so the colors are reversed. With three rainbows, it's an actual double rainbow, with the third one being a reflection of one of the other two. And with four, there are two rainbows, and two reflections of those.
enter image description here

So, let's make a third related challenge using that fact.

Challenge:

Inputs: A positive integer n which is >=2, and a list of integers of size >= n+1.
Output: The same list ordered as follows:

  1. First split the input lists in sub-lists of size n (where the trailing sub-list could be of any size in the range [1,n]).
  2. Then we do the following based on the amount of sub-lists m:
    • Sort the first m - m//2 amount of sub-lists from lowest to highest (where // is integer-divide). (I.e. with 6 sub-lists the first three will be sorted from lowest to highest; with 5 sub-lists the fist three will be sorted from lowest to highest.)
    • Sort the last m//2 amount of sub-lists from highest to lowest (where // is integer-divide). (I.e. with 6 sub-lists the last three will be sorted from highest to lowest; with 5 sub-lists the last two will be sorted from highest to lowest.)
  3. Merge all sub-lists together to form a single list again

Examples:

Inputs: n=7 and [3,2,1,-4,5,6,17,2,0,3,5,4,66,-7,7,6,-5,2,10]
Step 1: [[3,2,1,-4,5,6,17],[2,0,3,5,4,66,-7],[7,6,-5,2,10]]
Step 2: [[-4,1,2,3,5,6,17],[-7,0,2,3,4,5,66],[10,7,6,2,-5]]
Step 3 / Output: [-4,1,2,3,5,6,17,-7,0,2,3,4,5,66,10,7,6,2,-5]

Inputs: n=4 and [7,4,-8,9,3,19,0,-23,-13,13]
Step 1: [[7,4,-8,9],[3,19,0,-23],[-13,13]]
Step 2: [[-8,4,7,9],[-23,0,3,19],[13,-13]]
Step 3 / Output: [-8,4,7,9,-23,0,3,19,13,-13]

Challenge rules:

  • The integer input n is guaranteed to be larger than 1.
  • The size of the integer-list is guaranteed to be larger than n.
  • The trailing sub-list can be smaller than n (as can be seen in the examples and test cases).
  • I/O format is flexible in any reasonable format. Can be a list/array of integers or decimals, a comma/space/newline delimited string, stream of integers, etc. (Output may not be a 2D list of lists like step 2. Step 3 to flatten it back into a single list is required for this challenge.)

General rules:

  • This is , so shortest answer in bytes wins.
    Don't let code-golf languages discourage you from posting answers with non-codegolfing languages. Try to come up with an as short as possible answer for 'any' programming language.
  • Standard rules apply for your answer, so you are allowed to use STDIN/STDOUT, functions/method with the proper parameters and return-type, full programs. Your call.
  • Default Loopholes are forbidden.
  • If possible, please add a link with a test for your code.
  • Also, adding an explanation for your answer is highly recommended.

Test cases:

Inputs: n=7 and [3,2,1,-4,5,6,17,2,0,3,5,4,66,-7,7,6,-5,2,10]
Output: [-4,1,2,3,5,6,17,-7,0,2,3,4,5,66,10,7,6,2,-5]

Inputs: n=4 and [7,4,-8,9,3,19,0,-23,-13,13]
Output: [-8,4,7,9,-23,0,3,19,13,-13]

Inputs: n=2 and [7,-3,1]
Output: [-3,7,1]

Inputs: n=3 and [1,6,99,4,2]
Output: [1,6,99,4,2]

Inputs: n=2 and [5,2,9,3,-5,-5,11,-5,4,12,9,-2,0,4,1,10,11]
Output: [2,5,3,9,-5,-5,-5,11,4,12,9,-2,4,0,10,1,11]

Inputs: n=3 and [5,2,9,3,-5,-5,11,-5,4,12,9,-2,0,4,1,10,11]
Output: [2,5,9,-5,-5,3,-5,4,11,12,9,-2,4,1,0,11,10]

Kevin Cruijssen

Posted 2018-08-17T11:36:47.333

Reputation: 67 575

Answers

5

Brachylog, 18 17 16 bytes

ġ₎↔ḍ↔{izo₎ᵐ↔}ᶠcc

Try it online!

-1 byte thanks to @sundar

Expects input as [<integer list>, n]. Note that negative integers are represented with _, Brachylog's "low minus". Output variable is R.

First time attempting Brachylog, so I imagine it's sub-optimal and ripe for reducing in bytes.

Explanation

Partition, bifurcate, sort based on index (0: asc, 1: desc), flatten.

ġ₎               | split head of input into groups of length n (last of list)
  ↔              | reverse so that...
   ḍ             | dichotomize splits in two, attaching any additional element to the second list
    ↔            | reverse so first half of partitions corresponds to the 0 index
     {      }    | apply
      i          | : append index
       z         | : zip each sublist with the index of its parent
        o₎ᵐ      | : map over sublists, ordering by the zipped index
           ↔     | : undo earlier reverse
             ᶠ   | find all outputs
              cc | flatten two levels

redundancy

Posted 2018-08-17T11:36:47.333

Reputation: 241

A small tweak to your second solution, to get 17 bytes: Try it online!

– sundar - Reinstate Monica – 2018-08-19T19:33:18.667

@sundar I had a sneaking suspicion I was mapping one too many, thanks! – redundancy – 2018-08-19T20:09:32.857

What is this language for? – Sam Orozco – 2018-08-21T21:38:47.953

@SamOrozco Terse declarative logic programming. Try clicking on the language name! – Adám – 2018-08-21T21:52:44.013

3

Jelly, 9 bytes

sṢ€ŒHUÐeF

Try it online!

Mr. Xcoder

Posted 2018-08-17T11:36:47.333

Reputation: 39 774

1I don't understand why this programming language exists. – Sam Orozco – 2018-08-21T21:39:07.017

@SamOrozco It's sole purpose is to solve problems with as short code as possible. – Adám – 2018-08-21T21:55:05.913

Oh, really. That's cool. – Sam Orozco – 2018-08-21T22:05:09.700

2

Python 2, 82 bytes

lambda n,l:sum([sorted(l[i:i+n],reverse=i>len(l)/2)for i in range(0,len(l),n)],[])

Try it online!

TFeld

Posted 2018-08-17T11:36:47.333

Reputation: 19 246

2

05AB1E (legacy), 9 bytes

ô€{2ä`í«˜

Try it online!

Try it online! in 05AB1E (Elixir rewrite) – expects input to be on the stack, a default I/O method.

Kevin came up with his own 11-byter which I used to get to 10. Then I came up with something else for 9 bytes.

Mr. Xcoder

Posted 2018-08-17T11:36:47.333

Reputation: 39 774

Nice one. Here was my initial solution as 11-byte alternative: ô€{2äRć€R)˜.

– Kevin Cruijssen – 2018-08-17T12:29:42.373

1@KevinCruijssen Got to 10 using your approach haha. EDIT: 9 now! – Mr. Xcoder – 2018-08-17T12:36:49.810

Ah, nice. Completely forgot about í. And nice additional golf. – Kevin Cruijssen – 2018-08-17T13:46:36.383

2

Japt, 10 bytes

òV ®nÃÇwÃc

Also 10 bytes
òV mn ow c

Try it online!

Luis felipe De jesus Munoz

Posted 2018-08-17T11:36:47.333

Reputation: 9 639

2

JavaScript (ES6), 82 81 bytes

Saved 1 byte thanks to @redundancy

Takes input as (list)(n).

a=>n=>(g=z=>a+a?[...a.splice(0,n).sort((x,y)=>1/z?x-y:y-x),...g(a[i+=n])]:a)(i=0)

Try it online!

Arnauld

Posted 2018-08-17T11:36:47.333

Reputation: 111 334

Since a is one-dimensional, I believe you can replace a>[] with a+a to check the non-empty case and save 1 byte. Really clever recurive strategy for partitioning and determining when to reverse the sort, as well! – redundancy – 2018-08-19T18:56:50.013

@redundancy That should be safe indeed. Thanks! – Arnauld – 2018-08-19T21:46:00.633