Quando numeri interi si uniscono alla coda


26

introduzione

Una coda è un tipo di dati astratto in cui gli elementi vengono aggiunti alla parte anteriore (accodamento) e rimossi dalla parte posteriore ( accodamento ). Questo è anche noto come principio FIFO (First In First Out) .

È meglio mostrato con un esempio:

inserisci qui la descrizione dell'immagine


Sfida

Dato un array non vuoto che contiene numeri interi positivi ed elementi che indicano un dequeue (rimuovendo un elemento), genera l'elenco finale della coda.

Diciamo che Xdenota un dequeue in questo esempio. Diamo un'occhiata al seguente elenco:

[45, X, X, 37, 20, X, 97, X, 85]

Questo può essere tradotto nel seguente pseudo codice di coda:

                   Queue
Enqueue 45    ->   45
Dequeue       ->   
Dequeue       ->              (dequeue on an empty queue is a no-op)
Enqueue 37    ->   37
Enqueue 20    ->   20 37
Dequeue       ->   20
Enqueue 97    ->   97 20
Dequeue       ->   97
Enqueue 85    ->   85 97

Si può vedere che alla fine, il risultato è [85, 97], che è l'output per questa sequenza.


Casi test

Nota che puoi scegliere qualsiasi altro simbolo o carattere per X, purché non sia un numero intero positivo.

[1, X, 2, X, 3, X]      ->     []
[1, 2, X]               ->     [2]
[1, 2, 3]               ->     [3, 2, 1]
[1, 2, X, X, X, 3]      ->     [3]
[1, 2, X, 3, X, 4]      ->     [4, 3]

Questo è , quindi vince l'invio con il minor numero di byte!


Può essere una stringa separata da spazio anziché un array?
Riley

@Riley Certo, qualunque cosa funzioni meglio per te
Adnan,

2
Possiamo usare un numero negativo per x (Haskell non supporta elenchi eterogenei)
Nome visualizzato generico

2
... o altri numeri interi non negativi come zero o mezzo?
Jonathan Allan,

@GenericDisplayName Hmm, buon punto. Lo permetterò finché non sarà un numero intero positivo
Adnan,

Risposte:


4

Gelatina , 8 byte

F;@Ṗṛ?¥/

Utilizza qualsiasi valore di falsy ( 0 o vuoto iterable) per dequeue.

Provalo online!

Come funziona

F;@Ṗṛ?¥/  Main link. Argument: A (array)

       /  Reduce A by the link to the left.
      ¥     Combine the two links to the left into a dyadic chain.
F             Flatten the left argument.
    ṛ?        If the right argument is truthy:
 ;@             Concatenate the right argument and the flattened left argument.
              Else:
   Ṗ            Pop; remove the last element of the flattened left argument.
                This is why flattening is required, as Ṗ doesn't handle integers
                as intended for this challenge.

1
In realtà non è proibito. Sono vietati solo numeri interi positivi , 0 è neutro.
Erik the Outgolfer

Non è quello che ha detto quando ho pubblicato la mia risposta, ma grazie per il testa a testa.
Dennis


7

Mathematica, 102 byte

Sicuramente non è la soluzione più breve, ma non ho potuto resistere perché è un po 'perverso.

r=Reverse@{##}&
a_~f~b___:=b
f[a_,b___,]:=b
ToExpression[{"r[","f["~Table~StringCount[#,"]"],#}<>"]"]&

Dopo alcune funzioni di aiuto, questo definisce una funzione pura che accetta una stringa come input: nella stringa, i numeri sono separati da virgole (lo spazio bianco è opzionale); il personaggio dequeue è "]"; e l'elenco non ha delimitatori davanti o dietro. Ad esempio, il primo esempio nell'OP verrebbe inserito come stringa "45,],],37,20,],97,],85". L'output della funzione è un elenco di numeri.

La funzione conta il numero di dequeues "]"nella stringa di input, aggiunge molte copie "f["all'inizio della stringa e quindi circonda il tutto "r[...]". Nell'esempio sopra, questo produce "r[f[f[f[f[45,],],37,20,],97,],85]"; notare che le parentesi sono bilanciate.

Quindi, ToExpressioninterpreta la stringa risultante come un pezzo di codice Mathematica e la esegue. La funzione fè convenientemente definita per conservare tutti i suoi argomenti tranne il primo (e ignora anche le virgole finali; ciò è necessario per gestire comunque il dequeueing di code vuote) e rconverte la sequenza risultante di numeri in un elenco di numeri nel giusto ordine.


La virgola nella riga 3 è b___,destinata a essere lì? E funziona , ma i giri virgola rosso a causa di esso. (inoltre, qual è la differenza tra le righe 2 e 3?)
numbermaniac

1
Buon occhio :) La linea 2 è equivalente a f[a_,b___]:=b(senza la virgola), mentre la linea 3 è equivalente a f[a_,b___,Null]:=b. In entrambi i casi, si b___riferisce a un numero qualsiasi di argomenti (incluso nessuno). La riga 3 è più specifica, quindi viene sempre utilizzata prima della riga 2 quando appropriato. Quindi la funzione fignora il suo primo argomento e ignora anche il suo ultimo argomento se tale argomento è Null. Ciò era necessario per gestire il dequeueing di una coda vuota. Si noti che un input tipico produrrà un'espressione simile r[f[f[f[5,3,],2,],],11], dove ogni virgola prima ]indica di nuovo a Null.
Greg Martin,

1
Wow molto bello :). A proposito, penso che in realtà siano 102 byte; potresti aver contato un carattere di nuova riga in più alla fine.
numbermaniac

4

Retina , 30 byte

1+`\d+,(.*?)X,?|^X,
$1
O^$`\d+

Provalo online!

Rimuove ripetutamente il primo numero che (non necessariamente immediatamente) seguito da un Xinsieme a quello X, o un Xall'inizio della stringa. Quindi inverte i numeri rimanenti.


4

JavaScript, 70 63 53 50 43 byte

Grazie @Neil per aver giocato a golf di 10 byte con x.map anziché per l'espressione loop e ternaria

Grazie @Arnauld per giocare a golf con 3 byte

Grazie @ETHproductions per giocare a golf da 7 byte

x=>(t=[],x.map(a=>+a?t=[a,...t]:t.pop()),t)

Provalo online!

Dequeue può essere qualsiasi valore non numerico diverso da true.


Questo sarebbe più breve se si utilizzava un ternario anziché if un'istruzione, e più breve se si utilizzava mapinvece di un ciclo, e ancora più breve se si utilizzava un'espressione anziché un blocco. Vedi i suggerimenti .
Neil

Avevo pubblicato la prima versione che ho funzionato. Poi ho cenato: P
fəˈnɛtɪk

Puoi fare x=>(t=[],x.map(a=>a>0?t.unshift(a):t.pop()),t)per salvare parecchi byte sureturn
ETHproductions

x=>x.map(a=>a>0?t.unshift(a):t.pop(),t=[])&&tè ancora più breve.
Neil

(O è a?sufficiente, immagino?)
Neil

3

Mathematica, 46 45 byte

Grazie a ngenisis per il salvataggio di 1 byte.

Reverse[#//.{_Integer:0,a___,X,b___}:>{a,b}]&

Fondamentalmente lo stesso della mia risposta Retina, usando il pattern matching. Abbiniamo ripetutamente il primo Xe lo rimuoviamo insieme al primo numero (se ne esiste uno). Al termine, invertiamo l'elenco.


3

Pure Bash, 72

Input fornito come parametri della riga di comando.

for a;{
[ ${a/X} ]&&q=(${a:n++,0} ${q[@]})||((n-=n>0))
}
echo ${q[@]::n}

Provalo online .



3

MATL , 13 12 byte

vi"@?@wh}IL)

L'input è un array di numeri, con 0"dequeue".

L'output è costituito da numeri separati da spazi. Un risultato vuoto viene mostrato come nulla.

Provalo online! Oppure verifica tutti i casi di test .

Spiegazione

v        % Concatenate stack contents: gives []. This will grow to represent the queue
i        % Input numeric array
"        % For each entry in the input array
  @?     %   If current entry is non-zero
    @wh  %     Prepend current entry to the queue
  }      %   Else
    IL)  %     Remove last element from the queue
         %   End (implicit)
         % End (implicit)
         % Display (implicit)

3

Haskell, 41 40 byte

l#a|a>0=a:l|l>[]=init l|1>0=l

La funzione è foldl(#)[](inclusa anche in bytecount con un byte di separazione tra)

Provalo online!

X è un numero intero non positivo

EDIT: -1 byte grazie a nimi


Puoi salvare le ultime due guardie per salvare un byte:|l>[]=init l|1>0=l
nimi

3

Julia, 78 76 73 57 byte

f(a)=(q=[];[x<1?q=q[2:end]:push!(q,x)for x=a];reverse(q))

Grazie a Harrison Grodin per alcuni eccellenti suggerimenti sul golf Julia. Sostituito if / else con ternary e for / end con comprensione elenco per un risparmio di 16 byte.

f(a)=(q=[];for x in a if x<1 q=q[2:end]else q=[q...,x]end end;reverse(q))

Rimossi alcuni spazi non necessari per un risparmio di 3 byte.

Prima che fossero ammessi numeri negativi o zero:

f(a)=(q=[];for x in a if x==:X q=q[2:end] else q=[q...,x] end end;r everse(q))

Ungolfed:

function dequeue(list)
    queue = []

    for x in list
        if x < 1
            queue = queue[2:end]
        else
            queue = [queue..., x]
        end
    end

    reverse(queue)
end

Sono abbastanza nuovo per Julia; potrebbe esserci un modo migliore. Usa :Xper X, che è un simbolo in Julia. Aggiornato: ora che è consentito 0, utilizza 0 (o qualsiasi numero negativo) per X, salvando due caratteri. Aggiornato di nuovo per rimuovere alcuni spazi bianchi che non avevo realizzato non fossero necessari.


2

05AB1E , 12 11 byte

Salvataggio di un byte grazie a Riley

)Evyai¨ëy¸ì

Provalo online!

Spiegazione

I dequeues sono indicati da qualsiasi lettera .

)             # wrap stack in a list (pushes empty list)
 Ev           # for each y in evaluated input
   yai        # if y is a letter
      ¨       # remove the first element of the list
       ëy¸ì   # else, prepend y to the list

2

GNU Sed, 43

Il punteggio include +2 per l'uso dei flag -re -n.

G
s/X\n( *|(.*)\b\S+ *)$/\2/
s/\n/ /
h
$p

Provalo online .

Spiegazione

                            # Implicitly read the next line
G                           # append a newline, then the contents of the hold space
s/X\n( *|(.*)\b\S+ *)$/\2/  # If the input was an X, remove it, the newline, and any element at the end
s/\n/ /                     # Otherwise if the input was not an X, it is simply enqueued by removing the newline between it and the rest of the line
h                           # save a copy of the queue to the hold space
$p                          # since we're using -n to suppress output at the end of processing each input line, then this explicit print is required in the last line

2

PHP, 85 byte

<?$r=[];foreach($_GET as$v)is_int($v)?array_unshift($r,$v):array_pop($r);print_r($r);

-8 byte $vanziché is_int($v)se ogni valore di dequeue appartiene a false


2

Python 3 , 95 94 byte

def f(x):q=[];[*map(lambda s:exec(("q.pop(0)"if q else"","q+=[s]")[s!="X"]),x)];print(q[::-1])

Provalo online!

Anche 94 byte:

def f(x):q=[];[*map(lambda s:exec((("","q.pop(0)")[q>[]],"q+=[s]")[s!="X"]),x)];print(q[::-1])

2

Perl 5 , 28 + 1 = 29 byte

28 byte di codice + -pflag.

/\d/?$\=$_.$\:$\=~s/.*
$//}{

Provalo online!

Utilizza una stringa ( $\) come coda: quando l'input contiene un numero intero ( /\d/?, lo aggiungiamo all'inizio di $\( $\=$_.$\), e altrimenti rimuoviamo l'ultimo con s/.*\n$//. Alla fine, $\è implicitamente stampato grazie a -pflag (e quelli senza eguali }{).


Altri approcci:

  • 33 byte , usando un array come coda (credo sia il modo più naturale di farlo in Perl, ma non il più breve):

    /X/?pop@F:unshift@F,$_}{$_="@F"

    Provalo online!

  • 52 byte , usando regex e reverse(sembra esattamente la stessa cosa della risposta Retina di Martin Ender - grazie alla quale ho salvato 2 byte su di esso). L'inversione dell'elenco richiede molti caratteri, perché per preservare gli interi, devo convertire la stringa in un array per invertirla, quindi tornare a una stringa per stamparla. ( say forinvece di $_=join$",salvare 2 byte, ma richiede -Eo -M5.010e non è così interessante).

    s/\d+ (.*?)X ?|^X/$1/&&redo;$_=join$",reverse split

    Provalo online!


1

Python 3, 107 byte

def f(x):
 r = []
 for i in x:exec("try:r.pop(0)\nexcept:8;r+=i,".split(";")[type(i)==int])
 return r[::-1]

Dequeuer può essere qualsiasi valore non numerico.

Provalo online


1

Lotto, 160 byte

@set s=.
@for %%n in (%*)do @if %%n==X (call set s=%%s:* =%%)else call set s=%%s:~,-1%%%%n .
@set t=
@for %%n in (%s:~,-1%)do @call set t= %%n%%t%%
@echo%t%

Questo è stato più difficile di quanto fosse necessario.

  • Sebbene Batch possa enumerare il risultato della divisione di una stringa, non può rimuovere facilmente un elemento dall'enumerazione.
  • Può rimuovere il primo oggetto, ma solo se è presente almeno un oggetto. Altrimenti ottieni spazzatura.

Ciò significa che I a) devo avere un indicatore di fine coda, che non viene rimosso, e b) devo manipolare la coda da dietro a fronte, quindi nuovi elementi vengono inseriti appena prima del marcatore di fine, in modo che i vecchi oggetti possano essere rimossi dalla parte anteriore, il che significa che I c) deve invertire la coda prima di stamparla.


1

PHP, 70 byte

foreach($argv as$v)+$v?$r[]=$v:array_shift($r);krsort($r);print_r($r);

1

C #, 115 byte +33 byte per l'utilizzo

l=>{var r=new List<int>();foreach(var n in l)if(n<0)try{r.RemoveAt(0);}catch{}else r.Add(n);r.Reverse();return r;};

Metodo anonimo che restituisce un elenco di numeri interi dopo aver eseguito le operazioni di accodamento e dequeuing. Gli interi negativi vengono utilizzati per rimuovere elementi dalla coda.

Programma completo con metodo non golfizzato e casi di test:

using System;
using System.Collections.Generic;

public class Program
{
    static void PrintList(List<int> list)
    {
        var s = "{";
        foreach (int element in list)
            s += element + ", ";
        if (s.Length > 1)
            s += "\b\b";
        s += "}";
        Console.WriteLine(s);
    }

    public static void Main()
    {
        Func<List<int>, List<int>> f =
        l =>
        {
            var r = new List<int>();
            foreach (var n in l)
                if (n < 0)
                    try
                    {
                        r.RemoveAt(0);
                    }
                    catch
                    { }
                else
                    r.Add(n);
            r.Reverse();
            return r;
        };

        // test cases:
        var list = new List<int>(new[]{1, -1, 2, -1, 3, -1});   // {}
        PrintList(f(list));

        list = new List<int>(new[]{1, 2, -1});  // {2}
        PrintList(f(list));

        list = new List<int>(new[]{1, 2, 3});   // {3, 2, 1}
        PrintList(f(list));

        list = new List<int>(new[]{1, 2, -1, -1, -1, 3});   // {3}
        PrintList(f(list));

        list = new List<int>(new[]{1, 2, -1, 3, -1, 4});    // {4, 3}
        PrintList(f(list));
    }
}

1

Scala, 97 byte

type S=Seq[_];def f(a:S,b:S):S=a match{case h::t=>f(t,if(h==0)b dropRight 1 else h+:b);case _=>b}

Come input, faccetta un elenco con 0l'elemento "dequeue". Usa la ricorsione della coda con un secondo parametro ( b), che funge da accumulatore. Inizialmente, bè il vuoto Seq(Nil ).

Spiegazioni:

type S=Seq[_]                               // defines a type alias (save 1 byte since Seq[_] is used 3 times)
def f(a: S, b: S): S = {                    // a is the initial list, b is an accumulator
    a match {                           
        case h::t =>                        // if a is non-empty
            f(t,                            // recursive call to f with 1st parameter as the tail
                if (h==0) b dropRight 1     // if h == 0 (dequeue) then remove last element of b,
                else h+:b                   // otherwise, just add h at the beginning of b in recursive call
            )
        case _ => b                         // when the list is empty, return b (final result)
    }
}

Nota: b dropRight 1 viene utilizzato al posto di b.tailad eccezione Evitare: tail of empty list.

Casi test :

f(Seq(45, 0, 0, 37, 20, 0, 97, 0, 85), Nil)     // List(85, 97)
f(Seq(1, 0, 2, 0, 3, 0), Nil)                   // List()
f(Seq(1, 2, 0), Nil)                            // List(2)
f(Seq(1, 2, 3), Nil)                            // List(3, 2, 1)
f(Seq(1, 2, 0, 0, 0, 3), Nil)                   // List(3)
f(Seq(1, 2, 0, 3, 0, 4), Nil)                   // List(4, 3)

fpuò funzionare anche con altri tipi ( String, char, ..., anche la lista eterogenea di quei tipi!):

f(Seq(false, '!', "world", 0, "Hello"), Nil)    // List(Hello, world, !)

1

REXX, 115 byte

arg n
do while n>''
  parse var n m n
  if m=X then pull
  else queue m
  end
o=
do while queued()>0
  pull a
  o=a o
  end
say o

Prende una stringa separata da spazio, stampa una stringa separata da spazio


1

C ++, 122 119 byte

#import<list>
void f(std::list<int>o,std::list<int>&q){for(int i:o)if(i)q.push_front(i);else if(q.size())q.pop_back();}

0 indica un dequeue.

Provalo online!


1

Swift 3, 70 byte

Supponendo che abbiamo una serie di Ints come let x = [1, 2,-1,3,-1,4]

print(x.reduce([].prefix(0)){(a,i)in return i>0 ?[i]+a:a.dropLast(1)})

Si noti che [].prefix(0)è un modo subdolo per ottenere un ArraySlice vuoto

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.