# Moving modest minimum

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.

• What should [4 3 2 2 5] output? Commented Apr 27, 2017 at 9:03
• @KritixiLithos didn't the second test case cover this? Commented Apr 27, 2017 at 9:04
• @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) Commented Apr 27, 2017 at 9:04
• Oh, I missed the second test case. But now I understand how it works Commented Apr 27, 2017 at 9:08
• @LuisMendo You have changed "integer" to "any input size and values". Does that mean we need to account for all real numbers? Commented Apr 27, 2017 at 9:34

# 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.

• I have a hard time believing that this works. Commented Apr 27, 2017 at 9:24
• Great approach! Commented Apr 27, 2017 at 9:26
• 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
– anon
Commented Apr 28, 2017 at 16:55

# Jelly, 96 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.

• Oh, your edit... you got there first. Commented Apr 27, 2017 at 9:10
• @JonathanAllan I'm sorry. Commented Apr 27, 2017 at 9:11

# Jelly, 3 bytes

### Now possible in 3 bytes, since 2017-08-13:

Ṃ-Ƥ - map minimum over overlapping outfixes of length one less than the input


Try it online!

### Original, 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]

• @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 :) Commented Apr 27, 2017 at 9:40
• @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. Commented Apr 27, 2017 at 15:46
• @GraysonKent I apologize for my perceived hostility. Commented Apr 27, 2017 at 17:32
• @GraysonKent Welcome to PPCG! Commented Apr 27, 2017 at 23:47
• @LeakyNun This happens a lot in simpler challenges, you can't really say every answer is a port of every other one Commented Apr 28, 2017 at 0:20

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).... • You 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
Commented Apr 27, 2017 at 20:01
• f(h:t)=minimum t:(fst<$>zip(f(t++[h]))t) – xnor Commented Apr 27, 2017 at 21:19 # 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. ## 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. # 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. • You 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.) – user62131 Commented Apr 27, 2017 at 22:55 • @ais523 Thanks, I always forget about that trick… Commented Apr 28, 2017 at 6:20 ## JavaScript (ES6), 50 46 bytes a=>a.map((_,i)=>Math.min(...a.filter(_=>i--)))  Edit: Saved 4 bytes thanks to @Arnauld. • a=>a.map(x=>Math.min(...a.filter(y=>x!=y))) for 43 bytes. Commented Apr 27, 2017 at 9:35 • @Shaggy I don't think that works for an input such as 3,3,3,3 Commented Apr 27, 2017 at 9:36 • D'oh! No, it won't work if there are 2 or more occurrences of the minimum value. Commented Apr 27, 2017 at 9:37 • However, you can do a=>a.map((_,i)=>Math.min(...a.filter(_=>i--))) for 46. Commented Apr 27, 2017 at 9:40 • @Arnauld Very clever, thanks! – Neil Commented Apr 27, 2017 at 9:42 # 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. • Hmm. I was pleased that apply(diag(l<-scan())+l,2,min) was only 30 bytes, until I realised that a rearrangement of yours (sort(l<-scan())[2-(min(l)<l)]) could be only 29... Commented Feb 21, 2023 at 22:20 • That's all yours; the 2-(min(l)<l) index is quite clever! Commented Feb 21, 2023 at 22:22 # 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  • You still haven't allowed us to look at the global stack inside the temporary stack? Commented Apr 27, 2017 at 9:36 • @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. – user45941 Commented Apr 27, 2017 at 9:37 • When did you begin the large refactoring? Commented Apr 27, 2017 at 9:37 # Uiua, 8 bytes /↧÷⊞≠.⍏.  Vyxal port is 10 bytes: ⊏⊃'=/↧'⊏⍏.  Try these online! /↧÷⊞≠.⍏. input: a positive integer vector ⊞≠.⍏ a matrix of the size of the input where the diagonal is 0s and the rest are 1s ÷ . divide each number in the input by each row of the above matrix, giving infinities where division by 0 occurs /↧ minimum of each column ⊏⊃'=/↧'⊏⍏. ⊃ . fork on two functions with two copies of input vectors as arguments: '=/↧ for each element, 1 if it is the minimum, 0 otherwise '⊏⍏ input sorted ⊏ select 0th or 1st item from the sorted list  Alternative 8: ⊏=0⊃⍏⊏⍏.  Try it online! ⊏=0⊃⍏⊏⍏. ⊃⍏⊏⍏. take the input array and push (rank, sorted) ⍏ ⍏ rank: lowest number is replaced with 0, next lowest 1, ... ⊏⍏. sorted: lowest number is placed first, next 2nd, ... =0 for each element, 1 if rank is 0, 0 otherwise ⊏ select 1st in the sorted array if rank 0, 0th otherwise  # 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 ## Mathematica 34 Bytes Min[#~Drop~{i}]~Table~{i,Tr[1^#]}&  # 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

## 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.

# 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

{(.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)

## Clojure, 368162 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))))


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:

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


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.

# Pyth, 8 7 bytes

mh.-SQ]


-1 Byte thanks to @isaacg

Try it!

• You can remove the d at the end - it's implicitly filled in. Commented Apr 28, 2017 at 22:25
• @isaacg thank you, didn't know that Commented Apr 29, 2017 at 10:40

# Factor, 38 bytes

[ all-rotations [ rest infimum ] map ]


Try it online!

Get all the rotations of the input, then get the smallest element in each rotation minus the first element. Like this:

$$\\begin{matrix} 4 & 3 & 2 & 5 \\ \end{matrix} \rightarrow\$$

$$\\require{enclose}\begin{matrix}\enclose{horizontalstrike}{4} & 3 & \color{red}{2} & 5 \\ \enclose{horizontalstrike}{3} & \color{red}{2} & 5 & 4 \\ \enclose{horizontalstrike}{2} & 5 & 4 & \color{red}{3} \\ \enclose{horizontalstrike}{5} & 4 & 3 & \color{red}{2} \\ \end{matrix} \rightarrow\$$

$$\\begin{matrix} 2 & 2 & 3 & 2 \\ \end{matrix}\$$

# J, 7 bytes

1<./\.]


Attempt This Online!

J's outfix adverb \. is made for this. It applies a verb (in this case min) to every outfix of a list of a specified size (in this case 1). Outfix being the inverse operation of "window" functions which exist in most languages -- a list composed of the original list without a window as that window moves across the list.

• This outfix adverb is neat. Even its name is! Commented Oct 17, 2023 at 9:28

<?$k=$g=$_GET;sort($k);foreach($g as&$v)$v=$k[$v==$k[0]?:0];print_r($g);  Online Version # PHP, 47 bytes while(++$i<$argc)echo@min([z,$i=>z]+$argv),' ';  # 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)) # 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]  # 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. # 05AB1E, 5 bytes {sWQè  Port of @xnor's Python 2 answer. 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]  # 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  • Dyalog Vision allows saving a byte with ⌈/⍛=⊇≤ – Adám Commented Feb 12 at 7:55 # 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.

• It's smart. Save more :) Try it online! Commented Mar 14, 2019 at 16:18
• @mazzy Well done. It's obvious now that I see it but I never would've put that together. Commented Mar 14, 2019 at 16:31
• Nice work! Yours is more lovely :) Commented Jun 13, 2019 at 17:52

# Husk, 6 bytes

mo▼-¹


Try it online!

# K (ngn/k), 12 bytes

{(&/x_)'!#x}


Try it online!

Uses list _ int to remove individual values from the input, then takes the minimum of the remaining values.