Solleva un singolo numero


25

introduzione

Supponiamo di voler calcolare i massimi di coda di un elenco di numeri, ovvero il massimo di ciascun suffisso non vuoto. Un modo per farlo è scegliere ripetutamente un numero e sostituirlo con un numero più elevato che si verifica dopo di esso, fino a quando questo non è più possibile. In questa sfida, il tuo compito è eseguire un passaggio di questo algoritmo.

L'obiettivo

Il tuo input è un elenco di numeri interi L , che può essere vuoto. L'output deve essere l'elenco L in cui esattamente un numero L i è stato sostituito da un altro L j , dove L i <L j e i <j .

In altre parole, è necessario sostituire un numero con un numero più elevato che si verifica dopo di esso.

Puoi scegliere i e j liberamente tra tutte le coppie valide e la scelta può essere non deterministica.

Se tale i e j non esistono (ovvero L non è in aumento), l'output deve essere L invariato.

Esempio

Considera l'ingresso L = [3, 1, 4, -1, 2] . Le operazioni possibili sono sostituire 3 per 4 , sostituire 1 per 4 , sostituire 1 per 2 o sostituire -1 per 2 . Pertanto le possibili uscite sono:

 [  3 ,   1 ,   4 ,  -1 ,   2 ]
 ------------------------------
 [( 4),   1 ,(  4),  -1 ,   2 ]
 [  3 ,(  4),(  4),  -1 ,   2 ]
 [  3 ,(  2),   4 ,  -1 ,(  2)]
 [  3 ,   1 ,   4 ,(  2),(  2)]

Se si ripete il numero sufficiente di tempi di funzionamento, il risultato finale sarà [4,4,4,2,2] , che è appunto la lista di coda massimi di L .

Regole e punteggio

È possibile scrivere un programma completo o una funzione. In quest'ultimo caso, è possibile modificare l'input in atto anziché restituire un nuovo array, se la lingua lo consente. I formati di input e output sono flessibili entro limiti ragionevoli.

Vince il conteggio dei byte più basso.

Casi test

Vengono visualizzate tutte le possibili uscite.

[] -> []
[1] -> [1]
[1,2] -> [2,2]
[2,1] -> [2,1]
[4,4,4,4] -> [4,4,4,4]
[-1,-3,-10] -> [-1,-3,-10]
[1,3,10] -> [3,3,10] [10,3,10] [1,10,10]
[1,1,2,1] -> [2,1,2,1] [1,2,2,1]
[998,64,2,-94,-789] -> [998,64,2,-94,-789]
[998,2,64,-94,-789] -> [998,64,64,-94,-789]
[3,1,4,-1,2] -> [4,1,4,-1,2] [3,4,4,-1,2] [3,2,4,-1,2] [3,1,4,2,2]
[-1,4,0,4,7,2,3] -> [4,4,0,4,7,2,3] [0,4,0,4,7,2,3] [-1,4,4,4,7,2,3] [7,4,0,4,7,2,3] [-1,7,0,4,7,2,3] [-1,4,7,4,7,2,3] [-1,4,0,7,7,2,3] [2,4,0,4,7,2,3] [-1,4,2,4,7,2,3] [3,4,0,4,7,2,3] [-1,4,3,4,7,2,3] [-1,4,0,4,7,3,3]
[3542,-12311,7662,1672,6081] -> [7662,-12311,7662,1672,6081] [3542,7662,7662,1672,6081] [3542,1672,7662,1672,6081] [6081,-12311,7662,1672,6081] [3542,6081,7662,1672,6081] [3542,-12311,7662,6081,6081]

Risposte:


9

JavaScript (ES6), 41 40 39 38 byte

Salvato un byte grazie a @Neil, un altro grazie a @ user81655

x=>x.map(c=>c<x[++i]>d?x[d=i]:c,d=i=0)

Proprio quando sembra che reduceRightpossa finalmente avere una possibilità, si .mappresenta di nuovo ...


x=>x.map(c=>c<x[++i]&!d?x[d=i]:c,d=i=0)?
Neil

I condizionali vengono valutati da sinistra a destra, il che significa che x=>x.map(c=>c<x[++i]>d?x[d=i]:c,d=i=0)(38 byte) dovrebbe funzionare.
user81655

@ user81655 È incredibile :-)
ETHproductions

7

Mathematica, 37 byte

#/.{a___,b_,c_,d___}/;b<c:>{a,c,c,d}&

Funzione pura che prende un elenco di numeri reali pari e restituisce un elenco di numeri reali. Cerca la prima coppia di voci consecutive nell'ordine "errato" e sostituisce la prima di quella coppia con la seconda. Un buon comportamento predefinito /.significa che restituisce l'input inalterato quando appropriato.

Nota a margine divertente: se sostituiamo b<ccon !OrderedQ[{c,b}], la funzione funziona su stringhe (e in realtà qualsiasi tipo di dati una volta descritto l'ordinamento appropriato). Ad esempio, #/.{a___,b_,c_,d___}/;!OrderedQ[{c,b}]:>{a,c,c,d}&sui {"programming", "puzzles", "code", "golf"}ritorni di input {"puzzles", "puzzles", "code", "golf"}.


Un avvertimento per la nota a margine: l'ordinamento canonico delle stringhe di Mathematica è strano.
Martin Ender,

Come, Martin Ender?
Greg Martin,

Prova Sort[FromCharacterCode /@ Range[32, 127]]. Diventa strano una volta che hai stringhe con più parole, perché poi ignora spazi e cose.
Martin Ender,

6

JavaScript (ES6), 43 39 38 byte

a=>a[a.some(e=>e<a[++i],i=0)*i-1]=a[i]

Emette modificando l'array sul posto. Modifica: salvato 4 byte grazie a @ETHproductions. Salvato 1 byte grazie a @ user81655.


Penso che puoi farcela a=>a[i=0,a.findIndex(e=>e<a[++i])]=a[i]per 39.
ETHproductions

Un altro approccio per 40B:a=>a.map((_,b)=>Math.max(...a.slice(b)))
Luca

@Luke Penso che tu abbia frainteso la sfida; il punto è di ingrandire solo uno degli interi nell'array.
ETHproductions

@ETHproductions Grazie per aver restituito il favore, ora gli onori sono pari!
Neil,

Penso che potresti essere in grado di sostituire findIndexcon some(38 byte):a=>a[i=0,a.some(e=>e<a[++i])*i-1]=a[i]
user81655

5

Haskell , 36 byte

f(a:r@(b:_))|a<b=b:r|1>0=a:f r
f e=e

Provalo online!

Cerca nell'elenco gli elementi consecutivi a,bcon a<be li cambia in b,b.

Migliorato da 37 byte:

f(a:b:t)|a<b=b:b:t
f(a:t)=a:f t
f e=e

Penso che f(a:r@(b:_))=max(b:r)(a:f r)funzioni ed è più breve di due byte.
Ørjan Johansen,

@ ØrjanJohansen Questo è un metodo bellissimo! Penso che dovresti pubblicarlo come risposta personale. All'inizio non ero sicuro che avrebbe gestito correttamente i legami, ma ora vedo che funziona perché f r >= r.
xnor

Grazie, l'ho fatto !
Ørjan Johansen,

4

Gelatina , 13 11 byte

ṫJṀ€ż¹ŒpQ-ị

Sostituisce il numero più a destra di tutti i numeri possibili.

Provalo online!

Come funziona

ṫJṀ€ż¹ŒpQ-ị  Main link. Argument: A (array)

 J           Yield all indices of A, i.e., the array [1, ..., len(A)].
ṫ            Dyadic tail; for index k, take all elements starting with the k-th.
             This constructs the array of suffixes.
  Ṁ€         Maximum each; map the monadic maximum atom over the suffixes.
     ¹       Identity; yield A.
    ż        Zip; construct all pairs of elements of the result to the left and the
             corresponding elements of the result to the right.
      Œp     Cartesian product. Construct all arrays that, for each index, take
             either the left or the right element.
        Q    Unique; deduplicate the resulting arrays.
         -ị  At-index -1; select the second to last result.
             The last result is A itself, the first maxima of suffixes.

3

MATL , 15 byte

tdt0>0whY>d*0h+

Provalo online!

Non sono un grande fan di questa soluzione. Mi sembra orribilmente inefficiente. In particolare le sezioni whY>d*e 0h+.


3

Python 2, 139 134 93 byte

a=input()
for i in range(len(a)):
 for j in a[i+1:]:
    if a[i]<j:a[i]=j;print a;exit()
print a

Terribilmente lungo, ma è un primo tentativo.

-5 byte grazie a TemporalWolf
-41 (!!) byte grazie a Value Ink


[1,2][2,1]invece[2,2]
TemporalWolf il

1
@TemporalWolf Sì, ho letto male la sfida. Nessun byte salvato o perso verrà risolto.
HyperNeutrino,

Puoi rimuovere il ritorno prima del tuo interno printe usare una \tscheda invece di spazio extra per il ciclo interno. Inoltre, puoi rilasciare lo 0 exit()per uno in più. Dovresti portarti al 132.
TemporalWolf

@TemporalWolf Va bene, grazie!
HyperNeutrino,

1
if a[i]<a[j]:a[i]=a[j];print a;exit()è ancora più breve. Cavolo, è meglio farlofor j in a[i+1:]:\n\tif a[i]<j:a[i]=j;print a;exit()
Value Ink

3

MATL , 13 byte

ttd0>fX>Q)2M(

Provalo online!

Spiegazione

Le seguenti due condizioni sono equivalenti:

  1. C'è un numero che ha un numero più alto alla sua destra
  2. C'è un numero che ha un numero più alto immediatamente alla sua destra

Il codice utilizza la condizione 2, che è più semplice. Calcola incrementi consecutivi e trova l'ultimo, se presente. Per le due voci interessate, scrive il valore della seconda voce nella prima.

Questo trucco viene utilizzato per gestire il caso in cui non è possibile effettuare alcuna sostituzione. Si noti inoltre che l'indicizzazione MATL è 1basata.

Usiamo l'input [3,1,4,-1,2]come esempio.

tt    % Get input implicitly and duplicate it twice
      % STACK: [3,1,4,-1,2], [3,1,4,-1,2], [3,1,4,-1,2]
d     % Consecutive differences
      % STACK: [3,1,4,-1,2], [3,1,4,-1,2], [-2  3 -5  3]
0>    % Are they positive?
      % STACK: [3,1,4,-1,2], [3,1,4,-1,2], [0 1 0 1]
f     % Find indices of all positive differences. Result may be empty
      % STACK: [3,1,4,-1,2], [3,1,4,-1,2], [2 4]
X>    % Maximum index with a positive difference. Empty input remains as empty
      % STACK: [3,1,4,-1,2], [3,1,4,-1,2], 4
Q     % Add 1. Since the addition is elementwise, empty input remains as empty
      % STACK: [3,1,4,-1,2], [3,1,4,-1,2], 5
)     % Get the entry of the input at that position
      % STACK: [3,1,4,-1,2], 2
2M    % Push maximum index with a positive difference, again
      % STACK: [3,1,4,-1,2], 2, 4
(     % Assign to that position. Implicitly display
      % STACK: [3,1,4,2,2]

3

Haskell , 34 33 byte

Questo si basa sulla risposta di xnor , che mi ha suggerito di pubblicarlo da solo.

EDIT: xnor ha trovato un byte da salvare.

f(a:r@(b:_))=max(b:r)$a:f r
f e=e

Provalo online!

Fondamentalmente, ho osservato che la ramificazione del metodo di xnor finisce sempre per scegliere la più grande delle espressioni di diramazione, poiché Haskell utilizza l'ordinamento lessicografico per gli elenchi. (Il caso a==bfunziona anche perché f r>=r, che può essere provato separatamente per induzione.)

In altre parole, ogni volta b:r > a:f r, quindi b:rè una risposta corretta, e altrimenti possiamo recurse a a:f r.

Quindi, invece di controllare a<bin anticipo, calcolo solo entrambe le espressioni e prendo il massimo. Questo potrebbe dare un'esplosione esponenziale, sebbene la pigrizia di Haskell lo eviti a meno che ae bsiano uguali.


1
Sembra che max(b:r)$a:f rsalva un byte.
xnor

2

Python 3, 79 byte

def f(x):
 for i,a in enumerate(x):
  m=max(x[i+1:])
  if m>a:x[i]=m;break

Muta la matrice originale (elenco) assegnatagli. Non sono contento che questo non sia un lambda e sono sicuro che ci sono ottimizzazioni migliori; Spero di affrontarli più tardi.

Breve spiegazione

Prende il massimo dell'array oltre l'elemento corrente (a partire da zeroth). Quindi lo confronta con l'elemento stesso: se il massimo è maggiore, sostituisci l'elemento corrente con esso e ferma, altrimenti, incrementa di uno e continua a provarlo.



2

C, 47 byte

f(p,n)int*p;{n>1?*p<p[1]?*p=p[1]:f(p+1,n-1):0;}

Implementazione ricorsiva che assume come input un puntatore al primo elemento di un array e alla lunghezza dell'array. Modifica l'array in atto.


La restituzione del codice non è valida ideone.com/83HJqN
Khaled.K

@ Khaled.K Mostra l'output "3 4 4 -1 2", che è uno degli output consentiti indicati nella domanda. Cosa pensi sia sbagliato?
hvd,

Vedo, la domanda non è abbastanza chiara a riguardo però
Khaled.K

2

SWI-Prolog, 70 byte

f([H|T],[S|T]):-max_list(T,S),S>H,!.
f([H|T],[H|R]):-f(T,R),!.
f(I,I).

La prima clausola sostituisce il primo elemento dell'elenco con il valore massimo del resto dell'elenco, ma solo se questo massimo è maggiore. La seconda clausola chiama ricorsivamente il predicato per la coda dell'elenco. Se nessuna di queste clausole ha esito positivo, la terza clausola restituisce semplicemente l'input.

Questo ritorno è solo una delle possibili soluzioni. È banale trovarli tutti con un codice molto simile, ma poi il caso in cui non è possibile alcuna modifica richiede molti più byte da gestire.

Esempio:

?- f([-1,4,0,4,7,2,3], O).
O = [7, 4, 0, 4, 7, 2, 3]

1

R, 71 byte

a=scan()
l=length(a) 
lapply(1:l,function(x){
  a[x]=max(a[x:l])
  a
})

1

C, 80 byte

i,j;f(l,n)int*l;{for(i=0;i<n;++i)for(j=i;++j<n;)if(l[i]<l[j]){l[i]=l[j];j=i=n;}}

Chiama con:

int main()
{
    int a[5]={3,1,4,-1,2};
    f(a,5);
    for(int k=0;k<5;++k)
        printf("%d ", a[k]);
}

1

Python 2, 89 byte

Provalo online -1 byte grazie a @TemporalWolf
-25 byte grazie a @ValueInk
-7 byte grazie a @Cole

Funzione che muta la matrice di input

def F(A):
 for i in range(len(A)):
    r=[y for y in A[i+1:]if y>A[i]]
    if r:A[i]=r[0];break

Se non fosse necessario fermarsi dopo la prima iterazione, sarebbe un po 'più bello


Questo sembra non funzionare. Provare [1, 3, 5, 7]; ritorna [3, 3, 5, 7].
HyperNeutrino,

1
A[i]<y and=> y>A[i]andsalva 1
TemporalWolf

@HyperNeutrino Se intendo il compito giusto, questo è valido outut
Dead Possum

1
Considera r=[y for y in A[i+1:]if y>A[i]]\n if r:A[i]=r[0];breakdi lasciare il tuo punteggio a 96!
Value Ink

1
Potrei suggerire ciò che ho suggerito per una delle altre risposte di Python: converti ciò che hai in una funzione che muta l'array originale in modo da evitare la stampa e input().
Cole

1

Python 2, 60 byte

f=lambda x:x and[x[:1]+f(x[1:]),[max(x)]+x[1:]][x[0]<max(x)]

Provalo online!

Spiegazione: Verifica ricorsivamente se un determinato elemento è inferiore maxall'elemento nel resto dell'elenco. In tal caso, restituisce l'elenco maxsostituendo il primo elemento.


1

TI-Basic, 72 byte

Prompt L1
If 2≤dim(L1
Then
For(A,1,dim(L1)-1
For(B,A,dim(L1
If L1(A)<L1(B
Then
L1(B→L1(A
Goto E
End
End
End
End
Lbl E
L1

Spiegazione:

Prompt L1          # 4 bytes, input list
If 2≤dim(L1        # 7 bytes, if the list has 2 or 1 element(s), skip this part and return it
Then               # 2 bytes
For(A,1,dim(L1)-1  # 12 bytes, for each element in the list other than the last
For(B,A,dim(L1     # 9 bytes, for each element after that one
If L1(A)<L1(B      # 12 bytes, if the second is larger than the first
Then               # 2 bytes
L1(B→L1(A          # 10 bytes, replace the first with the second
Goto E             # 3 bytes, and exit
End                # 2 bytes
End                # 2 bytes
End                # 2 bytes
End                # 2 bytes
Lbl E              # 3 bytes
L1                 # 2 bytes, implicitly return L1

1

sh, 118 byte

Gli interi di input vengono passati come argomenti allo script.

l=("$@");for i in "$@";{ for j in "$@";{(($i<$j))&&{ l[$x]=$j;echo ${l[@]};exit;};};shift;x=`expr $x+1`;};echo ${l[@]}

Abbattersi:

l=("$@");                      #copy original list
for i in "$@";{ for j in "$@"; #check all elements j that follow element i in list
{(($i<$j))&&{ l[$x]=$j;echo ${l[@]};exit;};};   #if i<j, make i=j; print list, done
shift;                         #makes sure that i is compared only to j that occur after it
x=`expr $x+1`;};               #keeps track of i'th position in the list
echo ${l[@]}                   #prints list if it was unchanged

0

PHP, 88 byte

<?for(;$i+1<$c=count($a=$_GET)&&$a[+$i]>=$a[++$i];);$i>=$c?:$a[$i-1]=$a[$i];print_r($a);

Abbattersi

for(;
$i+1<($c=count($a=$_GET))  # first condition end loop if the item before the last is reach 
&&$a[+$i]>=$a[++$i] # second condition end loop if item is greater then before 
;);
$i>=$c?:$a[$i-1]=$a[$i]; # replace if a greater item is found
print_r($a); #Output

0

Haskell, 48 byte

f(b:l)|l>[],m<-maximum l,b<m=m:l|1<2=b:f l
f x=x

Esempio di utilizzo: f [1,1,2,1]-> [2,1,2,1]. Provalo online! .

Se l'elenco di input ha almeno un elemento, associa bal primo elemento e lal resto dell'elenco. Se lnon è vuoto e binferiore al massimo di l, restituisce il massimo seguito da l, altrimenti restituisce bseguito da una chiamata ricorsiva di f l. Se l'elenco di input è vuoto, restituirlo.


0

Racchetta 202 byte

(let((g(λ(L i n)(for/list((c(in-naturals))(l L))(if(= c i)n l))))(ol'()))
(for((c(in-naturals))(i L))(for((d(in-range c(length L)))#:when(>(list-ref L d)i))
(set! ol(cons(g L c(list-ref L d))ol))))ol)

Ungolfed:

(define (f L)
  (let ((replace (λ (L i n)   ; sub-function to replace i-th item in list L with n;
                   (for/list ((c (in-naturals))
                              (l L))
                     (if (= c i) n l))))
        (ol '()))             ; outlist initially empty; 
    (for ((c (in-naturals))               ; for each item in list
          (i L))
      (for ((d (in-range c (length L)))   ; check each subsequent item in list
            #:when (> (list-ref L d) i))  ; if greater, replace it in list
        (set! ol (cons (replace L c (list-ref L d)) ol)))) ; and add to outlist.
    ol))          ; return outlist.

test:

(f '(3 1 4 -1 2))

Produzione:

'((3 1 4 2 2) (3 2 4 -1 2) (3 4 4 -1 2) (4 1 4 -1 2))

0

C, 67 byte

Single Run, 67 byte Live

j;f(l,i)int*l;{j=i-1;while(i-->0)while(j-->0)l[j]=fmax(l[i],l[j]);}

Passo singolo, 78 byte in diretta

j;f(l,i)int*l;{j=i-1;while(i-->0)while(j-->0)if(l[j]<l[i]){l[j]=l[i];return;}}

Maxima coda, 96 byte in diretta

x;i;j;f(l,n)int*l;{do{x=0;for(i=0;i<n;i++)for(j=0;j<i;j++)if(l[j]<l[i])l[j]=l[i],x=1;}while(x);}

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.