Spostamento minimo modesto


40

Ispirato da una domanda sopra Stack Overflow. Il titolo qui è interamente colpa mia.


La sfida

Dato un elenco di numeri interi positivi contenenti almeno due voci, sostituire ciascun numero con il minimo di tutte le voci escluso se stesso.

Casi test

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

Regole

L'algoritmo dovrebbe teoricamente funzionare per qualsiasi dimensione di input (maggiore di uno) e valori (numeri interi positivi). È accettato se il programma è limitato da tempo, memoria o tipi di dati e quindi funziona solo per numeri fino a un determinato valore o per dimensioni di input fino a un determinato valore.

Programmi o funzioni sono consentiti, in qualsiasi linguaggio di programmazione . Sono vietate le scappatoie standard .

L'input può essere preso con qualsiasi mezzo ragionevole ; e con qualsiasi formato. Lo stesso per l'output. I formati di input e output possono essere diversi.

Vince il codice più breve in byte.


Cosa dovrebbe [4 3 2 2 5]produrre?
Kritixi Lithos,

@KritixiLithos non ha riguardato il secondo caso di test?
Leaky Nun,

@KritixiLithos Per l'input [4 3 2 2 5]l'output sarebbe [2 2 2 2 2](questo è simile al secondo caso di test)
Luis Mendo

Oh, ho perso il secondo caso di test. Ma ora capisco come funziona
Kritixi Lithos,

@LuisMendo Hai modificato "numero intero" in "qualsiasi dimensione e valore di input". Ciò significa che dobbiamo tenere conto di tutti i numeri reali?
Leaky Nun,

Risposte:


19

Gelatina , 9 6 5 byte

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

 J [1,2,3, ..., len (z)]
ṙ ruota z di ciascuna delle quantità di cui sopra (l'array corrente è 2D)
  Ṗ rimuovere l'ultimo array
   «/ Riduzione del minimo [impliclitly vettorializzato]

Provalo online!

Verifica tutti in una volta! (leggermente modificato)

Sono abbastanza sicuro che Dennis possa giocare a golf.

Come funziona

L'algoritmo è piuttosto contorto. Osserviamo cosa fa questo [4,2,2,5].

In primo luogo, usiamo Jper ottenere [1,2,3,4]. Nota che Jelly utilizza l'indicizzazione 1.

Quindi vediamo . Sono necessari due argomenti: un array e un numero intero. Ruota l'array a sinistra di un importo specificato dall'intero. Qui, vedrebbe [4,2,2,5]alla sua sinistra e [1,2,3,4]alla sua destra (di più su come funziona può essere trovato nel tutorial ). In Jelly, i comandi implicitamente vettorializzano. Pertanto, questo comando verrà eseguito su ogni singolo elemento a destra, motivo per cui dovremmo creare un array 2D:

Pertanto, [4,2,2,5]ṙ[1,2,3,4]diventa [[4,2,2,5]ṙ1,[4,2,2,5]ṙ2,[4,2,2,5]ṙ3,[4,2,2,5]ṙ4], che diventa:

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

Si noti che gli elementi originali si trovano nell'ultima riga, poiché in quella riga abbiamo ruotato a sinistra di un importo pari alla lunghezza dell'array, motivo per cui utilizziamo accanto per rimuovere quella riga, in modo che le colonne siano le raccolte di gli elementi dell'array che non si trovano nell'indice corrente:

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

Anche l'operazione seguente «/è piuttosto contorta. In primo luogo, «restituisce il minimo dei due numeri che vede alla sua sinistra e alla sua destra. Ad esempio, 5«3restituisce3 . Ora, se i due argomenti sono array, allora vettorializzerebbe come ho detto sopra. Cosa significa che [1,5,2,3]«[4,1,5,2]diventerebbe quello [1«4,5«1,2«5,3«2]che è [1,1,2,2]. Ora, /è reduce, il che significa che eseguiamo l'operazione su ogni riga fino alla fine. Ad esempio, [1,2,3,4]+/diventerebbe ((1+2)+3)+4, che è la somma dell'array [1,2,3,4].

Quindi, se applichiamo «/all'array 2D che abbiamo appena ottenuto, otterremmo:

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

che, a causa della vettorializzazione, sarebbe equivalente a:

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

che calcola il minimo di ogni array senza l'elemento nell'indice.


1
Oh, la tua modifica ... ci sei arrivato prima.
Jonathan Allan,

1
@JonathanAllan Mi dispiace.
Leaky Nun,

40

Python 2 , 41 byte

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

Provalo online!

Per ogni elemento xcontrolliamo se x==min(l). In caso contrario, questo è False, che viene trattato come 0quando usato come indice di elenco in sorted(l), fornendo l'elemento più piccolo. Altrimenti, è Trueaka 1, che dà il secondo elemento più piccolo, poiché quell'elemento stesso è il più piccolo e dovrebbe essere ignorato.


2
Ho difficoltà a credere che funzioni.
Leaky Nun,

2
Ottimo approccio!
Luis Mendo,

Potresti aggiungere una spiegazione? Non sarebbe molto complicato, ma il trucco di "ogni numero sarà il minimo, tranne quello che è il minimo, che sarà il secondo più piccolo" e il fatto che Falseviene convertito 0e Trueconvertito in 1sono davvero bello e dovrebbe essere vantato ^ W ^ Wexplained
Fund Monica's Lawsuit

18

Gelatina , 5 byte

=Ṃ‘ịṢ

Provalo online!

Come?

=Ṃ‘ịṢ - 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 Questa non è una porta, è solo lo stesso metodo, sto ancora cercando di meno ... Ho votato troppo questa risposta ora :)
Jonathan Allan

5
@LeakyNun Sono nuovo qui, ma sei sempre così ostile? Non è che ci siano tonnellate di modi unici per affrontarlo. Anche se lo ha portato, ha ancora la risposta più breve.
Grayson Kent,

3
@GraysonKent Mi scuso per l'ostilità percepita.
Leaky Nun,

1
@GraysonKent Benvenuti in PPCG!
Luis Mendo,

1
@LeakyNun Questo succede molto nelle sfide più semplici, non si può davvero dire che ogni risposta è una porta di ogni altra
solo ASCII

12

Haskell , 42 41 39 byte

MODIFICARE:

  • -1 byte grazie a nimi!
  • -2 byte. Uno grazie a xnor! E uno da solo.

fprende un elenco di numeri interi (o qualsiasi Ordtipo) e restituisce un elenco.

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

Provalo online!

frecluta mentre ruota l'elenco. xè il primo elemento dell'elenco e yil resto. Poiché la ricorsione è infinita, l'elenco dei risultati deve essere tagliato: fst<$>zip...yè un modo più breve di dire take(length y)....


1
È possibile salvare un byte nominando l'intera lista di input tramite @e capovolgere le liste per essere zip: f l@(x:y)=fst<$>zip(minimum...)l.
nimi,

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

9

Ottava, 26 byte

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

Un approccio simile a quello usato in questa risposta , che sembra essere lo stesso di questo .

Non sono proprio un fan del porting di altre risposte, motivo per cui mi piacerebbe notare che avevo un'idea simile prima di vedere le altre.

Spiegazione:

Jonathan Allan ha già fornito una buona spiegazione per il codice Jelly, quindi questo copre il bit di Ottava e perché funziona (e non funzionerebbe 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

Questo non funziona in MATLAB, poiché le assegnazioni in linea e l'indicizzazione diretta non funzionano. sort(x)(1)dà un errore in MATLAB, non il primo elemento nel vettore ordinato.


8

Haskell, 41 byte

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

Esempio di utilizzo: ([]#) [4,3,2,5]-> [2,2,3,2]. Provalo online!

Inizia con un accumulatore vuoto aed esegui l'elenco di input. L'elemento successivo nell'elenco di output è il minimo dell'accumulatore ae tutti tranne il primo elemento dell'elenco di input (-> c) seguito da una chiamata ricorsiva con il primo elemento baggiunto all'accumulatore e c. Interrompi quando raggiungi la fine dell'elenco di input.


7

JavaScript (ES6), 50 46 byte

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

Modifica: salvato 4 byte grazie a @Arnauld.


a=>a.map(x=>Math.min(...a.filter(y=>x!=y)))per 43 byte.
Shaggy,

@Shaggy Non credo che funzioni per un input come3,3,3,3
Arnauld,

D'oh! No, non funzionerà se ci sono 2 o più occorrenze del valore minimo.
Shaggy,

1
Tuttavia, puoi farlo a=>a.map((_,i)=>Math.min(...a.filter(_=>i--)))per 46.
Arnauld

@Arnauld Molto intelligente, grazie!
Neil,

7

Brachylog , 13 12 byte

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

Provalo online!

Salvato un byte grazie a @ ais523.

Spiegazione

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

Sfruttiamo il fatto che unifica i sottoinsiemi dal più grande al più piccolo. Ad esempio, per [1,2,3], i sottoinsiemi che otteniamo sono in questo ordine: [1,2,3], [1,2], [1,3], [2,3], [1], [2], [3], [].

Possiamo vedere che i sottoinsiemi [1,2], [1,3], [2,3]sono quelli da cui vogliamo il minimo, ma sono nell'ordine inverso rispetto all'elenco di input (da qui il ). Possiamo selezionare quei sottoinsiemi solo trovando i primi length(Input) + 1sottoinsiemi, che conterranno prima tutti loro + l'intero elenco. Eliminiamo l'intero elenco con b.


1
È possibile salvare un byte suddividendo "sottoinsieme findall + minimo" in "sottoinsieme findall" e "minimo mappa". (Devo aggiungere questo al thread dei suggerimenti di Brachylog, ora me lo hai ricordato.)

1
@ ais523 Grazie, mi dimentico sempre di quel trucco ...
Fatalizza il

6

In realtà , 13 byte

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

Utilizza la stessa tecnica che ha scoperto anche xnor .

Provalo online!

Spiegazione:

;;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
Non ci hai ancora permesso di esaminare lo stack globale all'interno dello stack temporaneo?
Leaky Nun,

1
@LeakyNun Non ancora. Allo stato attuale in cui si trova il codice dell'interprete, sarebbe molto difficile. Dopo aver terminato il grande refactoring su cui sto lavorando, vedrò di aggiungere quella funzionalità.
Mego

1
Quando hai iniziato il grande refactoring?
Leaky Nun,

6

R, 46 31 byte

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

implementa la soluzione di Stewie Griffin in R, ahimè, la mia idea originale è più lunga del 50%! legge ancora l'elenco da stdin, ma ora restituisce un vettore numerico molto più leggibile.

Provalo online!

vecchia implementazione:

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

legge nell'elenco da stdin. Un indice negativo l[-x]esclude l'elemento dall'elenco e match(l,l)restituisce l'indice della prima occorrenza di ciascun elemento dell'elenco. Restituisce un elenco.


5

Python 2, 51 byte

So che esiste già una soluzione Python migliore, ma voglio ancora pubblicare la mia.

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

Provalo online



5

PowerShell , 68 59 byte

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

Provalo online!

Sono abbastanza fiducioso che possa essere abbreviato, continuerò a guardarlo


4

C, 85 byte

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

Il primo argomento è l'array intero di input. Il secondo argomento è l'array intero di output. Il terzo argomento è il conteggio degli elementi per entrambi gli array.

Guardalo funzionare online .


3

Perl 6 ,  26 24  19 byte

26

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

Si noti che è U + 2216 non \U + 5C

Provalo

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

Provalo

24

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

Provalo

19

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

Provalo


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
}

Ho usato gli operatori unicode "fantasiosi" piuttosto che gli equivalenti ASCII perché avrebbero richiesto uno spazio prima di loro in modo da non essere analizzati come parte della .Bagchiamata del metodo.

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

(I golf da 24 e 19 byte sono stati ispirati da un'implementazione di Jelly )


3

Clojure, 36 81 62 71 byte

Più recenti (non dovresti davvero inviarli in fretta):

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

Provalo online .

Anche se questo ha un bug (62 byte), zipmap produce una mappa non ordinata in modo che non produca la sequenza corretta su input più grandi.

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

vnon è effettivamente utilizzato per nulla ma è più breve di i (keys c).

Precedente a 81 byte:

Provalo online .

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

Provalo online .

Oh dannazione l'originale (36 byte) non funziona quando si ripete il numero minimo, si [4 2 2 5]ottiene [2 4 4 2]come entrambi 2vengono rimossi :(

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

#{i}è l'insieme che contiene solo i, restituisce verità ie falsità per gli altri, il che significa che il minimo viene calcolato da tutti gli altri numeri nell'elenco di input.

Provalo online .




2

PHP, 47 byte

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

2

Scala, 37 byte

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

l è una raccolta di Int.

Casi test:

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)

Probabilmente questo può ancora essere giocato a golf, non sono riuscito a trovare un modo più breve per rimuovere un elemento da un elenco di l diff Seq(l(i))


2

C #, 36 byte

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

Prende gli elementi (i) e cerca gli elementi senza l'elemento corrente per il valore minimo.

È un po 'triste, che alcuni altri tentativi non funzionino, poiché lavoriamo con tipi primitivi e quindi non abbiamo elenchi con riferimenti per confrontare gli elementi.


2

PowerShell , 49 38 byte

-11 byte grazie a mazzy

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

Provalo online!

Miglioramento della bella risposta di Sinusoid . Salva 10 byte utilizzando l'output esplicito invece di creare un array. Indica nella matrice ordinata lo spot 0 (ovvero il valore più piccolo) o lo spot 1 se il condizionale è vero.


1
È intelligente. Risparmia di più :) Provalo online!
mazzy

1
@mazzy Ben fatto. È ovvio ora che lo vedo ma non lo avrei mai messo insieme.
Veskah

1
Bel lavoro! Il tuo è più adorabile :)
Sinusoide,

1

Perl 5, 43 byte

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

Equivalente alla soluzione Python. sortSfortunatamente , Perl ha un valore predefinito errato per i numeri (che richiede un comparatore esplicito), e minnon è integrato, ma quasi lo compensa subessendo più corto di lambda, map$_,essendo più corto di x for x in, e l'implicazione di return e args list.


1

Rubino, 30 byte

Per ogni elemento, ordina l'array, rimuovi l'elemento corrente e prendi il primo elemento dell'array rimanente.

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

È una funzione anonima che può essere utilizzata in questo modo:

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

1

CJam, 15 byte

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

Essenzialmente una traduzione dell'algoritmo di xnor in CJam.

Questo è un blocco senza nome che prende un array dallo stack e lascia il risultato nello stack.

Spiegazione:

{
  :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 - Ho dimenticato di ordinare effettivamente l'array. Dovrebbe funzionare ora.
Esolanging Fruit,

1

05AB1E , 5 byte

{sWQè

Porta della risposta Python 2 di @xnor .

Provalo online o verifica tutti i casi di test .

Spiegazione:

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

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 della risposta Python 2 di @xnor .

Modifica l'input-array invece di restituirne uno nuovo per salvare i byte.

Provalo online.

Spiegazione:

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 byte

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

∧⊇⍨⊢=⌊/

Provalo online!

Spiegazione:

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

Questo è notevolmente più lungo rispetto alle precedenti voci di Haskell, ma è il primo che esegue solo un numero lineare di confronti e una quantità lineare di lavoro aggiuntivo.

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

Provalo online!

Spiegazione

!accetta due argomenti: un minimo corrente e un elenco non vuoto. Restituisce il valore minimo nell'elenco e il risultato dell'elaborazione dell'elenco specificato utilizzando il minimo corrente.


1

MathGolf , 9 7 byte

s_╓?m=§

Provalo online!

Spiegazione

Fondamentalmente una porta della risposta 05AB1E di Kevin Cruijssen, ma perdo 2 byte grazie a dover fare le cose in modo esplicito.

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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.