Compilare una sequenza crescente con il maggior numero possibile di numeri


29

Un elenco di numeri è chiamato monotonicamente crescente (o non decrescente) se ogni elemento è maggiore o uguale all'elemento precedente.

Ad esempio, 1, 1, 2, 4, 5, 5, 5, 8, 10, 11, 14, 14sta aumentando monotonicamente.

Dato un elenco monotonicamente crescente di numeri interi positivi che ha un numero arbitrario di punti vuoti indicato da ?, riempire i punti vuoti con numeri interi positivi in ​​modo tale che il numero intero di numeri interi possibili sia presente nell'elenco, ma rimane monotonicamente crescente.

Ci possono essere diversi modi per ottenere questo risultato. Qualsiasi è valido.

Emette l'elenco risultante.

Ad esempio , se l'ingresso è

?, 1, ?, 1, 2, ?, 4, 5, 5, 5, ?, ?, ?, ?, 8, 10, 11, ?, 14, 14, ?, ?

è garantito che senza i punti vuoti l'elenco sarà monotonicamente crescente

1, 1, 2, 4, 5, 5, 5, 8, 10, 11, 14, 14

e il tuo compito è quello di assegnare numeri interi positivi a ciascuno di essi ?per massimizzare il numero di numeri interi distinti nell'elenco mantenendo al contempo non in diminuzione.

Un compito non valido è

1, 1, 1, 1, 2, 3, 4, 5, 5, 5, 5, 5, 5, 5, 8, 10, 11, 14, 14, 14, 14, 14

perché, mentre non diminuisce, ha solo un intero univoco in più rispetto all'input, vale a dire 3.

In questo esempio è possibile inserire sei numeri interi positivi unici e mantenere la lista non in diminuzione.
Un paio di modi possibili sono:

1, 1, 1, 1, 2, 3, 4, 5, 5, 5, 6, 7, 8, 8, 8, 10, 11, 12, 14, 14, 15, 16

1, 1, 1, 1, 2, 3, 4, 5, 5, 5, 5, 6, 6, 7, 8, 10, 11, 13, 14, 14, 20, 200

Uno di questi (e molti altri) sarebbe un output valido.

Tutti i punti vuoti devono essere riempiti.

Non esiste un limite superiore per gli interi che possono essere inseriti. Va bene se numeri molto grandi sono stampati in notazione scientifica.

Lo zero non è un numero intero positivo e non deve mai essere inserito.

Al posto di ?si può utilizzare qualsiasi valore costante che non è un numero intero positivo, come ad esempio 0, -1, null, False, o "".

Vince il codice più breve in byte.

Altri esempi

[input]
[one possible output] (a "*" means it is the only possible output)

2, 4, 10
2, 4, 10 *

1, ?, 3
1, 2, 3 *

1, ?, 4
1, 2, 4

{empty list}
{empty list} *

8
8 *

?
42

?, ?, ?
271, 828, 1729

?, 1
1, 1 *

?, 2
1, 2 *

?, 3
1, 3

45, ?
45, 314159265359

1, ?, ?, ?, 1
1, 1, 1, 1, 1 *

3, ?, ?, ?, ?, 30
3, 7, 10, 23, 29, 30 

1, ?, 2, ?, 3, ?, 4
1, 1, 2, 3, 3, 3, 4

1, ?, 3, ?, 5, ?, 7
1, 2, 3, 4, 5, 6, 7 *

1, ?, 3, ?, 5, ?, ?, 7
1, 2, 3, 4, 5, 6, 7, 7

1, ?, ?, ?, ?, 2, ?, ?, ?, ?, 4, ?, 4, ?, ?, 6
1, 1, 1, 1, 1, 2, 3, 4, 4, 4, 4, 4, 4, 5, 6, 6

98, ?, ?, ?, 102, ?, 104
98, 99, 100, 101, 102, 103, 104 *

Probabilmente un modo migliore per esprimere il problema che ha un input rigoroso, una coppia di output per la verifica, sarebbe "Qual è il numero più alto possibile di numeri distinti nella sequenza". In questo modo tutte le risposte produrranno lo stesso numero e semplificheranno molto la valutazione dei casi di test
Cruncher

@StewieGriffin Puoi assumere che i valori e la lunghezza dell'elenco siano al di sotto dei massimi int come al solito. Intendevo solo che va bene inserire interi molto grandi alla fine se è così che funziona il tuo algoritmo.
Calvin's Hobbies

Risposte:


11

Haskell , 41 byte

fprende un elenco e restituisce un elenco, con 0 che rappresenta ?s.

f=scanr1 min.tail.scanl(#)0
m#0=m+1
_#n=n

Fondamentalmente, prima scansione elenco da sinistra, sostituendo 0s con uno in più rispetto all'elemento precedente (o 0 all'inizio); quindi scansiona da destra riducendo gli elementi troppo grandi per eguagliare quello alla loro destra.

Provalo online! (con wrapper per convertire ?s.)


4

Mathematica, 84 byte

Rest[{0,##}&@@#//.{a___,b_,,c___}:>{a,b,b+1,c}//.{a___,b_,c_,d___}/;b>c:>{a,c,c,d}]&

Funzione pura che prende un elenco come argomento, in cui i punti vuoti sono indicati da Null(come in {1, Null, Null, 2, Null}) o eliminati del tutto (come in {1, , , 2, }) e restituendo un elenco adatto (in questo caso {1, 2, 2, 2, 3}).

Risulta che sto usando lo stesso algoritmo della risposta Haskell di Ørjan Johansen : prima sostituisci ciascuno Nullcon uno in più del numero a sinistra ( //.{a___,b_,,c___}:>{a,b,b+1,c}), quindi sostituisci qualsiasi numero troppo grande con il numero a destra ( //.{a___,b_,c_,d___}/;b>c:>{a,c,c,d}). Per far fronte ai possibili Nulls all'inizio dell'elenco, iniziamo anteponendo a 0( {0,##}&@@#), facendo l'algoritmo, quindi eliminando l'iniziale 0( Rest).

Sì, ho scelto Nullinvece Xo qualcosa del genere per salvare letteralmente un byte nel codice (quello che sarebbe altrimenti tra le virgole di b_,,c___).


Hm, anteponendo 1 dici? Ho usato uno 0, a causa di cose come ?, 2. Ho il sospetto che poi produresti 2, 2invece del corretto 1, 2.
Ørjan Johansen,

Punto eccellente! Fortunatamente la correzione è facile.
Greg Martin,

3

C 160

Questo non vincerà mai ma:

#define p(x)printf("%d ",x);
i=1,l=0,m=0,n;main(c,v)char**v;{for(;i<c;i++)if(*v[i]==63)m++;else{for(n=atoi(v[i]);m>0;m--)p(l<n?++l:n)p(l=n)}for(;m>0;m--)p(++l)}

Prende l'elenco dagli argomenti della riga di comando.



3

05AB1E , 31 23 13 byte

Risparmiato 10 byte grazie a Grimy

ε®X:D>U].sR€ß

Provalo online!

Spiegazione

ε      ]       # apply to each number in input
 ®X:           # replace -1 with X (initially 1)
    D>U        # store current_number+1 in X
        .s     # get a list of suffixes
          R    # reverse
           ۧ  # take the minimum of each

Perché questo stampa solo una parte dell'output? Nell'esempio TIO manca il primo 1.
Fatalizza il

So che è passato un po 'di tempo, e probabilmente può essere giocato a golf ancora un po', ma -3 byte con alcuni golf facili: Entrambi }}possono essere ]per salvare 2 byte; e õ-)Rpuò essere )˜Rper salvare un byte aggiuntivo.
Kevin Cruijssen,

2
@KevinCruijssen: In effetti potrebbe :)
Emigna il

1
Può ancora! 16 , 15 , 13 .
Grimmy,

@Grimy: Wow, grazie! Quel trucco del suffisso era davvero intelligente!
Emigna

2

Pip , 25 23 21 byte

Y{Y+a|y+1}MgW PMNyPOy

Accetta input come più argomenti della riga di comando separati da spazi. Stampa l'elenco dei risultati un numero per riga. Provalo online! (Ho confuso le molteplici argomentazioni della riga di comando perché sarebbe un problema aggiungere 25 argomenti su TIO, ma funziona anche come pubblicizzato.)

Spiegazione

Procediamo in due passaggi. Innanzitutto, sostituiamo ogni ?sequenza di s nell'input con una sequenza che inizia dal numero precedente nell'elenco e aumenta di uno ogni volta:

? 1 ? 1 2 ? 4 5 5 5 ? ? ? ? 8 10 11 ?  14 14 ?  ?
1 1 2 1 2 3 4 5 5 5 6 7 8 9 8 10 11 12 14 14 15 16

Quindi ripetiamo il ciclo; per ogni numero, ne stampiamo il minimo e tutti i numeri alla sua destra. Questo porta i numeri troppo alti verso il basso per mantenere la monotonicità.

                      y is initially "", which is 0 in numeric contexts
                      Stage 1:
 {       }Mg           Map this function to list of cmdline args g:
   +a                  Convert item to number: 0 (falsey) if ?, else nonzero (truthy)
     |                 Logical OR
      y+1              Previous number +1
  Y                    Yank that value into y (it is also returned for the map operation)
Y                      After the map operation, yank the whole result list into y
                      Stage 2:
            W          While loop, with the condition:
               MNy      min(y)
              P         printed (when y is empty, MN returns nil, which produces no output)
                  POy  Inside the loop, pop the leftmost item from y

2

Python 2 con NumPy, 163 byte

8 byte salvati grazie a @wythagoras

Gli zeri utilizzati per contrassegnare i punti vuoti

import numpy
l=[1]+input()
z=numpy.nonzero(l)[0]
def f(a,b):
 while b-a-1:a+=1;l[a]=l[a-1]+1;l[a]=min(l[a],l[b])
i=1
while len(z)-i:f(z[i-1],z[i]);i+=1
print l[1:]

Più leggibile con i commenti:

import numpy
l=[1]+input()           # add 1 to the begining of list to handle leading zeros
z=numpy.nonzero(l)[0]   # get indices of all non-zero values
def f(a,b):             # function to fill gap, between indices a and b
    while b-a-1:
        a+=1
        l[a]=l[a-1]+1   # set each element value 1 larger than previous element
        l[a]=min(l[a],l[b])   # caps it by value at index b
i=1
while len(z)-i:       
    f(z[i-1],z[i])      # call function for every gap
    i+=1
print l[1:]             # print result, excluding first element, added at the begining

1
Alcuni miglioramenti: if l[a]>l[b]:l[a]=l[b]può essere l[a]=min(l[a],l[b])e quindi può essere in linea prima di quello. Inoltre, ciò significa che l'intera riga può essere inserita dopo il while. E penso l=input()e l=[1]+lposso essere l=[1]+input()(Inoltre, in generale: se usi due livelli di rientro, puoi usare uno spazio e una scheda invece di uno spazio e due spazi in Python 2 (vedi codegolf.stackexchange.com/a/58 ) )
wythagoras,

1
Inoltre, accanto all'ultima riga può essere while len(z)-i:f(z[i-1],z[i]);i+=1quando si inizia con i = 1.
wythagoras,

@wythagoras Grazie, buoni consigli. Ho aggiunto questo al codice
Dead Possum del

Bello, ma è solo 163 byte.
wythagoras,

@wythagoras Oh, ho dimenticato di aggiornare il conteggio dei byte
Dead Possum

1

PHP, 95 77 71 69 68 byte

for($p=1;$n=$argv[++$i];)echo$p=$n>0?$n:++$p-in_array($p,$argv)," ";

accetta input dagli argomenti della riga di comando, stampa un elenco separato da spazi. Corri con -nr.

abbattersi

for($p=1;$n=$argv[++$i];)   # loop through arguments
    echo$p=                     # print and copy to $p:
    $n>0                            # if positive number
        ?$n                             # then argument
        :++$p                           # else $p+1 ...
            -in_array($p,$argv)         # ... -1 if $p+1 is in input values
    ," ";                       # print space

$nè vero per qualsiasi stringa tranne la stringa vuota e "0".
$n>0è vero per numeri positivi - e stringhe che li contengono.


1

Perl 6 , 97 byte

{my $p;~S:g/(\d+' ')?<(('?')+%%' ')>(\d*)/{flat(+($0||$p)^..(+$2||*),(+$2 xx*,($p=$2)))[^+@1]} /}

L'input è un elenco di valori o una stringa separata da spazio, dove ?viene utilizzata per sostituire i valori da sostituire.

L'output è una stringa separata da spazio con uno spazio finale.

Provalo

Allargato:

{                       # bare block lambda with implicit parameter 「$_」

    my $p;              # holds the previous value of 「$2」 in cases where
                        # a number is sandwiched between two replacements

    ~                   # stringify (may not be necessary)
    S                   # replace
    :global
    /
        ( \d+ ' ' )?    # a number followed by a space optionally ($0)

        <(              # start of replacement

          ( '?' )+      # a list of question marks
          %%            # separated by (with optional trailing)
          ' '           # a space

        )>              # end of replacement

        (\d*)           # an optional number ($2)

    /{                  # replace with the result of:

        flat(

          +( $0 || $p ) # previous value or 0
          ^..           # a range that excludes the first value
          ( +$2 || * ), # the next value, or a Whatever star

          (
            +$2 xx *,   # the next value repeated endlessly

            ( $p = $2 ) # store the next value in 「$p」
          )

        )[ ^ +@1 ]      # get as many values as there are replacement chars
    } /                 # add a space afterwards
}

Non conosco Perl 6, ma in Perl 5 puoi usare $"invece di ' 'radere un byte. Funziona qui?
msh210

@ msh210 Quasi tutte queste variabili sono sparite o hanno nomi più lunghi. Circa l'unico che esiste ancora e ha lo stesso scopo è $!. ( $/esiste ma viene utilizzato per $1$/[1]e $<a>$/{ qw< a > })
Brad Gilbert b2gills

1

JavaScript (ES6), 65 byte

a=>a.map(e=>a=e||-~a).reduceRight((r,l)=>[r[0]<l?r[0]:l,...r],[])

Perché volevo usare reduceRight. Spiegazione: mapSostituisce ogni valore di falsa con uno in più rispetto al valore precedente, quindi reduceRighttorna alla fine assicurandosi che nessun valore superi il seguente valore.


1

Q, 63 byte

{1_(|){if[y>min x;y-:1];x,y}/[(|){if[y=0;y:1+-1#x];x,y}/[0,x]]}

Sostanzialmente lo stesso algoritmo della risposta Haskell di Ørjan Johansen .

  • Assume? = 0.
  • Inserisce uno 0 all'inizio dell'array in caso di? all'inizio.
  • Esegue la scansione dell'array sostituendo 0 con 1 + elemento precedente.
  • Inverte l'array e scansiona di nuovo, sostituendo gli elementi maggiori dell'elemento precedente con l'elemento precedente.
  • Inverte e taglia il primo elemento (lo 0 aggiunto dall'inizio).

L'uso di min vs last è stato usato per salvare un byte, poiché si può presumere che l'ultimo elemento sarà l'elemento min dato il tipo di array decrescente.


Bella risposta, benvenuta nel sito! :)
DJMcMayhem

1

TI-Basic (TI-84 Plus CE), 81 byte

not(L1(1))+L1(1→L1(1
For(X,2,dim(L1
If not(L1(X
1+L1(X-1→L1(X
End
For(X,dim(L1)-1,1,-1
If L1(X)>L1(X+1
L1(X+1→L1(X
End
L1

Un semplice porto della risposta Haskell di Ørjan Johansen a TI-Basic. Usa 0 come valore nullo. Riceve input da L 1 .

Spiegazione:

not(L1(1))+L1(1→L1(1 # if it starts with 0, change it to a 1
For(X,2,dim(L1     # starting at element 2:
If not(L1(X              # if the element is zero
1+L1(X-1→L1(X            # change the element to one plus the previous element
End
For(X,dim(L1)-1,1,-1 # starting at the second-last element and working backwards
If L1(X)>L1(X+1           # if the element is greater than the next
L1(X+1→L1(X               # set it equal to the next
End
L1                   # implicitly return

1

Java 8, 199 164 byte

a->{for(int l=a.length,n,j,x,i=0;i<l;)if(a[i++]<1){for(n=j=i;j<l;j++)if(a[j]>0){n=j;j=l;}for(j=i-3;++j<n-1;)if(j<l)a[j+1]=j<0?1:a[j]+(l==n||a[n]>a[j]|a[n]<1?1:0);}}

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

Provalo online.

Spiegazione:

a->{                      // Method with integer-array parameter and no return-type
  for(int l=a.length,     //  Length of the input-array
      n,j,x,              //  Temp integers
      i=0;i<l;)           //  Loop `i` over the input-array, in the range [0, length):
    if(a[i++]<1){         //   If the `i`'th number of the array is 0:
                          //   (And increase `i` to the next cell with `i++`)
      for(n=j=i;          //    Set both `n` and `j` to (the new) `i`
          j<l;j++)        //    Loop `j` in the range [`i`, length):
        if(a[j]>0){       //     If the `j`'th number of the array is not 0:
          n=j;            //      Set `n` to `j`
          j=l;}           //      And set `j` to the length to stop the loop
                          //    (`n` is now set to the index of the first non-0 number 
                          //     after the `i-1`'th number 0)
      for(j=i-3;++j<n-1;) //    Loop `j` in the range (`i`-3, `n-1`):
        if(j<l)           //     If `j` is still within bounds (smaller than the length)
          a[j+1]=         //      Set the `j+1`'th position to:
            j<0?          //       If `j` is a 'position' before the first number
             1            //        Set the first cell of the array to 1
            :             //       Else:
             a[j]+        //        Set it to the `j`'th number, plus:
              (l==n       //        If `n` is out of bounds bounds (length or larger)
               ||a[n]>a[j]//        Or the `n`'th number is larger than the `j`'th number
               |a[n]<1?   //        Or the `n`'th number is a 0
                1         //         Add 1
               :          //        Else:
                0);}}     //         Leave it unchanged by adding 0

0

Python 2 , 144 124 119 byte

l=input()
for n in range(len(l)):a=max(l[:n]+[0]);b=filter(abs,l[n:]);b=len(b)and b[0]or-~a;l[n]=l[n]or a+(b>a)
print l

Provalo online!


Utilizza 0invece di?


Non è b=filter(abs,l[n:])uguale a b=l[n:] ?
Dead Possum,

@DeadPossum filter (abs ... filtra tutti gli 0
ovs

Oh, questo rimuove gli zeri, lo capisco
Dead Possum,

0

JavaScript (ES6), 59

Una funzione con un array intero come input. I punti vuoti sono contrassegnati con0

a=>a.map((v,i)=>v?w=v:(a.slice(i).find(x=>x)<=w?w:++w),w=0)

Test

var F=
a=>a.map((v,i)=>v?w=v:(a.slice(i).find(x=>x)<=w?w:++w),w=0)

;[[2, 4, 10]
,[1, 0, 3]
,[1, 0, 4]
,[]
,[8]
,[0]
,[0, 0, 0]
,[0, 1]
,[0, 2]
,[0, 3]
,[45, 0]
,[1, 0, 0, 0, 1]
,[3, 0, 0, 0, 0, 30]
,[1, 0, 2, 0, 3, 0, 4]
,[1, 0, 3, 0, 5, 0, 7]
,[1, 0, 3, 0, 5, 0, 0, 7]
,[1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 4, 0, 4, 0, 0, 6]
,[98, 0, 0, 0, 102, 0, 104]]
.forEach(a=>{
  console.log(a+'\n'+F(a))
})


0

C # (.NET Core) , 182 byte

Utilizzando la stessa strategia di Ørjan Johansen.

Utilizza 0 nell'elenco di input per contrassegnare la var sconosciuta.

l=>{if(l[0]<1)l[0]=1;int j;for(j=0;j<l.Length;j++)l[j]=l[j]==0?l[j-1]+1:l[j];for(j=l.Length-2;j>=0;j--)l[j]=l[j]>l[j+1]?l[j+1]:l[j];foreach(var m in l) System.Console.Write(m+" ");};

Provalo online!


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.