Reliably Broken Sort

23

2

Given a list of positive integers that contains at least 3 distinct entries, output a permutation of that list that isn't sorted in ascending or descending order.

Examples

1,2,3 -> 2,1,3 or 3,1,2 or 1,3,2 or 2,3,1
1,2,3,3 -> 2,1,3,3 or 3,1,2,3 or 1,3,2,3 etc..

Thanks @Arnauld and @NoOneIsHere for the title!

flawr

Posted 2017-08-13T19:54:27.620

Reputation: 40 560

Will the input always be sorted? – xnor – 2017-08-13T20:31:06.170

Must the sort be "reliable" in that given a given set of entries, it always produces the same permutation as output? Or must it only be "reliable" in that the output is not sorted? – Wildcard – 2017-08-15T03:16:16.450

It must just satisfy the specs. – flawr – 2017-08-15T14:58:29.213

Would a nested array be allowed as output? e.g., [2,[1,3]]. – Shaggy – 2017-08-19T09:51:12.830

No, it should be one single array/list. – flawr – 2017-08-19T11:47:34.023

Answers

14

JavaScript (ES6), 39 34 bytes

a=>[a.sort((x,y)=>x-y).pop(),...a]

Sort the array in ascending order, pop the last element and use it as the first element of a new array. Then destructure the remaining elements of the original array into the new array (In JS, both sort and pop modify the original array).


Test it

o.innerText=(f=

a=>[a.sort((x,y)=>x-y).pop(),...a]

)(i.value=[1,2,3]);oninput=_=>o.innerText=f(i.value.split`,`)
<input id=i><pre id=o>

Shaggy

Posted 2017-08-13T19:54:27.620

Reputation: 24 623

Why cant you just do a.sort()? – geokavel – 2017-08-14T14:47:36.010

1@geokavel: Because JS's sort method sorts lexicographically. – Shaggy – 2017-08-14T14:50:06.713

3So because it's already unreliably broken? =D – jpmc26 – 2017-08-15T04:12:37.983

10

Brachylog, 2 bytes

o↻

Try it online!

or

o↺

Try it online!

Sorts then rotates the list

DanTheMan

Posted 2017-08-13T19:54:27.620

Reputation: 3 140

7

Jelly, 3 bytes

Ṣṙ1

Try it online!

Erik the Outgolfer

Posted 2017-08-13T19:54:27.620

Reputation: 38 134

Ṣṙ- also works (just felt like saying that; you probably knew :P) – HyperNeutrino – 2017-08-13T20:05:43.207

@HyperNeutrino Yep that works too, same bytecount :p – Erik the Outgolfer – 2017-08-14T07:43:25.563

In which encoding is Ṣṙ1 only three bytes? In UTF-8, it's 7 bytes. – heinrich5991 – 2017-08-15T00:46:19.900

2

@heinrich5991 Jelly uses a custom codepage.

– cole – 2017-08-15T00:54:38.567

I feel like everyone who uses Jelly must have a browser extension which adds a button to automatically post the "Jelly uses a custom codepage" comment. – 12Me21 – 2017-10-21T05:13:07.297

6

Ohm, 2 bytes

S╙

Try it online!

Sort and rotate to the right.

totallyhuman

Posted 2017-08-13T19:54:27.620

Reputation: 15 378

6

Japt, 3 bytes

n é

Test it

Sorts (n) the array and rotates it (é) one element to the right.

Shaggy

Posted 2017-08-13T19:54:27.620

Reputation: 24 623

5

APL, 9 bytes

{1⌽⍵[⍋⍵]}

Try it online!

How?

⍵[⍋⍵] - sort the list

1⌽ - rotate by 1

Uriel

Posted 2017-08-13T19:54:27.620

Reputation: 11 708

Also works in GNU and ngn! – Zacharý – 2017-08-13T20:32:27.090

@Zacharý guess I'll just remove the dyalog... – Uriel – 2017-08-13T20:37:18.803

5

Python 3, 31 bytes

lambda a:sorted(a)[1:]+[min(a)]

Try it online!

-1 byte thanks to xnor

HyperNeutrino

Posted 2017-08-13T19:54:27.620

Reputation: 26 575

...How did I not see this basic logic. >.> – totallyhuman – 2017-08-13T20:02:16.640

@totallyhuman lol all 3 of my answers do the exact same thing. but ha :P Also I merged your PR for iOS -> MacOS :P – HyperNeutrino – 2017-08-13T20:02:53.120

Yeah, I noticed and deleted my branch. :P – totallyhuman – 2017-08-13T20:04:06.010

Putting the min at the end saves a byte. – xnor – 2017-08-13T20:11:16.433

5

Pyth, 7 5 4 bytes

.P1S

Try it online!

-1 byte thanks to FryAmTheEggman

NoOneIsHere

Posted 2017-08-13T19:54:27.620

Reputation: 1 916

You can save a byte by using permutations: https://pyth.herokuapp.com/?code=.P1S&input=%5B314%2C+112%2C+938%2C+792%2C+309%2C+308%5D&debug=0

– FryAmTheEggman – 2017-08-13T20:52:42.890

@FryAmTheEggman thanks, I'll update it when I get to a computer. – NoOneIsHere – 2017-08-13T21:13:41.117

5

TI-Basic (TI-84 Plus CE), 31 bytes

Prompt A
SortA(LA
max(LA→B
dim(LA)-1→dim(LA
augment({B},LA

Prompts for input in the format {1,2,3,4}.

TI-Basic is a tokenized language, all tokens used here are one-byte.

Explanation:

Prompt A         # 3 bytes, store user input in LA
SortA(LA         # 4 bytes, sort LA ascending
max(LA→B         # 6 bytes, save the last value in the sorted list to B
dim(LA)-1→dim(LA # 11 bytes, remove the last value from LA
augment({B},LA   # 7 bytes, prepend B to LA and implicitly print the result

pizzapants184

Posted 2017-08-13T19:54:27.620

Reputation: 3 174

4

05AB1E, 2 bytes

Try it online!

HyperNeutrino

Posted 2017-08-13T19:54:27.620

Reputation: 26 575

4

05AB1E, 2 bytes

Try it online!

Uriel

Posted 2017-08-13T19:54:27.620

Reputation: 11 708

2Ninja'd (almost) :P – HyperNeutrino – 2017-08-13T20:03:33.713

3

Retina, 21 bytes

O#`
s`(.*)¶(.*)
$2¶$1

Try it online! Sort and rotate as per usual. At least there's no unary conversion this time.

Neil

Posted 2017-08-13T19:54:27.620

Reputation: 95 035

3

Java 8, 68 37 bytes

l->{l.sort(null);l.add(l.remove(0));}

-31 bytes thanks to @Nevay (forgot Java 8 had a List#sort(Comparator) method..)

Modifies the input-ArrayList, instead of returning a new one.

Explanation:

Try it here.

l->{                   // Method with ArrayList parameter and no return-type
  l.sort(null);        //  Sort the input-list (no need for a Comparator, thus null)
  l.add(l.remove(0));  //  Remove the first element, and add it last
}                      // End of method

Kevin Cruijssen

Posted 2017-08-13T19:54:27.620

Reputation: 67 575

You can use l->{l.sort(null);java.util.Collections.rotate(l,1);} to save 16 bytes. – Nevay – 2017-08-14T12:19:31.780

2Alternatively you can use l->{l.sort(null);l.add(l.remove(0));} to save 31 bytes (requires the usage of a not fixed sized list). – Nevay – 2017-08-14T12:24:52.617

@Nevay nice one, but... the parentheses are a bit off in regards to the documentation: the reality is that the optional operations add and remove must be implemented; nothing is said about fixed-sized list... Kevin Cruijssen, given that there are much better alternatives in the previous comments, I'll wait for an edit before +1ing. – Olivier Grégoire – 2017-08-14T13:52:27.277

3

Haskell, 36 37 bytes

import Data.List
f(a:b)=b++[a];f.sort

Use view patterns to match on the head of a sorted version of the input list, then append the first item of the list to the tail of the remaining list.

View patterns aren't worth it. Sort the list, take the head off, append it to the end. In this case, it turns out that the naive solution typed out compactly is the best.

typedrat

Posted 2017-08-13T19:54:27.620

Reputation: 31

1Welcome to PPCG! Great idea to use view patterns, I didn't know about them before. Unfortunately, they are not enabled in standard Haskell, so per site rules you need to include the bytes for the command line flag -XViewPatterns. Counting those the standard way f(a:b)=b++[a];f.sort is shorter. – Laikoni – 2017-08-15T18:57:47.103

I somehow wasn't thinking about the flag needed. I guess I use them so much that I forgot that I turn it on in my Cabal files and that it's not part of the language. – typedrat – 2017-08-16T19:37:52.020

2

Perl 6,  43  19 bytes

{first {![<=]($_)&&![>=] $_},.permutations}

Try it

*.sort[1..*,0].flat

Try it

Note that [1..*,0] would result in ((2,3),1), so .flat is there to turn it into (2,3,1)

Brad Gilbert b2gills

Posted 2017-08-13T19:54:27.620

Reputation: 12 713

2

Mathematica, 18 bytes

RotateLeft@Sort@#&

Try it online!

J42161217

Posted 2017-08-13T19:54:27.620

Reputation: 15 931

4Shorter: RotateLeft@*Sort – JungHwan Min – 2017-08-14T03:46:19.853

2

Ly, 7 bytes

&nasprl

Try it online!

Ugh, ruining the sort is so expensive!

Explanation:

&nasprl

&n      # take input as a list of numbers
  a     # sort
   sp   # save top of stack and pop
     r  # reverse stack
      l # load saved item

LyricLy

Posted 2017-08-13T19:54:27.620

Reputation: 3 313

2

R, 33 32 29 bytes

Takes input from stdin. Sorts the list and then moves the first element to the end, ensuring that it is no longer sorted. Saved three bytes due to Giuseppe.

c(sort(x<-scan())[-1],min(x))

Another implementation, same byte count:

c((x<-sort(scan()))[-1],x[1])

rturnbull

Posted 2017-08-13T19:54:27.620

Reputation: 3 689

c(sort(x<-scan())[-1],min(x)) is 29 bytes using essentially the same idea as yours. – Giuseppe – 2017-08-29T21:15:54.097

1

Proton, 19 bytes

a=>sorted(a)[1to,0]

Try it online!

-2 bytes indirectly thanks to xnor

Not yet working on TIO; waiting for a pull.

HyperNeutrino

Posted 2017-08-13T19:54:27.620

Reputation: 26 575

1

Ohm, 2 bytes

S╜

Try it online!

I think this is dissimilar enough from totallyhuman's post to post a new answer; I hope you don't mind :P EDIT: DAMMIT YOU NINJA'D ME

HyperNeutrino

Posted 2017-08-13T19:54:27.620

Reputation: 26 575

Ninja'd you. ;) – totallyhuman – 2017-08-13T20:11:16.997

1

Python, 31 bytes

def f(a):a[1:]=a[a.sort():0:-1]

Yet another Python solution.

Sadly, this one has the same length to HyperNeutrino's answer.

tsh

Posted 2017-08-13T19:54:27.620

Reputation: 13 072

1

C# (Mono), 76 67 bytes

using System.Linq;a=>a.OrderBy(n=>n).Skip(1).Concat(new[]{a.Min()})

Saved 9 bytes thanks to @Patrick Stephansen.

Try it online!

TheLethalCoder

Posted 2017-08-13T19:54:27.620

Reputation: 6 930

1Save a few bytes: a=>a.OrderBy(n=>n).Skip(1).Concat(new[]{a.Min()}) – Patrick Stephansen – 2017-08-15T10:42:51.023

1

PHP, 44 bytes

requires PHP 5.4 or later for short array syntax.

sort($a=&$argv);print_r([array_pop($a)]+$a);

sort arguments, replace 0-th argument with removed last argument, print.
Run with -nr or try it online.


The 0-th argument is the script file name, "-" if you call PHP with -r. "-" is compared to the other arguments as a string, and since ord("-")==45, it is smaller than any number. The numbers themselves, although strings, are compared as numbers: "12" > "2".

php -nr '<code>' 3 4 2 5 1 and sort($a=&$argv) lead to $a=["-","1","2","3","4","5"]
[array_pop($a)]+$a is [0=>"5"]+[0=>"-",1=>"1",2=>"2",3=>"3",4=>"4"],
which results in [0=>"5",1=>"1",2=>"2",3=>"3",4=>"4"].

Titus

Posted 2017-08-13T19:54:27.620

Reputation: 13 814

Can you explain why [array_pop($a)]+$a doesn't overwrite the 0th index of $a? For example: $a=[1,2,3,4,5], array_pop($a) = 5, $a=[1,2,3,4]. If you do [5]+[1,2,3,4], shouldn't it end up being [5,2,3,4] because both arrays have a 0th index?

I'm confused because the PHP manual says "The + operator returns the right-hand array appended to the left-hand array; for keys that exist in both arrays, the elements from the left-hand array will be used, and the matching elements from the right-hand array will be ignored." – jstnthms – 2017-08-14T23:08:30.000

@jstnthms The + operator does not append, it merges (without reordering the indexes; but that doesn´t matter here). The important point is that $a points to $argv and $argv[0] contains the script´s file name, the arguments start at index 1. I extended the description. Thanks for the question. – Titus – 2017-08-15T07:49:13.557

1

Pyth, 5 bytes

.>SQ1

Explanation

SQ - sort input list

.>SQ1 - rotate input list cyclicaly by 1

Karan Elangovan

Posted 2017-08-13T19:54:27.620

Reputation: 179

1

Retina, 10 bytes

O#`
O^#-2`

Try it online!

O#`     Sort the list
O^#-2`  Reverse sort the list other than the last element

This leaves the list with the 2nd highest element first and the highest element last which is never correctly sorted

PunPun1000

Posted 2017-08-13T19:54:27.620

Reputation: 973

1

Gaia, 3 bytes

ȯ1«

Try it online!

Same as other answers: sort ȯ and rotate left once .

Business Cat

Posted 2017-08-13T19:54:27.620

Reputation: 8 927

1

Ruby, 18 bytes

Submitted on mobile. Please don't kill me for problems.

->a{a.sort.rotate}

dkudriavtsev

Posted 2017-08-13T19:54:27.620

Reputation: 5 781

1

Python 3, 28 bytes

lambda a:a[1:a.sort()]+a[:1]

Try it online!

a.sort() sorts a in place and returns None. None can be used as a slicing index and is the same as omitting that index.

Business Cat

Posted 2017-08-13T19:54:27.620

Reputation: 8 927

1

Python 3, 31 bytes

lambda a:a.sort()or[a.pop(),*a]

Try it online! or Verify all test cases.

Inspired by Shaggy's JS answer.

Pi-votal

Posted 2017-08-13T19:54:27.620

Reputation: 11

1

RProgN 2, 2 bytes

§›

Try it online!

ATaco

Posted 2017-08-13T19:54:27.620

Reputation: 7 898

1

Julia, 23 bytes

f(x)=sort(x)[[2:end;1]]

Slightly shorter than, but equivalent to f(x)=circshift(sort(x),1). I wish I could makeamethod based on select that was more, compact but I can not

Lyndon White

Posted 2017-08-13T19:54:27.620

Reputation: 1 021

1

Common Lisp, 52 bytes

(let((x(sort(read)'<)))(rotatef(nth 0 x)(nth 1 x))x)

Try it online!

Renzo

Posted 2017-08-13T19:54:27.620

Reputation: 2 260

1

Clojure, 36 bytes

#(let[s %](cons(last s)(butlast s)))

Stole the solution to sort it and push the last element to the start of the list.

Joshua

Posted 2017-08-13T19:54:27.620

Reputation: 231

1

TeX - 207 183 bytes

\def\a#1 #2 #3 #4 {\ifnum#2#1#3\def\e{#3 #4 #2 }\else\def\e{#2 #4 #3 }\fi\e}\def\b#1 #2 #3 {\a< #1 #2 \a> #3 {} }\def\c#1 #2 {\ifnum#1=#2\let\b\f\def\d#1 {#1 \c}\else\let\d\b\fi\d#1 #2 }\def\f#1 #2 {#2 #1 }

This is the best I can do with a language that doesn't really have data structures, or many builtins.

The approach is to take the first three numbers we find, and do a broken sort as follows: Sort the first two by greater, and then take the second two by lesser. This should always result in our list being unsorted. It's convenient to ignore anything but the first 3 unique inputs.

We also have a check for two of the same number in a row. In that case, we scan ahead until we find a different number, and then switch the two, ensuring that our list is out of order.

I'm gonna work on golfing this down, but it's the best approach I can think of.

EDIT: Considerable work has been put in to this, to make it more golfy and also actually work. So here it is:

\let~\def~\a#1 #2 {\if^#2~\e{\box9 #1 }\else\ifnum#1\h#2~\e{\hbox{#1 }\a#2 }\else~\e{\hbox{#2 }\a#1 }\ifnum#1=#2~\h{=}\setbox9=\lastbox\fi\fi\fi~\g{>}\e}~\g{<}~\h{\g}\everypar{\a}\x^

I changed the the method from inserting things into the input to one where we recurse, replaced \expandafter with \everypar, and added that when it finds an equal number, it grabs the last number typeset and saves it until the second to last slot, ensuring that 1 2 2 (the case that secretly broke the previous answer) will be incorrectly sorted as 2 1 2.

This is just a function, to properly use it you need to: have input stored on the variable \x (or you could type in a list of numbers, with a ^ as a delimeter).

If you'd really like to try this, then do this

\read1to\x    

before the lines of this function.

A Gold Man

Posted 2017-08-13T19:54:27.620

Reputation: 280

0

Ruby, 20 bytes

->(x){x.sort.rotate}

I can't figure out how to use lambdas on TIO, but I'll add a link when I do

clap

Posted 2017-08-13T19:54:27.620

Reputation: 834

0

SmileBASIC, 33 bytes

DEF B A
SORT A
PUSH A,SHIFT(A)END

Modifies the array in place. This uses the simple sort+rotate algorithm, though there may be a shorter solution involving RINGCOPY or something (the problem being that COPY and RINGCOPY don't work well when copying between overlapping parts of the same array)

12Me21

Posted 2017-08-13T19:54:27.620

Reputation: 6 110