Movendo o mínimo modesto


40

Inspirado por uma pergunta no Stack Overflow. O título aqui é inteiramente minha culpa.


O desafio

Dada uma lista de números inteiros positivos contendo pelo menos duas entradas, substitua cada número pelo mínimo de todas as entradas, excluindo a si mesma.

Casos de teste

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

Regras

O algoritmo deve teoricamente funcionar para qualquer tamanho de entrada (maior que um) e valores (números inteiros positivos). É aceito se o programa é limitado por tempo, memória ou tipos de dados e, portanto, funciona apenas para números até um determinado valor ou para tamanho de entrada até um determinado valor.

Programas ou funções são permitidos, em qualquer linguagem de programação . As brechas padrão são proibidas.

A entrada pode ser obtida por qualquer meio razoável ; e com qualquer formato. Mesmo para saída. Os formatos de entrada e saída podem ser diferentes.

O menor código em bytes vence.


O que deve [4 3 2 2 5]produzir?
Kritixi Lithos

@KritixiLithos o segundo caso de teste não cobriu isso?
Leaky Nun

@KritixiLithos Para entrada [4 3 2 2 5]a saída seria [2 2 2 2 2](isto é similar à segunda etapa de teste)
Luis Mendo

Oh, eu perdi o segundo caso de teste. Mas agora eu entendo como ele funciona
Kritixi Lithos

@LuisMendo Você alterou "número inteiro" para "qualquer tamanho e valor de entrada". Isso significa que precisamos contabilizar todos os números reais?
Freira vazada

Respostas:


19

Geléia , 9 6 5 bytes

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

 J [1,2,3, ..., len (z)]
z gire z de acordo com a quantidade acima (a matriz atual é 2D)
  Ṗ remover a última matriz
   «/ Reduzir em [vetor implicitamente vetorizado]

Experimente online!

Verifique todos eles de uma vez! (ligeiramente modificado)

Tenho certeza que Dennis pode jogar fora isso.

Como funciona

O algoritmo é bastante complicado. Vamos observar o que isso faz [4,2,2,5].

Em primeiro lugar, usamos Jpara obter [1,2,3,4]. Observe que o Jelly usa a indexação 1.

Então nós vemos . São necessários dois argumentos: uma matriz e um número inteiro. Ele gira a matriz para a esquerda em uma quantidade especificada pelo número inteiro. Aqui, veria [4,2,2,5]à esquerda e [1,2,3,4]à direita (mais sobre como isso funciona pode ser encontrado no tutorial ). No Jelly, os comandos vetorizam implicitamente. Portanto, este comando será executado sobre cada elemento individual à direita, e é por isso que criaríamos uma matriz 2D:

Portanto, [4,2,2,5]ṙ[1,2,3,4]torna-se [[4,2,2,5]ṙ1,[4,2,2,5]ṙ2,[4,2,2,5]ṙ3,[4,2,2,5]ṙ4], o que se torna:

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

Observe que os elementos originais estão na última linha, pois, nessa linha, giramos para a esquerda por uma quantidade igual ao comprimento da matriz, e é por isso que usamos a seguir para remover essa linha, para que as colunas sejam as coleções de os elementos da matriz que não estão no índice atual:

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

A operação a seguir,, «/também é bastante complicada. Primeiro, «retorna o mínimo dos dois números que vê à esquerda e à direita. Por exemplo, 5«3retorna 3. Agora, se os dois argumentos forem arrays, ele será vetorizado como eu disse acima. O que isso significa é que [1,5,2,3]«[4,1,5,2]se tornaria o [1«4,5«1,2«5,3«2]que é [1,1,2,2]. Agora, /é reduce, o que significa que fazemos a operação em cada linha até o final. Por exemplo, [1,2,3,4]+/se tornaria ((1+2)+3)+4, que é a soma da matriz [1,2,3,4].

Portanto, se aplicarmos «/à matriz 2D que acabamos de obter, obteremos:

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

que, devido à vetorização, seria equivalente a:

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

que calcula o mínimo de cada matriz sem o elemento no índice.


11
Oh, sua edição ... você chegou primeiro.
Jonathan Allan

11
@JonathanAllan me desculpe.
Freira vazada

40

Python 2 , 41 bytes

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

Experimente online!

Para cada elemento x, verificamos se x==min(l). Caso contrário, trata-se do Falseque é tratado 0como um índice de lista sorted(l), fornecendo o menor elemento. Caso contrário, é Trueconhecido como 1dando o segundo menor elemento, já que esse elemento é o menor e deve ser ignorado.


2
Tenho dificuldade em acreditar que isso funciona.
Freira vazada

2
Ótima abordagem!
Luis Mendo

Você poderia adicionar uma explicação? Não seria muito complicado, mas o truque de "todo número será o mínimo, exceto aquele que é o mínimo, que será o segundo menor" e o fato de que Falseé convertido 0e Trueconvertido 1é realmente arrefecer e deve ser gabava ^ W ^ Wexplained
Nic Hartley

18

Gelatina , 5 bytes

=Ṃ‘ịṢ

Experimente online!

Quão?

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

4
@LeakyNun Esta não é uma porta, é apenas o mesmo método, eu ainda estou procurando menos também ... Eu upvoted essa resposta também agora :)
Jonathan Allan

5
@LeakyNun Eu sou novo aqui, mas você é sempre tão hostil? Não é como se houvesse várias maneiras únicas de abordar isso. Mesmo que ele tenha portado, ele ainda tem a resposta mais curta.
Grayson Kent

3
@GraysonKent Peço desculpas pela minha hostilidade percebida.
Freira vazada

11
@GraysonKent Bem-vindo ao PPCG!
Luis Mendo

11
@LeakyNun Isso acontece muito em desafios mais simples, você não pode realmente dizer que cada resposta é um porto de cada outro
ASCII-only

12

Haskell , 42 41 39 bytes

EDITAR:

  • -1 byte graças a nimi!
  • -2 bytes. Um agradecimento ao xnor! E um sozinho.

fpega uma lista de números inteiros (ou qualquer Ordtipo) e retorna uma lista.

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

Experimente online!

fse repete enquanto gira a lista. xé o primeiro elemento da lista e yo restante. Como a recursão é infinita, a lista de resultados precisa ser cortada: fst<$>zip...yé uma maneira mais curta de dizer take(length y)....


11
Você pode salvar um byte nomeando toda a lista de entrada via @e virar as listas para ser compactado: f l@(x:y)=fst<$>zip(minimum...)l.
N

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

9

Oitava, 26 bytes

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

Uma abordagem semelhante à usada nesta resposta , que é a mesma que esta .

Eu não sou realmente fã de apenas portar outras respostas, e é por isso que eu gostaria de observar que tive uma ideia semelhante antes de ver as outras.

Explicação:

Jonathan Allan já forneceu uma boa explicação para o código Jelly, então isso abrange o bit Octave e por que ele funciona (e não funcionaria no 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

Isso não funciona no MATLAB, pois as atribuições embutidas e a indexação direta não funcionam. sort(x)(1)dá um erro no MATLAB, não o primeiro elemento no vetor classificado.


8

Haskell, 41 bytes

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

Exemplo de uso: ([]#) [4,3,2,5]-> [2,2,3,2]. Experimente online!

Comece com um acumulador vazio ae execute a lista de entradas. O próximo elemento na lista de saída é o mínimo do acumulador ae todos, exceto o primeiro elemento da lista de entrada (-> c), seguido de uma chamada recursiva com o primeiro elemento badicionado ao acumulador e c. Pare quando você chegar ao final da lista de entrada.


7

JavaScript (ES6), 50 46 bytes

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

Editar: salvou 4 bytes graças a @Arnauld.


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

@Shaggy Eu não acho que funciona para uma entrada como3,3,3,3
Arnauld

D'oh! Não, não funcionará se houver 2 ou mais ocorrências do valor mínimo.
Shaggy

11
No entanto, você pode fazer a=>a.map((_,i)=>Math.min(...a.filter(_=>i--)))para 46.
Arnauld

@ Arnauld Muito inteligente, obrigado!
315 Neil

7

Braquilog , 13 12 bytes

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

Experimente online!

Guardou um byte graças a @ ais523.

Explicação

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

Exploramos o fato de unificar subconjuntos do maior para o menor. Por exemplo, para [1,2,3]os subconjuntos que recebemos são, nesta ordem: [1,2,3], [1,2], [1,3], [2,3], [1], [2], [3], [].

Podemos ver que os subconjuntos [1,2], [1,3], [2,3]são aqueles dos quais queremos o mínimo, mas estão na ordem inversa em comparação com a lista de entrada (daí a ). Podemos selecionar esses subconjuntos apenas localizando os primeiros length(Input) + 1, que conterão todos eles + a lista inteira primeiro. Nós descartamos toda a lista com b.


11
Você pode salvar um byte dividindo seu "findall subconjunto + mínimo" em "findall subconjunto" e "map minimum". (Eu preciso ir adicione ao dicas fio Brachylog, agora você me lembrou disso.)

11
@ ais523 Obrigado, eu sempre esqueço esse truque ...
Fatalize

6

Na verdade , 13 bytes

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

Usa a mesma técnica que o xnor também descobriu .

Experimente online!

Explicação:

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

11
Você ainda não nos permitiu examinar a pilha global dentro da pilha temporária?
Freira vazada

11
@LeakyNun Ainda não. No estado atual em que o código do intérprete está, isso seria muito difícil. Depois de concluir a grande refatoração em que estou trabalhando, veremos como adicionar essa funcionalidade.
Mego

11
Quando você começou a grande refatoração?
Freira vazada

6

R, 46 31 bytes

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

implementa a solução de Stewie Griffin em R, infelizmente, minha ideia original é 50% mais longa! ainda lê a lista de stdin, mas agora retorna um vetor numérico muito mais legível.

Experimente online!

implementação antiga:

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

lê na lista de stdin. Um índice negativo l[-x]exclui o elemento da lista e match(l,l)retorna o índice da primeira ocorrência de cada elemento da lista. Retorna uma lista.


5

Python 2, 51 bytes

Eu sei que já existe uma solução Python melhor, mas ainda quero postar a minha.

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

Experimente online




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

O primeiro argumento é a matriz inteira de entrada. O segundo argumento é a matriz inteira de saída. O terceiro argumento é a contagem de elementos para ambas as matrizes.

Veja como funciona online .


3

Perl 6 ,  26 24  19 bytes

26

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

Observe que U + 2216 não \U + 5C

Tente

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

Tente

24

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

Tente

19

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

Tente


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
}

Usei os operadores unicode "sofisticados" em vez dos equivalentes ascii, porque eles precisariam de um espaço antes deles para que não fossem analisados ​​como parte da .Bagchamada do 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
  ]
}

(Os campos de golfe de 24 e 19 bytes foram inspirados por uma implementação Jelly )


3

Clojure, 36 81 62 71 bytes

Mais novo (não deve realmente enviá-los com pressa):

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

Experimente online .

E esse aqui tem um bug (62 bytes), o zipmap produz um mapa não ordenado, portanto não produz a seqüência correta em entradas maiores.

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

vnão é realmente usado para nada, mas é mais curto que i (keys c).

Anterior aos 81 bytes:

Experimente online .

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

Experimente online .

Oh caramba, o original (36 bytes) não funciona quando o número mínimo é repetido, [4 2 2 5]resulta em [2 4 4 2]como os dois 2s são removidos :(

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

#{i}é o conjunto que contém apenas i, retorna verdade para ie falsifica para outros, significando que o mínimo é calculado a partir de todos os outros números na lista de entrada.

Experimente online .




2

PHP, 47 bytes

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

2

Scala, 37 bytes

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

l é qualquer coleção de Int.

Casos de teste:

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)

Provavelmente ainda pode ser jogado no golfe. Não foi possível encontrar uma maneira mais curta de remover um elemento de uma lista do que l diff Seq(l(i))


2

C #, 36 bytes

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

Pega os elementos (i) e procura nos elementos sem o item atual o valor mínimo.

É meio triste que algumas outras tentativas não funcionem, como trabalhamos com tipos primitivos e, portanto, não temos listas com referências para comparar os itens.


2

PowerShell , 49 38 bytes

-11 bytes graças ao mazzy

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

Experimente online!

Melhoria da adorável resposta de Sinusoid . Economiza 10 bytes usando saída explícita em vez de criar uma matriz. Indexa na matriz classificada para o ponto 0 (ou seja, o menor valor) ou o ponto 1 se a condicional for verdadeira.


11
Isso é esperto. Economize mais :) Experimente online!
mazzy 14/03

11
@mazzy Bem feito. É óbvio agora que eu o vejo, mas eu nunca teria reunido isso.
Veskah 14/03

11
Bom trabalho! O seu é mais adorável :)
Sinusoid

1

Perl 5, 43 bytes

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

Equivalente à solução Python. sortInfelizmente, o Perl tem o padrão errado para números (exigindo um comparador explícito) e minnão é incorporado, mas quase o compensa por subser mais curto do que lambda, map$_,mais curto do que x for x ine pela implicação das listas de retorno e argumentos.


1

Ruby, 30 bytes

Para cada elemento, classifique a matriz, remova o elemento atual e pegue o primeiro elemento da matriz restante.

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

É uma função anônima que pode ser usada assim:

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$=}%}

Essencialmente, uma tradução do algoritmo do xnor para o CJam.

Este é um bloco sem nome que pega uma matriz da pilha e deixa o resultado na pilha.

Explicação:

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

11
@LuisMendo Ops - eu esqueci de realmente classificar a matriz. Deve funcionar agora.
Esolanging Fruit

1

05AB1E , 5 bytes

{sWQè

Porta da resposta Python 2 do @xnor .

Experimente online ou verifique todos os casos de teste .

Explicação:

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

Porta da resposta Python 2 do @xnor .

Modifica a matriz de entrada em vez de retornar uma nova para salvar bytes.

Experimente online.

Explicação:

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

Porta da resposta Python 2 do xnor. Requer ⎕IO←0:

∧⊇⍨⊢=⌊/

Experimente online!

Explicação:

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

Isso é consideravelmente mais longo do que as entradas anteriores de Haskell, mas é a primeira que realiza apenas um número linear de comparações e uma quantidade linear de trabalho 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

Experimente online!

Explicação

!requer dois argumentos: um mínimo de execução e uma lista não vazia. Retorna o valor mínimo na lista e o resultado do processamento da lista fornecida usando o mínimo em execução.


1

MathGolf , 9 7 bytes

s_╓?m=§

Experimente online!

Explicação

Basicamente, uma porta da resposta 05AB1E de Kevin Cruijssen, mas eu perco 2 bytes devido a ter que fazer as coisas explicitamente.

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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.