25
\$\begingroup\$

Slap sort is such a sorting strategy:

  • Repeatedly move to end the first element which is larger than the following element, until sorted(aka. no such element exist).

This is easily coded when elements are stored in a gravity stack, e.g. in game EXAPUNKS.

Now, given some values, count how many operations done during this sorting process.

I decide that input is a permutation of {1,2,3,...,n} since that shouldn't help a pure simulation but may help formula-based solution(if it exists) which I encourage.

Example

Given array [3,2,1], it goes like following:

[3]2 1
[2]1 3
 1[3]2
 1 2 3

which takes 3 steps.

Test cases

3,2,1 => 3
1,3,5,2,4 => 5
1,2,5,3,4 => 1
3,6,5,4,1,2 => 10
2,5,1,3,4 => 8

Shortest code in each language wins.

\$\endgroup\$
9
  • 3
    \$\begingroup\$ For a reversed sequence \$n,n-1,\dots,1\$, the result is \$T(n)\$. \$\endgroup\$ Commented Mar 22 at 5:48
  • 1
    \$\begingroup\$ This also holds for any sequence of length \$n\$ ending with \$1\$. \$\endgroup\$ Commented Mar 22 at 5:54
  • 2
    \$\begingroup\$ The average result for a sequence of length \$n\$ is a little over \$T(n-1)\$. This approximation improves as \$n\$ increases. \$\endgroup\$ Commented Mar 22 at 10:40
  • 1
    \$\begingroup\$ @ShadowRanger A sorted array is one with smallest order given same of all permutation, so even if it's not a permutation of 1..n a>sorted(a) and a!=sorted(a) should work same \$\endgroup\$ Commented Mar 23 at 16:37
  • 1
    \$\begingroup\$ @PeterCordes It's used in game where typically <20 elements to sort so complexity isn't an issue, but there's only one register and one pointer. This allows writing (EXAPUNKS) Retry:while(p[0]/*require use of register*/<=p[1])++p;reg=*p;erase(*p);p=end();put(p,reg);p=begin();goto Retry; Also I'm recently on Manufactoria where data is stored in a queue and slap sort on binary array take O(n) steps or say O(n^2) queue operations. \$\endgroup\$ Commented Mar 24 at 21:55

20 Answers 20

9
\$\begingroup\$

R, 56 bytes

f=\(l)`if`(i<-match(F,diff(l)>0,0),1+f(c(l[-i],l[i])),0)

Attempt This Online!

Simulation, sorry.

\$\endgroup\$
8
\$\begingroup\$

x86 machine code, 56 50 bytes

  • My program sorts the array directly from the command-line. It makes no difference whether we sort integers [1,9] or ASCII codes ["1","9"].
  • This is a full application. Submitting it as a function, it could have been a mere 20 bytes, depending on what input/output registers we choose.
  • For code-golfing, I rely on a few registers that DOS gives a particular value at program start: AX=0, BX=0 and CX=255.
  • Use FASM to assemble this.
  • The hexdump is in the second column of the following listing:
               1       ORG   256        ; AX=0, BX=0, CX=255
               2
0100  BE8200   3 redo: mov   si, 130    ; Start array in command-line
0103  8A4CFE   4       mov   cl, [si-2] ; CH=0, Length command-line
0106  80E902   5       sub   cl, 2      ; Number of comparisons
0109  760F     6       jbe   done       ; Less than 2 array elements
010B  89F7     7 next: mov   di, si
010D  AC       8       lodsb
010E  3A04     9       cmp   al, [si]
0110  7606    10       jbe   cont       ; Correct order
0112  F3A4    11       rep movsb        ; Move down and
0114  AA      12       stosb            ; store at rear end
0115  43      13       inc   bx         ; Tally moves
0116  EBE8    14       jmp   redo
0118  E2F1    15 cont: loop  next
              16
011A  93      17 done: xchg  ax, bx     ; -> AX is Number of moves, BH=0 DisplayPage
011B  B10A    18       mov   cl, 10     ; CH=0, CONST
011D  51      19       push  cx         ; Sentinel
011E  99      20 .a:   cwd
011F  F7F1    21       div   cx
0121  52      22       push  dx
0122  85C0    23       test  ax, ax
0124  75F8    24       jnz   .a
0126  58      25       pop   ax
0127  05300E  26 .b    add   ax, 0E30h  ; -> AH is BIOS.Teletype, AL is ["0","9"]
012A  CD10    27       int   10h
012C  58      28       pop   ax
012D  39C8    29       cmp   ax, cx
012F  72F6    30       jb    .b
0131  C3      31       ret

All of the suggested test cases work fine.

\$\endgroup\$
7
\$\begingroup\$

Google Sheets, 209 164 bytes

=let(s,sequence(rows(a)),i,+filter({0;s},{0;a}>{a;9^9}),b,{filter(a,s<i);filter(a,s>i);index(a,i)},if(isna(i),n,f({filter(a,s<i);filter(a,s>i);index(a,i)},n+1)))

Recursive named function with signature f(a, n) that slap sorts values in a column and outputs the count of rounds. You can call the named function from a formula as in =f(A1:A3,) or =f(tocol(A:A,1),).

You can also implement the function as a recursive lambda that can be directly pasted in a cell:

screenshot

Ungolfed debug version:

=let( 
  f, lambda(f, arr, n, let(
    a, filter(arr, isnumber(arr)),
    s, sequence(rows(a)),
    i, +filter({ 0; s }, { 0; a } > { a; 9^9 }),
    b, vstack(
      "head", filter(a, s < i),
      "tail", filter(a, s > i),
      "pivot", index(a, i)
    ),
    if(isna(i),
      vstack("count", n, arr), 
      f(f, b, n + 1)
    )
  )),
  f(f, tocol(A:A, 1), 0)
)

Outputs count, head, tail and pivot from the last round.

formula-based solution(if it exists) which I encourage

...it's one kind of a formula.

\$\endgroup\$
6
\$\begingroup\$

JavaScript (ES6), 58 bytes

Just applies the slap sort algorithm.

f=a=>a.some((v,i)=>q=+a.splice(i,v>a[i+1]))&&1+f([...a,q])

Try it online!

Commented

f = a =>           // f is a recursive function taking a[]
a.some((v, i) =>   // for each element v at index i in a[]:
  q =              //   q = either 0 or a copy of v, obtained by
    +a.splice(     //   coercing the result of this splice() to a number:
      i,           //     extract at index i
      v > a[i + 1] //     extract only if v is greater than its successor
    )              //   end of splice()
) &&               // end of some(); if truthy:
  1 +              //   increment the final result
  f([...a, q])     //   do a recursive call with q moved at the end of a[]
                   // (otherwise, the array is fully sorted and we stop)
\$\endgroup\$
5
\$\begingroup\$

Japt, 17 16 15 bytes

Works over the range [1,n].

d§ ©ÒßUñ϶UäÎb1

Try it or run all test cases

d§ ©ÒßUñ϶UäÎb1     :Implicit input of array U
d                   :Is any element
 §                  :  Less than or equal to its (implicit) 0-based index
   ©                :Logical AND with
    Ò               :  Negate the bitwise NOT of
     ß              :    A recursive call with argument
      Uñ            :      U sorted by
        Ï           :      Passing each index through the following function
         ¶          :        Is equal to
          Uä        :          Consecutive pairs of U
            Î       :          Reduced by the signs of their differences
             b1     :          First index of 1
\$\endgroup\$
4
\$\begingroup\$

Python 3,  72  71 bytes

-1 thanks to l4m2! (Don't handle empty inputs, allowing changing []<a[i+1:] to ~i+len(a).)

f=lambda a,i=0:~i+len(a)and(a[i]>a[i+1]and-~f(a+[a.pop(i)])or f(a,i+1))

A recursive function that accepts a non-empty list that's a permutation of \$[1,N]\$, and returns the slap sort iteration count (with False quacking like zero).

Try it online!

\$\endgroup\$
4
  • 1
    \$\begingroup\$ Very nice! I can see the relationship to mine, but you went the extra step of having the recursive process perform the sorting itself to shave a few more bytes (sorted() is just so long to type!). \$\endgroup\$ Commented Mar 24 at 15:32
  • 1
    \$\begingroup\$ "If it looks like a duck, swims like a duck, and quacks like a duck, then it probably is a duck". I didn't really have time to look at a lambda solution and just made a quick fix then golfed it as much as possible :) Very nice solution. \$\endgroup\$ Commented Mar 24 at 19:33
  • 1
    \$\begingroup\$ 71 failing empty input \$\endgroup\$ Commented Mar 25 at 1:20
  • \$\begingroup\$ Thanks, @l4m2 :) \$\endgroup\$ Commented Mar 25 at 20:32
3
\$\begingroup\$

Jelly, 11 bytes

=Þx>ƝḢƊ$ƬL’

A monadic Link that accepts a permutation of \$[1,N]\$, and yields the slap sort iteration count.

Try it online! Or see the test-suite.

How?

Perform the sort.

=Þx>ƝḢƊ$ƬL’ - Link: list of distinct items, A
        Ƭ   - start with X=A, and collect up while distinct, applying:
       $    -   last two links as a monad - f(X):
      Ɗ     -     last three links as a monad - f(X):
   >Ɲ       -       neighbour-wise greater than? -> [x1>x2, x2>x3, ...]
  x         -       {X} repeated by {those} (vectorises)
     Ḣ      -       head -> the first value in X preceding a decrease (or 0 if none)
 Þ          -     sort {X} by:
=           -       is {element} equal to {the first value preceding a decrease}
         L  - length -> number of states
          ’ - decrement -> number of iterations
\$\endgroup\$
3
\$\begingroup\$

R, 91 bytes

f=\(x)`if`(length(x)-1,{i=which.min(x);i-1+f(c(x[-seq_len(i)],sort(x[seq_len(i-1)],T)))},0)

This is not shorter than pajonks's answer but uses a slightly different (more formulaic?) approach. Instead of iterating through the sequence to find the index where it decreases then slapping and recursing, this answer makes use of the observation that the smallest element must pass all elements before it, requiring exactly i-1 slaps if it is at index i. Those i-1 slaps are collapsed to one step, and then the list is reconstructed as it would appear after those moves followed by the preceding elements in decreasing order. More bytes, but fewer iterations for many cases?

Attempt this online

\$\endgroup\$
5
  • 1
    \$\begingroup\$ I don't think you can guarantee that the preceding elements are slapped in decreasing order, but sadly I've since closed the tab where I think I had a counterexample open. \$\endgroup\$ Commented Mar 25 at 9:19
  • \$\begingroup\$ some golfs to the code without changing the logic for -16 bytes \$\endgroup\$ Commented Mar 25 at 13:19
  • \$\begingroup\$ @Neil I searched through some randomly generated test-cases and didn't find one (which doesn't mean there isn't one). \$\endgroup\$ Commented Mar 25 at 13:23
  • \$\begingroup\$ @pajonk I think you're right and I had been looking for a counterexample to a different optimisation. \$\endgroup\$ Commented Mar 25 at 13:55
  • \$\begingroup\$ @pajonk What might be happening is that the preceding elements are slapped in an order which always takes \$T(n-1)\$ more slaps. It just so happens that descending order is one of those orders. \$\endgroup\$ Commented Mar 25 at 13:59
3
\$\begingroup\$

Rust, 144 124 110 108+ 107 bytes

The + is was to take into account the possibility of values outside of u8 or i8 range requiring one or a few extra bytes.

|l:&mut[_]|{let mut r@mut i=0;while!l.is_sorted(){while l[i]<=l[i+1]{i+=1}l[i..].rotate_left(1);i=0;r+=1}r}

ungolfed and explained:

// `|l:&mut[_]|` has the integer and the return type
// inferred by the compiler, default numeric is `i32`
// The benefit of the closure syntax is that it's shorter.
// &mut [_] means a borrowed mutable list-like type (slice).
fn slap_sort(list: &mut [i32]) -> usize {
  // The @ pattern assigns if the right pattern holds. Because declaration
  // is an irrefutable pattern, 'let mut r@mut i=0;' just shaves off an extra
  // 'let ' and a ';', for a single character. -4 bytes!
  let mut ret_val = 0; // r half of mut r@mut i=0, context dictates the type.
  let mut idx = 0; // i half of the same. Because it's used as index,
                   // it's now always a usize
  while !list.is_sorted() {
    // Increment idx until l > r, which must happen because the list
    // is not yet sorted as per the outer loop.
    // unfortunately Rust does not have increment operators (++)
    while list[idx] <= l[idx+1] { i += 1; }
    // Moves the leftmost element of the subslice starting at idx
    // to the end, shifts the rest one position back
    list[i..].rotate_left(1);
    idx = 0; // reset for next run
    ret_val += 1; // increment the amount of "slaps" in sorting
    break // break the inner loop and check all pairs again
    // This also prevents checking beyond the end of the list as
    // `i` can only ever be the last element's index when the list is sorted.
    // And the loop is never entered in that case!
  }
  ret_val // implicit return
}

Try it on the Rust Playground


Changes:

  • Realized I didn't need the else in else if, shaves off 5 bytes
  • Then while editing, realized while !is_sorted() omits an entire comparison and lets the range be exclusive, shaving off another 10
  • Inner loop cleanup for another 5
  • Realized I could work with unbounded ranges and rotation on slices
  • Shaved off another 2 thanks to @ShadowRanger suggesting a while instead of for + if
  • Let the compiler infer the integer type for -1

I omitted the optional surrounding parentheses (to allow immediately calling the closure) or assigning to a variable after reading lang-specific rules. The examples for several langs omit ceremonial boilerplate (e.g. JS examples don't assign to variables either).

\$\endgroup\$
6
  • 1
    \$\begingroup\$ On "I omitted [...] assigning to a variable", yeah, you only need to assign closures to variables if the function is recursive (in which case you need a name to call it by), so omitting it here it completely fair. I love how .rotate_left(1) on a slice does exactly what we need here, very clever, and a weird demonstration of how well Rust's standard library and language features work together to accomplish novel tricks in a weirdly pleasant fashion. \$\endgroup\$ Commented Mar 24 at 15:57
  • 1
    \$\begingroup\$ 107+ bytes. Replacing for i in 0..+if with a while loop that manually increments i lets us avoid a break, and the incremental cost to declare a mut i up front via pattern-matching is pretty small. |l:&mut[u8]|{let mut r@mut i=0;while!l.is_sorted(){i=0;while l[i]<l[i+1]{i+=1}l[i..].rotate_left(1);r+=1}r}. The #[allow(unused_assignments)] isn't strictly necessary, it's just silencing a harmless warning. (Oh, and welcome to CGCC!) \$\endgroup\$ Commented Mar 24 at 16:16
  • \$\begingroup\$ It occurs to me the warning could be avoided by just moving the i=0 to the end of the loop, so it's not replacing the initial value, just resetting for the next loop that may not actually run. But it's fine either way (compile-time warnings aren't a problem). \$\endgroup\$ Commented Mar 24 at 16:29
  • \$\begingroup\$ Oh that's actually a really nice way of shaving down the inner loop! I think that the solution would have to be stuck on 108+, however, as the explanation of the sorting algorithm defines it as a stable sort: "Repeatedly move to end the first element which is larger than the following element, until sorted" Unfortunately this would move equal elements too, even if those do not occur in the example inputs. Actually, a single repeat would make this an infinite loop \$\endgroup\$ Commented Mar 25 at 11:20
  • \$\begingroup\$ The OP specifically says "I decide that input is a permutation of {1,2,3,...,n}" so you don't need to worry about stability or equal elements. \$\endgroup\$ Commented Mar 25 at 23:50
3
\$\begingroup\$

Python, 84 76 74 bytes

f=lambda a,y=0:any(b:=[y>(y:=x)for x in a])and-~f(a+[a.pop(b.index(1)-1)])

Attempt This Online!

Explanation:

  1. Check for out-of-order status at each index, and if any are out of order:
  2. Find the first index with an element larger than the next element, using the list from step 1, and finding the index of the first true value (conveniently, True==1)
  3. pop it out, and concatenate the result with the original list, passing it to a recursive call and adding 1 to the result
  4. Once step 1 finds no elements out of order, return False (numerically 0) and the 1+s count up the number of recursions

Thanks to naffetS and l4m2 for successive improvements.

Update: Drop from 84 to 76 (thanks naffetS!) by:

  • Shaves 4: Dropping pointless or 0 (the False produced by a>sorted(a) is equivalent, and will convert to true int assuming the input isn't sorted from the start
  • Shaves 1: Use -~ to perform 1+ in a way that lets us drop the space after and
  • Shaves 3: Use defaulted y argument and lazily replace/cache it during comparison via walrus to avoid need for ziping at offset. Costs four to define y, and two to adjust index by -1, but saves a lot by avoiding slicing, zip, and unpacking

Update 2: Shave 2 by replacing use of test of a against sorted(a) with a test that constructs and caches the out-of-order status list and simply tests for "is one out of order" without sorting at all, allowing us to reuse said list when finding the index of the first out of order index. sorted(a) was just too long.

\$\endgroup\$
5
  • \$\begingroup\$ 79 bytes? \$\endgroup\$ Commented Mar 23 at 22:40
  • 1
    \$\begingroup\$ 76 \$\endgroup\$ Commented Mar 24 at 2:59
  • 1
    \$\begingroup\$ alternative 76 \$\endgroup\$ Commented Mar 24 at 3:03
  • \$\begingroup\$ Ah, man, you get out of practice for a few months and suddenly forget to use False as 0 and avoid or 0 entirely. And the -~ trick to drop a space. The abuse of the walrus is new to me, though, and delightful! \$\endgroup\$ Commented Mar 24 at 15:15
  • 1
    \$\begingroup\$ Python, 74 bytes: f=lambda a,y=0:any(b:=[y>(y:=x)for x in a])and-~f(a+[a.pop(b.index(1)-1)]) \$\endgroup\$ Commented Mar 24 at 21:40
3
\$\begingroup\$

Charcoal, 28 bytes

WΦθ›κ§⊞Oθ⌈θ⊕λ≔⊕⁺Φθ⌕ικ…ι¹θI⌊θ

Try it online! Link is to verbose version of code. Takes input as a permutation of the integers 0..n-1. Explanation:

WΦθ›κ§⊞Oθ⌈θ⊕λ

"Temporarily" append the maximum element to the input, then find the elements that are greater than the next element. While at least one such element exists, ...

≔⊕⁺Φθ⌕ικ…ι¹θ

... remove all elements that are first in that list from the input and append the first element from that list to the input, then increment all of the elements.

I⌊θ

Output the count of operations.

While the "temporary" elements hang around until the maximum value gets slapped, they don't affect the operation count.

I tried porting @acvill's approach which notes that the operation count is the same if for each value in the range you slap the values above i but before i in the list in descending order; to make things simpler you can them remove i from the list. However the best I could do was 32 bytes:

FLθ«W⌈…θ⌕θι«≔⁻θ⟦κ⟧θ⊞θκ→»≔Φθλθ»Iⅈ

Try it online! Link is to verbose version of code. Takes input as a permutation of the integers 0..n-1. Explanation:

FLθ«

Loop through the input elements in ascending order.

W⌈…θ⌕θι«

While the maximum of the elements before the i element exists...

≔⁻θ⟦κ⟧θ

Remove it from its current position in the list.

⊞θκ

Append it back to the end of the list.

Increment the count of operations.

»≔Φθλθ

Remove the first element from the list; it will be the i element by this point.

»Iⅈ

Output the count of operations.

\$\endgroup\$
2
\$\begingroup\$

Vyxal, 13 bytes

¯±uḟ₌⟇iJ)↔?sḟ

Try it Online!

Yeah, pure simulation is probably the way to go :p

Explained

¯±uḟ₌⟇iJ)↔?sḟ­⁡​‎‎⁡⁠⁤⁡‏‏​⁡⁠⁡‌⁢​‎‎⁡⁠⁣⁣‏⁠‎⁡⁠⁣⁤‏‏​⁡⁠⁡‌⁣​‎‎⁡⁠⁣⁡‏⁠‎⁡⁠⁣⁢‏‏​⁡⁠⁡‌⁤​‎‎⁡⁠⁡‏‏​⁡⁠⁡‌⁢⁡​‎‎⁡⁠⁢‏‏​⁡⁠⁡‌⁢⁢​‎‎⁡⁠⁣‏⁠‎⁡⁠⁤‏‏​⁡⁠⁡‌⁢⁣​‎‎⁡⁠⁢⁡‏⁠‏​⁡⁠⁡‌⁢⁤​‎‎⁡⁠⁢⁢‏⁠‏​⁡⁠⁡‌⁣⁡​‎‎⁡⁠⁢⁣‏⁠‎⁡⁠⁢⁤‏‏​⁡⁠⁡‌­
            ḟ  # ‎⁡Find the index of
          ?s   # ‎⁢the sorted input in
        )↔     # ‎⁣the list generated by repeating the following function until the result does not change:
¯              # ‎⁤  Get the forward differences of the argument
 ±             # ‎⁢⁡  Push the signs of each (1 if positive, -1 if negative)
  uḟ           # ‎⁢⁢  And find the first `-1` (i.e. the first item where it's bigger than the next). Call this index n
    ₌          # ‎⁢⁣  Then create a list of
     ⟇         # ‎⁢⁤    The argument with item n removed
      iJ       # ‎⁣⁡    with item n appended
💎

Created with the help of Luminespire.

\$\endgroup\$
2
\$\begingroup\$

05AB1E, 14 bytes

ΔÐü›Ïн©di®†À]N

Try it online or verify all test cases.

Explanation:

Δ            # Loop until the result no longer changes,
             # using the (implicit) input-list in the first iteration:
 Ð           #  Triplicate the current list
  ü          #  Pop one copy, and map over each overlapping pair [a,b]:
   ›         #   Check a>b
    Ï        #  Pop another copy, and only keep the values at the truthy positions
     н       #  Pop and keep just the first value
      ©      #  Store this value in variable `®` (without popping)
       di    #  Pop, and if it's a digit:
         ®†  #   Move item `®` to the front of the list
           À #   Then rotate the list once counterclockwise,
             #   to put it at the end instead
]            # Close both the if-statement and changes-loop
 N           # Push the last 0-based index of the changes-loop
             # (which will be the 1-based result, since it does one additional
             # loop when it sees there was no change to the list)
             # (which is output implicitly as result)
\$\endgroup\$
2
\$\begingroup\$

Julia, 78 bytes

f(l)=(d=diff(l);all(d.>0) ? 0 : (i=argmin(d);1+f([l[1:i-1];l[i+1:end];l[i]])))

Attempt This Online!

\$\endgroup\$
2
\$\begingroup\$

Vyxal 3, 16 bytes

λ⁜>ṬD[£h∥QiJx|Þ`

Vyxal It Online!

Would probably be shorter by porting lyxal's v2 but this is mine.

λ⑴>oṬD[£h∥QiJx|Þ`
λ                  # ‎⁡execute lambda on input:
   o               # ‎⁢reduce overlapping windows of size 2 with:
 ⑴>                # ‎⁣lambda: gt
    ṬD[            # ‎⁤are there any truthy indices?
     D £           # ‎⁢⁡if so, push something to the register stack
     D  h          # ‎⁢⁢and get the first such index
         ∥QiJ      # ‎⁢⁣slap that index to the back of the list
             x     # ‎⁢⁤and recurse on that list
              |    # ‎⁣⁡if there are no truthy indices
               Þ`  # ‎⁣⁢get the length of the stack, do not recurse.
💎

Created with the help of Luminespire.

<script type="vyxal3">
λ⁜>ṬD[£h∥QiJx|Þ`
</script>
<script>
    args=[["[3,2,1]"],["[1,2,3]"],["[1,3,5,2,4]"],["[1,2,5,3,4]"],["[3,6,5,4,1,2]"],["[2,5,1,3,4]"]]
</script>
<script src="https://themoonisacheese.github.io/snippeterpreter/snippet.js" type="module"/>

\$\endgroup\$
2
\$\begingroup\$

Nekomata + -1, 9 bytes

ˡ{;Cvh>ɔ,

Attempt This Online!

ˡ{;Cvh>ɔ,
ˡ{          Repeatedly apply the following block until fails, and count how many times it is applied:
  ;           Split the list into two parts
   C          Split the second part into the head and the tail
    vh>       Check that the head is larger than the head of the tail
       ɔ      Append the head to the end of the tail
        ,     Join the first part and the new second part

-1 outputs the first possible result.

\$\endgroup\$
1
\$\begingroup\$

Python 3, 119 121 bytes

+2 following feedback from @Neil

def s(i,c=0):
 if i!=sorted(i):
  for x in range(len(i)):
   if i[x]>i[x+1]:i+=[i.pop(x)];break
  s(i,c+1)
 else:print(c)

Try it online!

Recursive function that simply moves the first item that is larger than it's next neighbour to the end of the list until the list matches it's sorted version.

\$\endgroup\$
3
  • \$\begingroup\$ I don't think code golf rules allow you to pass extra data to functions, but you can work around that by providing a default argument for c. \$\endgroup\$ Commented Mar 23 at 10:15
  • \$\begingroup\$ 98 bytes using a while loop to replace the for (with the on-break stuff occurring unconditionally after loop), plus tweaking i+=[i.pop(x)] to i+=i.pop(x), (one-tuples costing one fewer characters). \$\endgroup\$ Commented Mar 24 at 19:40
  • \$\begingroup\$ @ShadowRanger 89 \$\endgroup\$ Commented Mar 24 at 20:50
1
\$\begingroup\$

APL+WIN, 89 bytes

Prompts for vector to be sorted;

i←¯1⋄n←v←⎕
:while 0<⍴n
v←(v~n),n←((<\1=×2-/v),0)/v
i←i+1
:end
i                          

Try it online! Thanks to Dyalog Classic APL

\$\endgroup\$
1
\$\begingroup\$

APL(NARS), 30 chars

{×k←↑⍸2>/⍵:1+∇⍵[k∼⍨⍳≢⍵],k⊃⍵⋄0}

Interpreter: NARS2000 (Win32) Version # 0.5.14.11

Input one list of floats output one not negative integer.

{×k←↑⍸2>/⍵:1+∇⍵[k∼⍨⍳≢⍵],k⊃⍵⋄0}
 ×k←↑⍸2>/⍵                      search 2-2 the first index i where ⍵[i]>⍵[i+1] and assign that index to k
           1+∇⍵[k∼⍨⍳≢⍵],k⊃⍵    if k is a positive number, return 1+ the call of this function with input ⍵[k∼⍨⍳≢⍵],k⊃⍵
                                            that would mean "return the array without the k index, and add to end ⍵[k]"
                            0   else return 0

test:

  f←{×k←↑⍸2>/⍵:1+∇⍵[k∼⍨⍳≢⍵],k⊃⍵⋄0}
  f 3 2 1
3
  f 1 3 5 2 4
5
  f 1 2 5 3 4
1
  f 3 6 5 4 1 2
10
  f 2 5 1 3 4
8
\$\endgroup\$
0
\$\begingroup\$

Perl 5, 62 bytes

sub f{shift=~/(.)(.)(??{$1>$2?'':X})/?f("$`$2$'$1",1+pop):pop}

Try it online!

Using Perls postponed regular subexpression (a.k.a. dynamic regenerate-at-runtime regexes)

\$\endgroup\$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.