Sequenze impilabili


29

Distribuisci carte etichettate da 0 a 9 da un mazzo una alla volta, formando pile che iniziano da 0 e contano fino a 1.

  • Quando distribuisci uno 0, lo metti sul tavolo per iniziare un nuovo stack.
  • Quando distribuisci qualsiasi altra carta, la metti in cima a una carta che ha esattamente un valore inferiore, coprendola. Se non esiste una carta simile, il mazzo non è impilabile.

Dato un mazzo, determina se può essere impilato quando viene distribuito nell'ordine indicato. Equivalentemente, dato un elenco di cifre, decidere se può essere suddiviso in sottosezioni disconnesse in ciascun modulo0,1,..,k

Esempio

Prendi il mazzo 0012312425. Le prime due carte sono 0, quindi vanno sul tavolo:

Stacks: 00

  Deck: 12312425

Successivamente, trattiamo a 1, che va avanti a 0, non importa quale:

        1
Stacks: 00

  Deck: 2312425

Ci occupiamo quindi della parte 2appena posizionata 1e della parte 3superiore.

        3
        2
        1
Stacks: 00

  Deck: 12425

Successivamente, il 1, 2e posizionato in cima al primo stack e in 4cima al secondo.

        4
        3
        22
        11
Stacks: 00

  Deck: 25

Ora, dobbiamo posizionare un 2, ma non c'è nessuno dei 1due stack. Quindi, questo mazzo non era impilabile.

Input: un elenco non vuoto di cifre 0-9 o una stringa di esse. Non puoi presumere che 0 sarà sempre nell'input.

Output : uno dei due valori coerenti distinti, uno per le sequenze impilabili e uno per quelle non impilabili

Casi test:

impilabile:

0
01
01234
00011122234567890
012031
0120304511627328390

Non impilabile:

1
021
0001111
0012312425
012301210
000112223

Per comodità, come elenchi:

[0]
[0, 1]
[0, 1, 2, 3, 4]
[0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 4, 5, 6, 7, 8, 9, 0]
[0, 1, 2, 0, 3, 1]
[0, 1, 2, 0, 3, 0, 4, 5, 1, 1, 6, 2, 7, 3, 2, 8, 3, 9, 0]

[1]
[0, 2, 1]
[0, 0, 0, 1, 1, 1, 1]
[0, 0, 1, 2, 3, 1, 2, 4, 2, 5]
[0, 1, 2, 3, 0, 1, 2, 1, 0]
[0, 0, 0, 1, 1, 2, 2, 2, 3]

raggruppate:

[[0], [0, 1], [0, 1, 2, 3, 4], [0, 0, 0, 1, 1, 1, 2, 2, 2, 3], [0, 1, 2, 0, 3, 1], [0, 1, 2, 0, 3, 0, 4, 5, 1, 1, 6, 2, 7, 3, 2, 8, 3, 9, 0]]
[[1], [0, 2, 1], [0, 0, 0, 1, 1, 1, 1], [0, 0, 1, 2, 3, 1, 2, 4, 2, 5]]

Classifica:


Possiamo assumere un limite per la lunghezza dell'elenco?
orlp

@orlp Nessun limite esplicito.
xnor

@xnor probabilmente sta chiedendo di giustificare la scrittura int a[99]in C
Leaky Nun,

@LuisMendo Potrei, dico "non vuoto".
xnor

@xnor Ah, scusa, non l'ho visto. L'array può essere basato su 1? Cioè, numeri da 1a10
Luis Mendo,

Risposte:



6

Haskell , 55 byte

Una funzione anonima che prende un elenco di numeri interi e restituisce a Bool.

Uso: (all(<1).foldr(?)[]) [0,1,2,3,4].

all(<1).foldr(?)[]
m?l|(p,r)<-span(/=m+1)l=m:p++drop 1r

Provalo online!

Come funziona

  • foldr(?)[]piega il suo argomento dell'elenco da destra a sinistra usando ?, iniziando con un elenco vuoto. Il risultato è l'elenco di numeri nell'elenco che non rientrava in un numero precedente.
  • all(<1) verifica se gli unici numeri che non corrispondono sopra un numero precedente sono zero.
  • m?lantepone un numero ma un elenco ldi numeri non adatti. Se m+1è già nell'elenco, ora può essere rimosso in quanto si adatta sopra m.
    • (p,r)<-span(/=m+1)ldivide l'elenco lin due parti pe rnella prima istanza del numero m+1. Se non ce ne sono, la parte giusta rsarà vuota.
    • m:p++drop 1rantepone malle parti divise. Se rè vuoto, deve iniziare con m+1, che viene rimosso da drop 1.

Ottima idea facendo l'impilamento al contrario! Ho provato ad espandere la tua in ?modo ricorsivo, ma ho ottenuto la stessa lunghezza .
xnor

54 byte conData.List.delete
H.Piz,

5

Buccia , 9 byte

Λ¬ḞS:o-→ø

Provalo online!

Restituisce 1per mazzi impilabili e 0per mazzi non impilabili.

Sembra che Ørjan Johansen nella sua risposta di Haskell abbia già escogitato lo stesso algoritmo, ma in Husk questo è ovviamente molto più conciso.

Spiegazione

Risolviamo il problema da un'altra parte: capovolgi il mazzo e facciamo pile discendenti. Se dopo aver attraversato tutto il mazzo tutte le pile hanno uno 0 in cima, il mazzo è impilabile.

Λ¬ḞS:(-→)ø
         ø    Starting with the empty list (each element of this list will be the top card
              of a stack)
  ḞS          Traverse the input from right to left. For each card:
      -→        Remove the successor of this card from our list (if present)
    :           Add this card to our list
Λ¬            At the end, check if all the cards in our list are zeroes (falsy)


4

C (gcc), 74 73 byte

f(int*l){int s[10]={},r=1;for(;~*l;s[*l++]++)r*=!*l||s[*l-1]--;return r;}

Richiede l'array di input per contrassegnare la fine con -1. Esempio di utilizzo:

int main(int argc, char** argv) {
    int a[] = {0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 4, 5, 6, 7, 8, 9, 0, -1};
    printf("%d\n",  f(a));
    return 0;
}

Cosa c'è che non va nella pianura return r?
Leaky Nun,

4

Retina , 42 byte

O$#`(.)(?<=(\1.*?)*)
$#2
.
$*1,
^(,|1\1)+$

Provalo online!

Spiegazione

O$#`(.)(?<=(\1.*?)*)
$#2

Questo ordina le cifre, stabilmente, in base alla frequenza con cui la stessa cifra si è verificata in precedenza. In effetti, questo raccoglie insieme le varie sottosequenze candidate. La stringa risultante avrà prima la prima occorrenza di ogni cifra, quindi la seconda occorrenza di ogni cifra e così via. In un input impilabile, il risultato sarà simile a quello in 0123...0123...0123...cui ciascuna di queste sottostringhe può terminare in qualsiasi momento.

È più semplice determinare se l'input ha questo tipo di pattern in unario.

.
$*1,

Sostituiamo ogni cifra n con ns 1 , seguita da una virgola per separare le singole cifre.

^(,|1\1)+$

Finalmente ci avvaliamo di un riferimento diretto per abbinare sequenze di cifre consecutive in aumento. Cerchiamo di abbinare l'intera stringa sia abbinando una singola virgola (che rappresenta uno 0 , che inizia una nuova corsa) o abbinando la cosa precedente preceduta da un'ulteriore 1, che funziona solo se la cifra corrente è il successore di quella precedente.


3

TI-Basic (serie 83), 25 byte (49 caratteri)

:min(seq(min(cumSum(Ans=I)≤cumSum(Ans=I-1)),I,1,9

Come funziona

Accetta input come elenco in Ans. Uscite 1per ingressi impilabili, 0altrimenti.

Per ciascuno I, cumSum(Ans=I)calcola un elenco del numero di volte che si Iè verificato in ciascun segmento iniziale, quindi min(cumSum(Ans=I)≤cumSum(Ans=I-1))è solo 1 se, in ogni posizione, abbiamo visto I-1almeno tante volte quante I. L'espressione generale è 1ogni volta che questo vale per ciascuno I.


3

JavaScript (ES6), 61 45 40 byte

Accetta input come elenco.

a=>a.every(k=>a[~k]=!k|a[-k]--&&-~a[~k])

Casi test

Come?

Per ogni valore 0 ... 9 , teniamo traccia del numero di pile disponibili con la carta precedente in cima. Questi contatori sono memorizzati tra [-9] e [0] , dove a [] è l'array di input originale. L'unico contatore che si scontra con i dati di input è uno [0] , ma questo non ci interessa davvero perché 1) le carte etichettate con 0 sono sempre consentite e devono essere comunque elaborate separatamente e 2) il valore di input a [0 ] viene elaborato prima che abbia la possibilità di essere aggiornato.

a => a.every(k =>  // given the input array a, for each card k in a:
  a[~k] =          // the card is valid if:
    !k |           //   - it's a 0 or
    a[-k]-- &&     //   - there's at least one stack with the card k-1 atop
    -~a[~k]        // in which case we allow a new card k+1 and go on with the next card
)                  // otherwise, every() fails immediately

Sei più veloce di me: o
Leaky Nun,

@LeakyNun Devi essere stato via per 20 minuti ...;)
Arnauld

2

MATL , 16 byte

0*GQ"@yQy=f1)(]a

L'input è una matrice di numeri.

Il codice 1viene emesso in STDOUT se l'input è impilabile o esce con un errore e svuota l'output in STDOUT se l'input non è impilabile.

Provalo online!


2

Retina , 110 byte

+`0((.*?)1((.*?)2((.*?)3((.*?)4((.*?)5((.*?)6((.*?)7((.*?)8((.*?)9)?)?)?)?)?)?)?)?)?
$2$4$6$8$10$12$14$16$+
^$

Provalo online! Il link include casi di test. Non riesco spesso ad usare $16...


2

Mathematica, 80 byte

Catch[Fold[#~Join~{-1}/.{{p___,#2-1,q___}:>{p,#2,q},-1:>Throw[1<0]}&,{},#];1>0]&


2

R , 88 byte

function(d){s={}
for(e in d)if(!e)s=c(s,0)else{k=match(e,s+1)
if(is.na(k))T=F
s[k]=e}
T}

Provalo online!

Funzione che accetta un vettore R; ritorna TRUEper impilabile e FALSEper impilabile.

Spiegazione:

function(d){
 s <- {}              # initialize the stacks as empty
 for(e in d){         # iterate over the deck
  if(!e)              # if e is zero
   s <- c(s,0)        # start a new stack
  else {              # otherwise
   k <- match(e,s+1)  # find where e should go in s, NA if not there
   if(is.na(k))       # if no match (unstackable)
    T <- F            # set T to F (False)
   s[k] <- e          # set s[k] to e
  }
 T                    # return the value of T, which is TRUE by default and only gets changed in the loop to F.
}

2

Nim, 133 byte

proc s(d:seq[int]):int=
 var
  t= @[0]
  r=1
 for c in d:(t.add(0);var f=0;for i,s in t.pairs:(if s==c:(t[i]=c+1;f=1;break));r*=f)
 r

1se funziona; 0se non lo fa.

Ho dovuto fare qualche affare funky per gestire la mutabilità delle variabili nei for-loop, vabbè.


1

Haskell , 77 75 byte

import Data.List
g[]=1<3
g(x:r)|s<-r\\[x-1]=g r&&(x<1||s/=r&&g s)
g.reverse

Provalo online! Uso: g.reverse $ [0,1,2]. Restituisce Trueper input impilabili e Falsealtrimenti.

Questa è una soluzione ricorsiva che attraversa un determinato elenco da dietro a davanti. Implementa l'osservazione che

  • l'elenco vuoto è impilabile.
  • una lista non vuota con il prefisso re l'ultimo elemento xè impilabile se rè impilabile eo xè zero o entrambi x-1appare in re rcon x-1asportato è anche impilabile.

1

Java 8, 168 150 142 byte

a->{int x[]=new int[a.length],s=0,i;a:for(int n:a){if(n<1){s++;continue;}for(i=0;i<s;i++)if(x[i]==n-1){x[i]=n;continue a;}return 0;}return 1;}

ritorna 0 / 1se è impilabile correttamente o meno.

Spiegazione:

Provalo qui.

a->{                         // Method with integer-array parameter and integer return-type
  int x[]=new int[a.length], //  Array for the stacks, (max) size equal to input-size
      s=0,                   //  Amount of stacks, starting at 0
      i;                     //  Index integer
  a:for(int n:a){            //  Loop (1) over the input
    if(n<1){                 //   If the current item is a zero:
      s++;                   //    Increase amount of stacks `s` by 1
      continue;}             //    And go to the next iteration
    for(i=0;i<s;i++)         //   Inner loop (2) over the stacks
      if(x[i]==n-1){         //    If a top item of a stack equals the current item - 1:
        x[i]=n;              //     Set this item in the stacks-array
        continue a;}         //     And go to the next iteration of loop (1)
    return 0;                //   If we haven't encountered a `continue`, return 0
  }                          //  End of loop (1)
  return 1;                  //  Return 1 if we were able to correctly stack everything
}                            // End of method

1

C, 248 byte

Nota: per stampare lo stato di ritorno, digitare "echo $ status" nel terminale

Stato di ritorno 0: non impilabile

Stato di ritorno 1: impilabile

Spiegazione: Incrementa l'elemento dell'array con l'indice equivalente alla cifra più corrente nello stack. Quindi, il programma controlla se questo elemento dell'array appena incrementato è più grande dell'elemento che lo precede. In tal caso, restituisce 0. Altrimenti se il programma arriva alla fine dell'array restituisce 1.

 main(int argc, char ** argv)
{
    static int stack[10];

    while ( *++argv != 0x0 )
    {
        stack[**argv - 0x30]++;

        if ( **argv - 0x30 > 0 )
        {
            if ( stack[**argv - 0x30] > stack[**argv - 0x30 - 1] )
            {
                return 0;
            }

        }

    }   

    return 1;
}

3
Benvenuti in Code Golf! Il tuo codice e il tuo byte devono corrispondere, quindi assicurati di fornire una versione completamente giocata del tuo codice. La versione non golfata è quella opzionale.
Stephen,

0

Gelatina , 15 byte

œp@ŒQẎµ0rṀ⁼Qµ¿Ẹ

Un collegamento monadico che prende un elenco di numeri interi non negativi e restituisce 0se impilabile o 1se non impilabile.

Provalo online!

Come?

œp@ŒQẎµ0rṀ⁼Qµ¿Ẹ - Link: list
             ¿  - while loop:
      µ     µ   - ...condition chain:
       0        -      literal zero
         Ṁ      -      maximum of current list
        r       -      inclusive range = [0,1,2,...,max(list)]
           Q    -      de-duplicate list (unique values in order of appearance)
          ⁼     -      equal?
                - ...do:
   ŒQ           -      distinct sieve (1s at first occurrences 0s elsewhere)
  @             -      use swapped arguments:
œp              -        partition (the list) at truthy values (of the distinct sieve)
     Ẏ          -      tighten (makes the list flat again ready for the next loop)
              Ẹ - any truthy? 1 if the resulting list has any non-zero integers remaining
                -           - effectively isNotEmpty for our purposes since a list of only
                -             zeros gets reduced to an empty list via the loop.

La tua mossa: P: P
Leaky Nun

Heh, beh, dubito che avrei battuto l'11 (o il 10 ?!) e che dovessi dormire: D
Jonathan Allan,

0

Japt , 16 byte

£=k_¥T©°T}T=0ÃUd

Provalo online! Uscite falseper impilabile, trueper non impilabile.

Spiegazione

 £   = k_  ¥ T© ° T}T=0Ã Ud
UmX{U=UkZ{Z==T&&++T}T=0} Ud    Ungolfed
                               Implicit: U = input array
UmX{                   }       For each item X in the array:
                    T=0          Set T to 0.
      UkZ{         }             Remove the items Z where
          Z==T&&++T              Z == T (and if so, increment T).
                                 This has the effect of removing the largest stack.
    U=                           Reset U to the result.
                               This process is repeated U.length times, which is
                               evidently enough to handle any U.
                         Ud    Return whether there are any truthy items in U.
                               Any items not part of a stack are non-zero/truthy,
                               so this works for every possible case.

0

05AB1E , 25 byte

ηε[DõQ#ZƒDNåiNõ.;Dëˆ#]¯OĀ

La sfida non sembra poi così difficile, ma è abbastanza difficile in 05AB1E (almeno per me ..)

Output 0se impilabili e 1se non impilabili.

Provalo online o verifica tutti i casi di test .

Spiegazione:

η             # Prefixes of the (implicit) input
              #  i.e. '012031' → ['0','01','012','0120','01203','012031']
              #  i.e. `021` → ['0','02','021']
 ε            # Map each to:
  [           # Start an infinite inner loop
   D          # Duplicate the current value
    õQ#       # If it's an empty String, stop the infinite loop
   Z          # Get the maximum (without popping)
              #  i.e. '01203' → 3
              #  i.e. '02' → 2
    ƒ         # Inner loop `N` in the range [0,max]
     D        # Duplicate the current value
      Nåi     # If it contains the current digit `N`
              #  i.e. '01203' and 1 → 1 (truthy)
              #  i.e. '02' and 1 → 0 (falsey)
         Nõ.; # Remove the first one (by replacing the first `N` with an empty string)
              #  i.e. '1203' and 1 → '203'
         D    # And duplicate it again for the next iteration of the inner loop
      ë       # Else (does not contain the digit `N`):
       ˆ      # Push `N` to the global stack
        #     # And break the infinite loop
 ]            # Close the if-else, inner loop, infinite loop, and mapping (short for `}}}}`)
  ¯           # Push the global stack
   O          # Take the sum
              #  i.e. [] → 0
              #  i.e. ['2'] → 2
    Ā         # And get the trutified value of that (which we implicitly output as result)
              #  i.e. 0 → 0
              #  i.e. 2 → 1

0

Java 8, 87 byte

Invece di costruire gli stack, ho solo calcolato se un elemento non è impilabile sugli elementi precedenti e restituisco 0 quando si incontra un elemento non impilabile. Se raggiungo la fine, l'intera stringa è impilabile e viene restituito 1:

s->{int l[]=new int[10];for(int n:s)if(n!=0&&l[n]>=l[n-1]||l[n]++<0)return 0;return 1;}

Provalo online!

Spiegazione:

s->{
  int l[]=new int[10];                # initialise the counts of each digit encountered prefix of element, all initialised to 0
  for(int n:s)                        # Iterate over all entries in input
    if(n!=0&&l[n]>=l[n-1]||++l[n]<0)  # Check if the element is stackable on the previous elements. Last check is always evaluated and false, but the sideeffect is to add the element to the handled, prefixed element og the next element.  
      return 0;                       # Unstackable
  return 1;                           # No unstackable elements, so the result is stackable
}
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.