Moving modest minimum

40

2

Inspired by a question over at Stack Overflow. The title here is entirely my fault.


The challenge

Given a list of positive integers containing at least two entries, replace each number by the minimum of all entries excluding itself.

Test cases

[4 3 2 5]    ->  [2 2 3 2]
[4 2 2 5]    ->  [2 2 2 2]
[6 3 5 5 8]  ->  [3 5 3 3 3]
[7 1]        ->  [1 7]
[9 9]        ->  [9 9]
[9 8 9]      ->  [8 9 8]

Rules

The algorithm should theoretically work for any input size (greater than one) and values (positive integers). It's accepted if the program is limited by time, memory or data types and so only works for numbers up to a given value, or for input size up to a given value.

Programs or functions are allowed, in any programming language. Standard loopholes are forbidden.

Input can be taken by any reasonable means; and with any format. Same for output. Input and output formats may be different.

Shortest code in bytes wins.

Luis Mendo

Posted 2017-04-27T08:59:38.057

Reputation: 87 464

What should [4 3 2 2 5] output? – user41805 – 2017-04-27T09:03:20.643

@KritixiLithos didn't the second test case cover this? – Leaky Nun – 2017-04-27T09:04:19.797

@KritixiLithos For input [4 3 2 2 5] the output would be [2 2 2 2 2] (this is similar to the second test case) – Luis Mendo – 2017-04-27T09:04:24.010

Oh, I missed the second test case. But now I understand how it works – user41805 – 2017-04-27T09:08:12.907

@LuisMendo You have changed "integer" to "any input size and values". Does that mean we need to account for all real numbers? – Leaky Nun – 2017-04-27T09:34:49.803

@LeakyNun No, I changed it to better reflect the allowed practical limitations of data types and input size. The input consists of positive integers (Given a list of positive integers...). Anyway, I've clarified that part – Luis Mendo – 2017-04-27T09:53:15.403

Answers

19

Jelly, 9 6 5 bytes

JḟЀ`ị⁸Ṃ€
ṙJṖ€Ṃ€
ṙJṖ«/     argument: 1D array (z)

 J        [1,2,3,...,len(z)]
ṙ         rotate z by each of the above amount (current array is 2D)
  Ṗ       remove the last array
   «/     reduce by [impliclitly vectorized] minimum

Try it online!

Verify all of them at once! (slightly modified)

I'm pretty sure Dennis can out-golf this.

How it works

The algorithm is rather convoluted. Let us observe what this does to [4,2,2,5].

Firstly, we use J to obtain [1,2,3,4]. Note that Jelly uses 1-indexing.

Then, we see . It takes two arguments: an array and an integer. It rotates the array to the left by an amount specified by the integer. Here, would see [4,2,2,5] on its left and [1,2,3,4] on its right (more about how this works can be found in the tutorial). In Jelly, commands implicitly vectorize. Therefore, this command will be performed over each individual element on the right, which is why we would create a 2D array:

Therefore, [4,2,2,5]ṙ[1,2,3,4] becomes [[4,2,2,5]ṙ1,[4,2,2,5]ṙ2,[4,2,2,5]ṙ3,[4,2,2,5]ṙ4], which becomes:

[[2,2,5,4],
 [2,5,4,2],
 [5,4,2,2],
 [4,2,2,5]]

Notice that the original elements are on the last row, since in that row we rotated to the left by an amount equal to the length of the array, which is why we use next to remove that row, so that the columns are the collections of the elements of the array which are not at the current index:

[[2,2,5,4],
 [2,5,4,2],
 [5,4,2,2]]

The following operation, «/, is also quite convoluted. Firstly, « returns the minimum of the two numbers it sees on its left and on its right. For example, 5«3 returns 3. Now, if the two arguments are arrays, then it would vectorize as I have said above. What this means it that [1,5,2,3]«[4,1,5,2] would become [1«4,5«1,2«5,3«2] which is [1,1,2,2]. Now, / is reduce, which means that we do the operation over each row until the end. For example, [1,2,3,4]+/ would become ((1+2)+3)+4, which is the sum of the array [1,2,3,4].

So, if we apply «/ to the 2D array we just obtained, we would get:

([2,2,5,4]«[2,5,4,2])«[5,4,2,2]

which, because of the vectorization, would be equivalent to:

[2«2«5,2«5«4,5«4«2,4«2«2]

which computes the minimum of every array without the element at the index.

Leaky Nun

Posted 2017-04-27T08:59:38.057

Reputation: 45 011

1Oh, your edit... you got there first. – Jonathan Allan – 2017-04-27T09:10:42.533

1@JonathanAllan I'm sorry. – Leaky Nun – 2017-04-27T09:11:01.340

40

Python 2, 41 bytes

lambda l:[sorted(l)[x==min(l)]for x in l]

Try it online!

For each element x we check whether x==min(l). If not, this is False, which is treated as 0 when used as a list index into sorted(l), giving the smallest element. Otherwise, it's True aka 1, giving the second-smallest element, since that element itself is smallest and should be ignored.

xnor

Posted 2017-04-27T08:59:38.057

Reputation: 115 687

2I have a hard time believing that this works. – Leaky Nun – 2017-04-27T09:24:55.643

2Great approach! – Luis Mendo – 2017-04-27T09:26:11.437

Could you add an explanation? It wouldn't be very complicated, but the trick of "every number will be the minimum, except for the one that is the minimum, which will be the second-smallest" and the fact that False gets converted to 0 and True gets converted to 1 are really cool and should be bragged about^W^Wexplained – Fund Monica's Lawsuit – 2017-04-28T16:55:31.923

18

Jelly, 5 bytes

=Ṃ‘ịṢ

Try it online!

How?

=Ṃ‘ịṢ - Main link: list a     e.g.  [4,3,2,5]
 Ṃ    - minimum of a                2
=     - equals? (vectorises)        [0,0,1,0]
  ‘   - increment                   [1,1,2,1]
    Ṣ - sort a                      [2,3,4,5]
   ị  - index into                  [2,2,3,2]

Jonathan Allan

Posted 2017-04-27T08:59:38.057

Reputation: 67 804

Obviously a fork of this Python answer.

– Leaky Nun – 2017-04-27T09:35:38.793

@LeakyNun I credit if porting :) – Jonathan Allan – 2017-04-27T09:38:16.767

Does this mean you have already credited (which you haven't), or that this is not a port (which it obviously is)? – Leaky Nun – 2017-04-27T09:39:07.600

4@LeakyNun This is not a port, it's just the same method, I'm still looking for less too... I have upvoted that answer too now :) – Jonathan Allan – 2017-04-27T09:40:13.903

5@LeakyNun I am new here, but are you always this hostile? It's not like there are ton of unique ways to approach this. Even if he did port it, he still has the shorter answer. – Grayson Kent – 2017-04-27T15:46:38.493

3@GraysonKent I apologize for my perceived hostility. – Leaky Nun – 2017-04-27T17:32:47.063

1@GraysonKent Welcome to PPCG! – Luis Mendo – 2017-04-27T23:47:37.857

1@LeakyNun This happens a lot in simpler challenges, you can't really say every answer is a port of every other one – ASCII-only – 2017-04-28T00:20:11.103

12

Haskell, 42 41 39 bytes

EDIT:

  • -1 byte thanks to nimi!
  • -2 bytes. One thanks to xnor! And one by myself.

f takes a list of integers (or any Ord type) and returns a list.

f(x:y)=minimum y:(fst<$>zip(f$y++[x])y)

Try it online!

f recurses while rotating the list. x is the first list element and y the remainder. Since the recursion is infinite, the result list needs to be cut off: fst<$>zip...y is a shorter way of saying take(length y)....

Ørjan Johansen

Posted 2017-04-27T08:59:38.057

Reputation: 6 914

1You can save one byte by naming the whole input list via @ and flip the lists to be zipped: f l@(x:y)=fst<$>zip(minimum...)l. – nimi – 2017-04-27T20:01:19.320

1f(h:t)=minimum t:(fst<$>zip(f(t++[h]))t) – xnor – 2017-04-27T21:19:25.343

9

Octave, 26 bytes

@(x)sort(x)((x==min(x))+1)

A similar approach as used in this answer, which happens to be the same as this.

I'm not really a fan of just porting other answers, which is why I'd like to note that I had a similar idea before I saw the other ones.

Explanation:

Jonathan Allan has already provided a good explanation for the Jelly-code, so this covers the Octave-bit, and why it works (and wouldn't work in MATLAB).

@(x)                       % An unnamed anonymous function taking a vector x as input
    sort(x)                % Gives a sorted version of x
            (x==min(x))    % Checks if each element is equal to the minimum value
           ((x==min(x))+1) % Adds 1 to the boolean vector, to use as indices
@(x)sort(x)((x==min(x))+1) % Complete function

This doesn't work in MATLAB, since inline assignments and direct indexing doesn't work. sort(x)(1) gives an error in MATLAB, not the first element in the sorted vector.

Stewie Griffin

Posted 2017-04-27T08:59:38.057

Reputation: 43 471

8

Haskell, 41 bytes

a#(b:c)=minimum(a++c):(b:a)#c
a#b=b 
([]#)

Usage example: ([]#) [4,3,2,5]-> [2,2,3,2]. Try it online!

Start with an empty accumulator a and run down the input list. The next element in the output list is the minimum of the accumulator a and all but the first element of the input list (->c) followed by a recursive call with the first element b added to the accumulator and c. Stop when you reach the end of the input list.

nimi

Posted 2017-04-27T08:59:38.057

Reputation: 34 639

7

JavaScript (ES6), 50 46 bytes

a=>a.map((_,i)=>Math.min(...a.filter(_=>i--)))

Edit: Saved 4 bytes thanks to @Arnauld.

Neil

Posted 2017-04-27T08:59:38.057

Reputation: 95 035

a=>a.map(x=>Math.min(...a.filter(y=>x!=y))) for 43 bytes. – Shaggy – 2017-04-27T09:35:21.303

@Shaggy I don't think that works for an input such as 3,3,3,3 – Arnauld – 2017-04-27T09:36:19.877

D'oh! No, it won't work if there are 2 or more occurrences of the minimum value. – Shaggy – 2017-04-27T09:37:34.717

1However, you can do a=>a.map((_,i)=>Math.min(...a.filter(_=>i--))) for 46. – Arnauld – 2017-04-27T09:40:22.780

@Arnauld Very clever, thanks! – Neil – 2017-04-27T09:42:12.107

7

Brachylog, 13 12 bytes

l+₁:?⊇ᶠ⁽⌋ᵐb↔

Try it online!

Saved one byte thanks to @ais523.

Explanation

l+₁:?            The list [length(Input) + 1, Input]
     ⊇ᶠ⁽         Find the length(Input) + 1 first subsets of the Input
        ⌋ᵐ       Get the min of each subset 
           b↔    Remove the first element and reverse

We exploit the fact that unifies subsets from biggest to smallest. For example for [1,2,3], the subsets we get are in this order: [1,2,3], [1,2], [1,3], [2,3], [1], [2], [3], [].

We can see that the subsets [1,2], [1,3], [2,3] are the ones we want the minimum from, but are in the reverse order compared to the input list (hence the ). We can select those subsets only by finding the first length(Input) + 1 subsets, which will contain all of them + the entire list first. We discard that entire list with b.

Fatalize

Posted 2017-04-27T08:59:38.057

Reputation: 32 976

1You can save a byte by splitting your "findall subset+minimum" into "findall subset" and "map minimum". (I need to go add this to the Brachylog tips thread, now you've reminded me of it.) – None – 2017-04-27T22:55:27.007

1@ais523 Thanks, I always forget about that trick… – Fatalize – 2017-04-28T06:20:19.793

6

Actually, 13 bytes

;;S╝m╗⌠╜=╛E⌡M

Uses the same technique that xnor also discovered.

Try it online!

Explanation:

;;S╝m╗⌠╜=╛E⌡M
;;             make two extra copies of input list
  S╝           sort one and save it in register 1
    m╗         save the minimum of the other in register 0
      ⌠╜=╛E⌡M  for each value in list:
       ╜=╛E      return the minimum element of the input list if the value is not equal to the minimum, else return the second-smallest element

Mego

Posted 2017-04-27T08:59:38.057

Reputation: 32 998

1You still haven't allowed us to look at the global stack inside the temporary stack? – Leaky Nun – 2017-04-27T09:36:16.187

1@LeakyNun Not yet. In the current state that the interpreter's code is in, that would be very difficult. After I finish the large refactoring I'm working on, I'll see about adding that functionality. – Mego – 2017-04-27T09:37:09.323

1When did you begin the large refactoring? – Leaky Nun – 2017-04-27T09:37:42.087

6

R, 46 31 bytes

l=scan();sort(l)[(min(l)==l)+1]

implements Stewie Griffin's solution in R, alas, my original idea is 50% longer! still reads the list from stdin, but now returns a much more readable numeric vector.

Try it online!

old implementation:

l=scan();Map(function(x)min(l[-x]),match(l,l))

reads in the list from stdin. A negative index l[-x] excludes the element from the list, and match(l,l) returns the index of the first occurrence of each element of the list. Returns a list.

Giuseppe

Posted 2017-04-27T08:59:38.057

Reputation: 21 077

5

Python 2, 51 bytes

I know there's already a better Python solution, but I still want to post mine.

lambda L:[min(L[:i]+L[i+1:])for i in range(len(L))]

Try it online

mbomb007

Posted 2017-04-27T08:59:38.057

Reputation: 21 944

5

Mathematica 34 Bytes

Min[#~Drop~{i}]~Table~{i,Tr[1^#]}&

Kelly Lowder

Posted 2017-04-27T08:59:38.057

Reputation: 3 225

5

PowerShell, 68 59 bytes

($a=$args)|%{$b+=@((($c=$a|sort)[0],$c[1])[$_-eq$c[0]])};$b

Try it online!

I'm pretty confident it can be shortened, I will continue to look at it

Sinusoid

Posted 2017-04-27T08:59:38.057

Reputation: 451

4

C, 85 bytes

i,j,m;f(d,o,n)int*d,*o;{for(i=n;i--;)for(m=d[!i],j=n;j;o[i]=m=--j^i&&d[j]<m?d[j]:m);}

First argument is the input integer array. The second argument is the output integer array. The third argument is the element count for both arrays.

See it work online.

2501

Posted 2017-04-27T08:59:38.057

Reputation: 748

3

Clojure, 36 81 62 71 bytes

Newest (shouldn't really submit these in a hurry):

#(for[c[(zipmap(range)%)]i(sort(keys c))](apply min(vals(dissoc c i))))

Try it online.

Aaaand this one has a bug (62 bytes), zipmap produces an unordered map so this won't produce the correct sequence on larger inputs.

#(for[c[(zipmap(range)%)][i v]c](apply min(vals(dissoc c i))))

v is not actually used for anything but this is shorter than i (keys c).

Previous at 81 bytes:

Try it online.

#(let[r(range(count %))](for[i r](apply min(for[j r :when(not= i j)](nth % j)))))

Try it online.

Oh damn the original (36 bytes) does not work when the minimum number is repeated, [4 2 2 5] results in [2 4 4 2] as both 2s are removed :(

#(for[i %](apply min(remove #{i}%)))

#{i} is the set which contains only i, it returns truthy for i and falsy for others, meaning that the minimum is calculated from all other numbers within the input list.

Try it online.

NikoNyrh

Posted 2017-04-27T08:59:38.057

Reputation: 2 361

3

Perl 6,  26 24  19 bytes

26

{.map: (.Bag∖*).min.key}

Note that is U+2216 not \ U+5C

Try it

{.map: (.Bag⊖*).min.key}

Try it

24

{(.min X%$_)X||.sort[1]}

Try it

19

{.sort[.min X==$_]}

Try it


26

{           # bare block lambda with implicit parameter 「$_」

  .map:     # for each of the values in the input (implicit method call on 「$_」)
  (
    .Bag    # turn the block's input into a Bag
    ∖       # set-difference           「∖」 U+2216 aka 「(-)」
    # ⊖     # symmetric-set-difference 「⊖」 U+2296 aka 「(^)」
    *       # turn expression into a WhateverCode lambda (this is the parameter)
  ).min.key # get the minimum pair from the Bag, and return its key
}

I used the "fancy" unicode operators rather than the ascii equivalents because they would have required a space before them so that they wouldn't be parsed as part of the .Bag method call.

24

{
  (.min X% $_) # the minimum cross modulus-ed with the input
  X||          # cross or-ed 
  .sort[1]     # with the second minimum
}

19

{
  .sort\        # sort the values
  [             # index into that
    .min X== $_ # the minimum cross compared with the input
  ]
}

(The 24 and 19 byte golfs were inspired by a Jelly implementation)

Brad Gilbert b2gills

Posted 2017-04-27T08:59:38.057

Reputation: 12 713

3

Pyth, 8 7 bytes

mh.-SQ]

-1 Byte thanks to @isaacg

Try it!

KarlKastor

Posted 2017-04-27T08:59:38.057

Reputation: 2 352

You can remove the d at the end - it's implicitly filled in. – isaacg – 2017-04-28T22:25:29.447

@isaacg thank you, didn't know that – KarlKastor – 2017-04-29T10:40:02.180

2

PHP, 72 Bytes

<?$k=$g=$_GET;sort($k);foreach($g as&$v)$v=$k[$v==$k[0]?:0];print_r($g);

Online Version

Jörg Hülsermann

Posted 2017-04-27T08:59:38.057

Reputation: 13 026

2

PHP, 47 bytes

while(++$i<$argc)echo@min([z,$i=>z]+$argv),' ';

user63956

Posted 2017-04-27T08:59:38.057

Reputation: 1 571

2

Scala, 37 bytes

l.indices map(i=>l diff Seq(l(i))min)

l is any collection of Int.

Test cases:

scala> val l = List(4,3,2,5)
l: List[Int] = List(4, 3, 2, 5)

scala> l.indices map(i=>l diff Seq(l(i))min)
res0: scala.collection.immutable.IndexedSeq[Int] = Vector(2, 2, 3, 2)

scala> val l = List(4,2,2,5)
l: List[Int] = List(4, 2, 2, 5)

scala> l.indices map(i=>l diff Seq(l(i))min)
res1: scala.collection.immutable.IndexedSeq[Int] = Vector(2, 2, 2, 2)

scala> val l = List(6,3,5,5,8)
l: List[Int] = List(6, 3, 5, 5, 8)

scala> l.indices map(i=>l diff Seq(l(i))min)
res2: scala.collection.immutable.IndexedSeq[Int] = Vector(3, 5, 3, 3, 3)

scala> val l = List(7,1)
l: List[Int] = List(7, 1)

scala> l.indices map(i=>l diff Seq(l(i))min)
res3: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 7)

scala> val l = List(9,9)
l: List[Int] = List(9, 9)

scala> l.indices map(i=>l diff Seq(l(i))min)
res4: scala.collection.immutable.IndexedSeq[Int] = Vector(9, 9)

scala> val l = List(9,8,9)
l: List[Int] = List(9, 8, 9)

scala> l.indices map(i=>l diff Seq(l(i))min)
res5: scala.collection.immutable.IndexedSeq[Int] = Vector(8, 9, 8)

This can probably still be golfed, I couldn't find a shorter way to remove an element from a list than l diff Seq(l(i))

2xsaiko

Posted 2017-04-27T08:59:38.057

Reputation: 699

2

C#, 36 Bytes

i.Select((x,a)=>i.Where((y,b)=>b!=a).Min())

Takes the elements (i) and looks in the elements without the current item for the minimal value.

It's kind of sad, that some other attempts don't work, as we work with primitive types, and therefore don't have lists with references to compare the items from.

MetaColon

Posted 2017-04-27T08:59:38.057

Reputation: 391

2

PowerShell, 49 38 bytes

-11 bytes thanks to mazzy

($a=$args)|%{($c=$a|sort)[$_-eq$c[0]]}

Try it online!

Improvement of Sinusoid's lovely answer. Saves 10 bytes by using explicit output instead of building an array. Indexes into the sorted array to either spot 0 (i.e. smallest value) or spot 1 if the conditional is true.

Veskah

Posted 2017-04-27T08:59:38.057

Reputation: 3 580

1

It's smart. Save more :) Try it online!

– mazzy – 2019-03-14T16:18:42.747

1@mazzy Well done. It's obvious now that I see it but I never would've put that together. – Veskah – 2019-03-14T16:31:21.710

1Nice work! Yours is more lovely :) – Sinusoid – 2019-06-13T17:52:53.620

1

Perl 5, 43 bytes

sub{@x=sort{$a<=>$b}@_;map$x[$_==$x[0]],@_}

Equivalent to the Python solution. Perl's sort unfortunately has the wrong default for numbers (requiring an explicit comparator), and min isn't built-in, but it almost makes up for it by sub being shorter than lambda, map$_, being shorter than x for x in, and the implicitness of return and args lists.

hobbs

Posted 2017-04-27T08:59:38.057

Reputation: 2 403

1

CJam, 15 bytes

{:S{S:e<=S$=}%}

Essentially a translation of xnor's algorithm into CJam.

This is an unnamed block that takes an array from the stack and leaves the result on the stack.

Explanation:

{
  :S     e# Save in S
  {      e# For X in S:
    S:e< e#   Push Min(S)
    =    e#   X == Min(S)
    S$=  e#   Sorted(S)[top of stack]
  }%     e# End
}

Esolanging Fruit

Posted 2017-04-27T08:59:38.057

Reputation: 13 542

1@LuisMendo Whoops - I forgot to actually sort the array. It should work now. – Esolanging Fruit – 2017-04-30T23:38:57.937

1

Ruby, 30 bytes

For each element, sort the array, remove the current element and grab the first element of the remaining array.

->a{a.map{|e|(a.sort-[e])[0]}}

It's an anonymous function that can be used like this:

f = ->a{a.map{|e|(a.sort-[e])[0]}}
p f[[6, 3, 5, 5, 8]] # => [3, 5, 3, 3, 3]

daniero

Posted 2017-04-27T08:59:38.057

Reputation: 17 193

1

05AB1E, 5 bytes

{sWQè

Port of @xnor's Python 2 answer.

Try it online or verify all test cases.

Explanation:

{        # Sort the (implicit) input-list
         #  i.e. [4,1,3,6] → [1,3,4,6]
 s       # Swap, so the (implicit) input-list is at the top of the stack again
  W      # Get the minimum without popping from the list
         #  i.e. [4,1,3,6] → 1
   Q     # Check for each element if they are equal to this value (1/0 as truthy/falsey)
         #  i.e. [4,1,3,6] and 1 → [0,1,0,0]
    è    # Use these 0s and 1s to index in the sorted list
         #  i.e. [1,3,4,6] and [0,1,0,0] → [1,3,1,1]

Kevin Cruijssen

Posted 2017-04-27T08:59:38.057

Reputation: 67 575

1

Java 8, 119 bytes

a->{int t[]=a.clone(),m=a[0],i=a.length;for(int x:a)m=x<m?x:m;for(java.util.Arrays.sort(t);i-->0;)a[i]=t[a[i]==m?1:0];}

Port of @xnor's Python 2 answer.

Modifies the input-array instead of returning a new one to save bytes.

Try it online.

Explanation:

a->{                  // Method with integer-array parameter and no return-type
  int t[]=a.clone(),  //  Make a copy of the input-array
      m=a[0],         //  Minimum `m`, starting at the first value of the input-array
      i=a.length;     //  Index-integer, starting at the length of the input-array
  for(int x:a)        //  Loop over the input-array
    m=x<m?            //   If the current item is smaller than the current `m`
       x              //    Replace `m` with this value
      :               //   Else:
       m;             //    Leave `m` the same
  for(java.util.Arrays.sort(t);
                      //  Sort the copy we've made of the input-array
      i-->0;)         //  Loop `i` in the range (length, 0]
    a[i]=             //   Modify the item at index `i` of the input-array to:
      t[              //    The item in the sorted array at index:
        a[i]==m?      //     If the current item and the minimum are equal:
         1            //      Use index 1 in the sorted array
        :             //     Else:
         0];}         //      Use index 0 in the sorted array

Kevin Cruijssen

Posted 2017-04-27T08:59:38.057

Reputation: 67 575

1

APL (Dyalog Extended), 7 bytes

Port of xnor's Python 2 answer. Requires ⎕IO←0:

∧⊇⍨⊢=⌊/

Try it online!

Explanation:

∧⊇⍨⊢=⌊/  ⍝ Monadic function train
      ⌊/  ⍝ The minimum element of the input
    ⊢=    ⍝ Element-wise compare the input to the above
          ⍝ Results in a boolean vector, let's call it "X"
∧         ⍝ Sort the input
 ⊇⍨      ⍝ Index into sorted input by X

voidhawk

Posted 2017-04-27T08:59:38.057

Reputation: 1 796

1

Haskell, 76 bytes

This is considerably longer than the earlier Haskell entries, but it's the first that only performs a linear number of comparisons and a linear amount of additional work.

f(x:y)|(z,w)<-x!y=z:w
a![x]=(x,[a])
a!(x:y)|(p,q)<-a#x!y=(x#p,a#p:q)
(#)=min

Try it online!

Explanation

! takes two arguments: a running minimum and a nonempty list. It returns the minimum value in the list and the result of processing the given list using the running minimum.

dfeuer

Posted 2017-04-27T08:59:38.057

Reputation: 1 016

1

MathGolf, 9 7 bytes

s_╓?m=§

Try it online!

Explanation

Basically a port of Kevin Cruijssen's 05AB1E answer, but I lose 2 bytes thanks to having to do things explicitly.

s         sort(array)
 _        duplicate TOS
  ╓       minimum of two elements, min of list, minimum by filter
   ?      rot3 pops input on top of stack again
    m=    explicit map to check equality
      §   get from sorted array for each

maxb

Posted 2017-04-27T08:59:38.057

Reputation: 5 754

1

APL(NARS), 47 chars, 94 bytes

{m←⌊/⍵⋄⍵{⍵>≢⍺:⍬⋄t←⍺∇⍵+1⋄m=⍵⊃⍺:(⌊/⍺∼⍦m),t⋄m,t}1}

∼⍦ it seems is using for remove one element only 1 times; possible it is too much long for you... test:

  f←{m←⌊/⍵⋄⍵{⍵>≢⍺:⍬⋄t←⍺∇⍵+1⋄m=⍵⊃⍺:(⌊/⍺∼⍦m),t⋄m,t}1}
  f 4 3 2 5
2 2 3 2 
  f 4 2 2 5
2 2 2 2 
  f 6 3 5 5 8
3 5 3 3 3 
  f 7 1
1 7 
  f 9 9
9 9 
  f 8 9 8
8 8 8 
  f 9 8 9
8 9 8 

RosLuP

Posted 2017-04-27T08:59:38.057

Reputation: 3 036