Mover modesto mínimo


40

Inspirado por una pregunta en Stack Overflow. El título aquí es completamente mi culpa.


El reto

Dada una lista de enteros positivos que contiene al menos dos entradas, reemplace cada número por el mínimo de todas las entradas, excluyéndose a sí mismo.

Casos de prueba

[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]

Reglas

El algoritmo debería funcionar teóricamente para cualquier tamaño de entrada (mayor que uno) y valores (enteros positivos). Se acepta si el programa está limitado por el tiempo, la memoria o los tipos de datos y, por lo tanto, solo funciona para números de hasta un valor determinado o para un tamaño de entrada de hasta un valor determinado.

Se permiten programas o funciones , en cualquier lenguaje de programación . Las lagunas estándar están prohibidas.

La entrada puede tomarse por cualquier medio razonable ; y con cualquier formato Lo mismo para la salida. Los formatos de entrada y salida pueden ser diferentes.

El código más corto en bytes gana.


¿Qué debería [4 3 2 2 5]salir?
Kritixi Lithos

@KritixiLithos ¿el segundo caso de prueba no cubrió esto?
Leaky Nun

@KritixiLithos Para la entrada, [4 3 2 2 5]la salida sería [2 2 2 2 2](esto es similar al segundo caso de prueba)
Luis Mendo

Oh, me perdí el segundo caso de prueba. Pero ahora entiendo cómo funciona
Kritixi Lithos

@LuisMendo Ha cambiado "entero" a "cualquier tamaño y valor de entrada". ¿Eso significa que debemos tener en cuenta todos los números reales?
Leaky Nun

Respuestas:


19

Jalea , 9 6 5 bytes

JḟÐ € `ị⁸Ṃ € 
ṙJṖ € Ṃ €
ṙJṖ «/ argumento: matriz 1D (z)

 J [1,2,3, ..., len (z)]
ṙ gire z por cada una de las cantidades anteriores (la matriz actual es 2D)
  Ṗ eliminar la última matriz
   «/ Reducir en un mínimo [implícitamente vectorizado]

Pruébalo en línea!

¡Verifíquelos todos a la vez! (ligeramente modificado)

Estoy bastante seguro de que Dennis puede superar esto.

Cómo funciona

El algoritmo es bastante complicado. Observemos lo que esto hace [4,2,2,5].

En primer lugar, utilizamos Jpara obtener [1,2,3,4]. Tenga en cuenta que Jelly utiliza la indexación 1.

Entonces, ya vemos . Se necesitan dos argumentos: una matriz y un número entero. Gira la matriz a la izquierda en una cantidad especificada por el entero. Aquí, vería [4,2,2,5]a su izquierda y [1,2,3,4]a su derecha (puede encontrar más información sobre cómo funciona esto en el tutorial ). En Jelly, los comandos vectorizan implícitamente. Por lo tanto, este comando se ejecutará sobre cada elemento individual de la derecha, por lo que crearíamos una matriz 2D:

Por lo tanto, se [4,2,2,5]ṙ[1,2,3,4]convierte [[4,2,2,5]ṙ1,[4,2,2,5]ṙ2,[4,2,2,5]ṙ3,[4,2,2,5]ṙ4], que se convierte en:

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

Observe que los elementos originales están en la última fila, ya que en esa fila giramos a la izquierda en una cantidad igual a la longitud de la matriz, por lo que usamos next para eliminar esa fila, de modo que las columnas son las colecciones de Los elementos de la matriz que no están en el índice actual:

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

La siguiente operación, «/también es bastante complicada. En primer lugar, «devuelve el mínimo de los dos números que ve a su izquierda y a su derecha. Por ejemplo, 5«3vuelve 3. Ahora, si los dos argumentos son matrices, entonces se vectorizaría como he dicho anteriormente. Lo que esto significa es que [1,5,2,3]«[4,1,5,2]se convertiría en lo [1«4,5«1,2«5,3«2]que es [1,1,2,2]. Ahora, /es reduce, lo que significa que hacemos la operación sobre cada fila hasta el final. Por ejemplo, [1,2,3,4]+/se convertiría en ((1+2)+3)+4la suma de la matriz [1,2,3,4].

Entonces, si aplicamos «/a la matriz 2D que acabamos de obtener, obtendríamos:

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

que, debido a la vectorización, sería equivalente a:

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

que calcula el mínimo de cada matriz sin el elemento en el índice.


1
Oh, tu edición ... llegaste primero.
Jonathan Allan

1
@ JonathanAllan lo siento.
Leaky Nun

40

Python 2 , 41 bytes

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

Pruébalo en línea!

Para cada elemento xverificamos si x==min(l). Si no, esto es False, que se trata como 0cuando se usa como un índice de lista sorted(l), dando el elemento más pequeño. De lo contrario, es Trueaka 1, dando el segundo elemento más pequeño, ya que ese elemento en sí mismo es el más pequeño y debe ignorarse.


2
Me cuesta creer que esto funcione.
Leaky Nun

2
Gran enfoque!
Luis Mendo

¿Podría agregar una explicación? No sería muy complicado, pero el truco de "cada número será el mínimo, excepto el que es el mínimo, que será el segundo más pequeño" y el hecho de que Falsese convierte 0y Truese convierte en 1realidad genial y debería presumir de ^ W ^ Wexplained
Fund Monica's Lawsuit

18

Jalea , 5 bytes

=Ṃ‘ịṢ

Pruébalo en línea!

¿Cómo?

=Ṃ‘ịṢ - 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]

44
@LeakyNun Esto no es un puerto, es el mismo método, todavía estoy buscando menos también ... También he votado por esa respuesta :)
Jonathan Allan

55
@LeakyNun Soy nuevo aquí, pero ¿eres siempre tan hostil? No es que haya muchas formas únicas de abordar esto. Incluso si lo portó, todavía tiene la respuesta más corta.
Grayson Kent el

3
@GraysonKent Pido disculpas por mi hostilidad percibida.
Leaky Nun

1
@GraysonKent ¡Bienvenido a PPCG!
Luis Mendo

1
@LeakyNun Esto sucede mucho en desafíos más simples, realmente no se puede decir que cada respuesta es un puerto de cada una
solo ASCII

12

Haskell , 42 41 39 bytes

EDITAR:

  • -1 byte gracias a nimi!
  • -2 bytes. ¡Gracias a xnor! Y uno solo.

ftoma una lista de enteros (o cualquier Ordtipo) y devuelve una lista.

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

Pruébalo en línea!

frecurre mientras gira la lista. xes el primer elemento de la lista y yel resto. Como la recursividad es infinita, la lista de resultados debe cortarse: fst<$>zip...yes una forma más corta de decir take(length y)....


1
Puede guardar un byte al nombrar la lista de entrada a través de todo @y voltear las listas para ser comprimido: f l@(x:y)=fst<$>zip(minimum...)l.
nimi

1
f(h:t)=minimum t:(fst<$>zip(f(t++[h]))t)
xnor

9

Octava, 26 bytes

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

Un enfoque similar al utilizado en esta respuesta , que resulta ser el mismo que este .

Realmente no soy fanático de solo portar otras respuestas, por eso me gustaría señalar que tuve una idea similar antes de ver las otras.

Explicación:

Jonathan Allan ya ha proporcionado una buena explicación para el código Jelly, por lo que cubre el bit de octava y por qué funciona (y no funcionaría en 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

Esto no funciona en MATLAB, ya que las asignaciones en línea y la indexación directa no funcionan. sort(x)(1)da un error en MATLAB, no el primer elemento en el vector ordenado.


8

Haskell, 41 bytes

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

Ejemplo de uso: ([]#) [4,3,2,5]-> [2,2,3,2]. Pruébalo en línea!

Comience con un acumulador vacío ay recorra la lista de entrada. El siguiente elemento en la lista de salida es el mínimo del acumulador ay todos menos el primer elemento de la lista de entrada (-> c) seguido de una llamada recursiva con el primer elementob agregado al acumulador y c. Deténgase cuando llegue al final de la lista de entrada.


7

JavaScript (ES6), 50 46 bytes

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

Editar: Guardado 4 bytes gracias a @Arnauld.


a=>a.map(x=>Math.min(...a.filter(y=>x!=y)))por 43 bytes.
Shaggy

@ Shaggy No creo que funcione para una entrada como3,3,3,3
Arnauld

D'oh! No, no funcionará si hay 2 o más ocurrencias del valor mínimo.
Shaggy

1
Sin embargo, puedes hacerlo a=>a.map((_,i)=>Math.min(...a.filter(_=>i--)))por 46.
Arnauld

@Arnauld Muy inteligente, ¡gracias!
Neil

7

Brachylog , 13 12 bytes

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

Pruébalo en línea!

Guardado un byte gracias a @ ais523.

Explicación

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

Explotamos el hecho de que unifica subconjuntos de mayor a menor. Por ejemplo para[1,2,3] los subconjuntos que recibimos son en este orden: [1,2,3], [1,2], [1,3], [2,3], [1], [2], [3], [].

Podemos ver que los subconjuntos [1,2], [1,3], [2,3]son de los que queremos el mínimo, pero están en el orden inverso en comparación con la lista de entrada (de ahí el ). Podemos seleccionar esos subconjuntos solo encontrando los primeros length(Input) + 1subconjuntos, que contendrán todos ellos + toda la lista primero. Descartamos toda esa lista con b.


1
Puede guardar un byte dividiendo su "subconjunto findall + mínimo" en "subconjunto findall" y "mínimo del mapa". (Tengo que ir a añadir esto a la punta del hilo Brachylog, ahora usted me recordó de él.)

1
@ ais523 Gracias, siempre me olvido de ese truco ...
Fatalize

6

Actualmente , 13 bytes

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

Utiliza la misma técnica que xnor también descubrió .

Pruébalo en línea!

Explicación:

;;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

1
¿Todavía no nos ha permitido ver la pila global dentro de la pila temporal?
Leaky Nun

1
@LeakyNun Todavía no. En el estado actual en que se encuentra el código del intérprete, eso sería muy difícil. Después de terminar la gran refactorización en la que estoy trabajando, veré cómo agregar esa funcionalidad.
Mego

1
¿Cuándo comenzaste la gran refactorización?
Leaky Nun

6

R, 46 31 bytes

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

implementa la solución de Stewie Griffin en R, ¡ay, mi idea original es un 50% más larga! todavía lee la lista de stdin, pero ahora devuelve un vector numérico mucho más legible.

Pruébalo en línea!

implementación anterior:

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

lee en la lista de stdin. Un índice negativo l[-x]excluye el elemento de la lista y match(l,l)devuelve el índice de la primera aparición de cada elemento de la lista. Devuelve una lista.


5

Python 2, 51 bytes

Sé que ya hay una mejor solución de Python, pero aún quiero publicar la mía.

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

Pruébalo en línea




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);}

El primer argumento es la matriz de enteros de entrada. El segundo argumento es la matriz de enteros de salida. El tercer argumento es el recuento de elementos para ambas matrices.

Véalo trabajar en línea .


3

Perl 6 ,  26 24  19 bytes

26

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

Tenga en cuenta que es U + 2216 no \U + 5C

Intentalo

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

Intentalo

24

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

Intentalo

19

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

Intentalo


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
}

Usé los operadores unicode "elegantes" lugar de los equivalentes ascii porque habrían requerido un espacio antes de ellos para que no fueran analizados como parte de la .Bagllamada al método.

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
  ]
}

(Los campos de golf de 24 y 19 bytes se inspiraron en una implementación de Jelly )


3

Clojure, 36 81 62 71 bytes

Lo más nuevo (realmente no debería enviar esto con prisa):

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

Pruébalo en línea .

Aaa y este tiene un error (62 bytes), zipmap produce un mapa desordenado para que esto no produzca la secuencia correcta en entradas más grandes.

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

v en realidad no se usa para nada, pero esto es más corto que i (keys c) .

Anterior a 81 bytes:

Pruébalo en línea .

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

Pruébalo en línea .

Oh, maldita sea, el original (36 bytes) no funciona cuando se repite el número mínimo, como [4 2 2 5]resultado se eliminan [2 4 4 2]ambos 2s :(

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

#{i}es el conjunto que contiene solo i, devuelve verdad parai y falso para otros, lo que significa que el mínimo se calcula a partir de todos los demás números dentro de la lista de entrada.

Pruébalo en línea .





2

Scala, 37 bytes

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

l es cualquier colección de int.

Casos de prueba:

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)

Esto probablemente todavía se pueda jugar al golf, no pude encontrar una forma más corta de eliminar un elemento de una lista que l diff Seq(l(i))


2

C #, 36 bytes

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

Toma los elementos (i) y busca en los elementos sin el elemento actual el valor mínimo.

Es un poco triste que otros intentos no funcionen, ya que trabajamos con tipos primitivos y, por lo tanto, no tenemos listas con referencias para comparar los elementos.


2

PowerShell , 49 38 bytes

-11 bytes gracias a mazzy

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

Pruébalo en línea!

Mejora de la encantadora respuesta de Sinusoid . Ahorra 10 bytes utilizando una salida explícita en lugar de construir una matriz. Índices en la matriz ordenada para detectar el punto 0 (es decir, el valor más pequeño) o el punto 1 si el condicional es verdadero.


1
Es inteligente Ahorre más :) ¡ Pruébelo en línea!
mazzy

1
@mazzy Bien hecho. Es obvio ahora que lo veo, pero nunca lo habría logrado.
Veskah

1
¡Buen trabajo! El tuyo es más encantador :)
Sinusoid

1

Perl 5, 43 bytes

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

Equivalente a la solución Python. sortLamentablemente , Perl tiene un valor predeterminado incorrecto para los números (que requiere un comparador explícito) y minno está integrado, pero casi lo compensa subsiendo más corto que lambda, map$_,más corto que x for x in, y la implícita de las listas de retorno y argumentos.


1

Rubí, 30 bytes.

Para cada elemento, ordene la matriz, elimine el elemento actual y tome el primer elemento de la matriz restante.

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

Es una función anónima que se puede usar así:

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

1

CJam, 15 bytes

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

Esencialmente una traducción del algoritmo de xnor a CJam.

Este es un bloque sin nombre que toma una matriz de la pila y deja el resultado en la pila.

Explicación:

{
  :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
}

1
@LuisMendo Whoops: olvidé ordenar la matriz. Debería funcionar ahora.
Esolanging Fruit

1

05AB1E , 5 bytes

{sWQè

Puerto de la respuesta Python 2 de @xnor .

Pruébelo en línea o verifique todos los casos de prueba .

Explicación:

{        # 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]

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];}

Puerto de la respuesta Python 2 de @xnor .

Modifica la matriz de entrada en lugar de devolver una nueva para guardar bytes.

Pruébalo en línea.

Explicación:

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

1

APL (Dyalog Extended) , 7 bytes

Port of xnor's Python 2 respuesta. Requiere ⎕IO←0:

∧⊇⍨⊢=⌊/

Pruébalo en línea!

Explicación:

∧⊇⍨⊢=⌊/   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

1

Haskell , 76 bytes

Esto es considerablemente más largo que las entradas anteriores de Haskell, pero es el primero que solo realiza un número lineal de comparaciones y una cantidad lineal de trabajo adicional.

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

Pruébalo en línea!

Explicación

!toma dos argumentos: un mínimo de ejecución y una lista no vacía. Devuelve el valor mínimo en la lista y el resultado de procesar la lista dada usando el mínimo en ejecución.


1

MathGolf , 9 7 bytes

s_╓?m=§

Pruébalo en línea!

Explicación

Básicamente un puerto de la respuesta 05AB1E de Kevin Cruijssen, pero pierdo 2 bytes gracias a tener que hacer las cosas explícitamente.

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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.