Ketika bilangan bulat bergabung dengan antrian

26

pengantar

Sebuah antrian adalah jenis data abstrak di mana unsur-unsur yang ditambahkan ke depan (enqueue) dan dihapus dari belakang (dequeue). Ini juga dikenal sebagai prinsip FIFO (First In First Out) .

Paling baik ditunjukkan dengan contoh:

masukkan deskripsi gambar di sini


Tantangan

Diberikan array yang tidak kosong yang berisi bilangan bulat positif dan elemen yang menunjukkan dequeue (menghapus elemen), menampilkan daftar akhir antrian.

Katakanlah itu Xmenunjukkan dequeue dalam contoh ini. Mari kita lihat daftar berikut:

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

Ini dapat diterjemahkan ke kode antrian-pseudo berikut:

                   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

Anda dapat melihat bahwa pada akhirnya, hasilnya adalah [85, 97], yang merupakan output untuk urutan ini.


Uji kasus

Perhatikan bahwa Anda dapat memilih simbol atau karakter lain apa pun X, asalkan bukan bilangan bulat positif.

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

Ini adalah , jadi pengiriman dengan jumlah byte paling sedikit menang!

Adnan
sumber
Bisakah itu menjadi string yang dipisahkan ruang, bukannya array?
Riley
@Riley Tentu, apa pun yang paling cocok untuk Anda
Adnan
2
Bisakah kita menggunakan angka negatif untuk x (Haskell tidak mendukung daftar heterogen)
Nama Tampilan Umum
2
... atau bilangan bulat non-non-negatif lainnya seperti nol atau setengah?
Jonathan Allan
@GenericDisplayName Hmm, poin bagus. Saya akan mengizinkannya selama itu bukan bilangan bulat positif
Adnan

Jawaban:

4

Jelly , 8 byte

F;@Ṗṛ?¥/

Menggunakan nilai falsy ( 0 atau kosongkan iterable) ke dequeue.

Cobalah online!

Bagaimana itu bekerja

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.
Dennis
sumber
1
Sebenarnya itu tidak dilarang. Hanya bilangan bulat positif yang terlarang, 0 adalah netral.
Erik the Outgolfer
Bukan itu yang dikatakan ketika saya memposting jawaban saya, tapi terima kasih atas jawabannya.
Dennis
8

Python 2, 56 53 50 byte

q=[]
for i in input():q=[[i]+q,q[:i]][i<0]
print q

Cobalah secara Online!

Dequeue adalah -1. Trik ini memungkinkan irisan pythonic yang mudah dari antrian.

pecandu matematika
sumber
7

Mathematica, 102 byte

Jelas bukan solusi terpendek, tapi saya tidak bisa menolak karena itu agak menyimpang.

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

Setelah beberapa fungsi pembantu, ini mendefinisikan fungsi murni yang mengambil string sebagai input: dalam string, angka dipisahkan dengan koma (spasi putih adalah opsional); karakter dequeue adalah "]"; dan daftar tidak memiliki pembatas di bagian depan atau belakang. Misalnya, contoh pertama dalam OP adalah input sebagai string "45,],],37,20,],97,],85". Output dari fungsi adalah daftar angka.

Fungsi menghitung berapa banyak dequeues "]"dalam string input, menambahkan banyak salinan "f["ke bagian depan string, dan kemudian mengelilingi semuanya "r[...]". Dalam contoh di atas, ini menghasilkan "r[f[f[f[f[45,],],37,20,],97,],85]"; perhatikan tanda kurung seimbang.

Kemudian, ToExpressiontafsirkan string yang dihasilkan sebagai bagian dari kode Mathematica dan jalankan. Fungsi fmudah didefinisikan untuk mempertahankan semua argumen kecuali yang pertama (dan juga mengabaikan koma tertinggal; ini diperlukan untuk menangani antrian kosong dequeueing tetap), dan rmengubah urutan angka yang dihasilkan menjadi daftar angka dalam urutan yang benar.

Greg Martin
sumber
Apakah koma pada baris 3 b___,dimaksudkan untuk berada di sana? Ini berfungsi , tetapi koma berubah merah karena itu. (juga, apa perbedaan antara garis 2 dan 3?)
numbermaniac
1
Baik mata :) Baris 2 sama dengan f[a_,b___]:=b(tanpa koma), sedangkan baris 3 setara dengan f[a_,b___,Null]:=b. Dalam kedua kasus, b___mengacu pada sejumlah argumen (termasuk tidak ada sama sekali). Jalur 3 lebih spesifik, jadi selalu digunakan sebelum jalur 2 jika perlu. Jadi fungsi fmengabaikan argumen pertama, dan juga mengabaikan argumen terakhirnya jika argumen itu Null. Ini diperlukan untuk menangani antrian yang kosong. Perhatikan bahwa input tipikal akan menghasilkan ekspresi seperti r[f[f[f[5,3,],2,],],11], di mana setiap koma sebelumnya ]menunjukkan a Null.
Greg Martin
1
Wow sangat bagus :). By the way, saya pikir itu sebenarnya 102 byte; Anda mungkin telah menghitung karakter baris baru ekstra di akhir.
numbermaniac
4

Retina , 30 byte

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

Cobalah online!

Secara berulang menghapus angka pertama yang (tidak harus segera) diikuti oleh yang Xbersama - sama dengan itu X, atau Xdi awal string. Kemudian membalikkan angka yang tersisa.

Martin Ender
sumber
4

JavaScript, 70 63 53 50 43 byte

Terima kasih @Neil untuk bermain golf 10 byte dengan x.map alih-alih untuk ekspresi loop dan ternary

Terima kasih @Arnauld untuk bermain golf 3 byte

Terima kasih @ETHproduk untuk bermain golf 7 byte

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

Cobalah online!

Dequeue dapat berupa nilai non-numerik selain true.

fəˈnɛtɪk
sumber
Ini akan lebih pendek jika Anda menggunakan terner daripada if pernyataan, dan lebih pendek lagi jika Anda menggunakan mapbukan loop, dan bahkan lebih pendek lagi jika Anda menggunakan ekspresi bukan blok. Lihat tipsnya .
Neil
Saya telah memposting versi pertama saya mulai berfungsi. Kemudian saya makan malam: P
fəˈnɛtɪk
Anda dapat melakukan x=>(t=[],x.map(a=>a>0?t.unshift(a):t.pop()),t)untuk menyimpan beberapa byte padareturn
ETHproduk
x=>x.map(a=>a>0?t.unshift(a):t.pop(),t=[])&&tbahkan lebih pendek.
Neil
(Atau hanya a?cukup, saya kira?)
Neil
3

Mathematica, 46 45 byte

Terima kasih kepada ngenisis karena telah menghemat 1 byte.

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

Pada dasarnya sama dengan jawaban Retina saya, menggunakan pencocokan pola. Kami berulang kali mencocokkan yang pertama Xdan menghapusnya bersama dengan angka pertama (jika ada). Setelah selesai, kami membalik daftar.

Martin Ender
sumber
3

Pure Bash, 72

Input diberikan sebagai parameter baris perintah.

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

Cobalah online .

Trauma Digital
sumber
3

Haskell, 41 byte

x&y:z|y<1=init x&z|w<-y:x=w&z
x&y=x
([]&)
Michael Klein
sumber
Ninja'd :) sepertinya kami memiliki ide yang sama
Generic Display Name
(Meskipun Anda membutuhkan tanda kurung di sekitar y: z sepertix&(y:z)
Generic Display Name
Ini bekerja di REPL saya yang merupakan bagian dari pelukan. Saya tidak yakin dengan versi pastinya.
Michael Klein
3

MATL , 13 12 byte

vi"@?@wh}IL)

Input adalah array angka, dengan 0untuk "dequeue".

Output adalah angka yang dipisahkan oleh spasi. Hasil kosong ditampilkan sebagai tidak ada.

Cobalah online! Atau verifikasi semua kasus uji .

Penjelasan

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)
Luis Mendo
sumber
3

Haskell, 41 40 Bytes

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

Fungsi foldl(#)[](Termasuk dalam bytecount dengan byte pemisahan di antaranya)

Cobalah online!

X adalah bilangan bulat non-positif

EDIT: -1 byte terima kasih kepada nimi

Nama Tampilan Umum
sumber
Anda dapat membalik dua penjaga terakhir untuk menghemat 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))

Terima kasih kepada Harrison Grodin untuk beberapa saran golf Julia yang bagus. Diganti jika / selain dengan ternary dan for / end dengan daftar pemahaman untuk penghematan 16 byte.

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

Menghapus beberapa ruang yang tidak perlu untuk penghematan 3 byte.

Sebelum angka negatif atau nol diizinkan:

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

Tidak Disatukan:

function dequeue(list)
    queue = []

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

    reverse(queue)
end

Saya cukup baru untuk Julia; mungkin ada cara yang lebih baik. Menggunakan :Xuntuk X, yang merupakan Simbol di Julia. Diperbarui: Sekarang 0 diizinkan, menggunakan 0 (atau angka negatif apa pun) untuk X, menyimpan dua karakter. Diperbarui lagi untuk menghapus spasi putih yang tidak saya sadari tidak diperlukan.

David Conrad
sumber
2

05AB1E , 12 11 byte

Menyimpan satu byte berkat Riley

)Evyai¨ëy¸ì

Cobalah online!

Penjelasan

Dequeues dilambangkan dengan huruf apa saja .

)             # 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
Emigna
sumber
2

GNU Sed, 43

Skor termasuk +2 untuk penggunaan -rdan -nbendera.

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

Cobalah online .

Penjelasan

                            # 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
Trauma Digital
sumber
2

PHP, 85 Bytes

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

-8 Bytes $valih-alih is_int($v)jika setiap nilai dequeue milik false

Jörg Hülsermann
sumber
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])

Cobalah online!

Juga 94 byte:

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

Perl 5 , 28 + 1 = 29 byte

28 byte kode + -pbendera.

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

Cobalah online!

Ia menggunakan string ( $\) sebagai antrian: ketika input berisi integer ( /\d/?, kami menambahkannya di awal $\( $\=$_.$\), dan sebaliknya, kami menghapus yang terakhir dengan s/.*\n$//. Pada akhirnya, $\dicetak secara implisit berkat -pflag (dan yang tidak cocok }{).


Pendekatan lain:

  • 33 byte , menggunakan array sebagai antrian (itu cara paling alami untuk melakukannya di Perl saya pikir, tapi bukan yang terpendek):

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

    Cobalah online!

  • 52 byte , menggunakan regex dan reverse(kebetulan hal yang persis sama dengan jawaban Retina Martin Ender - terima kasih kepada siapa saya menyimpan 2 byte di atasnya). Membalik daftar membutuhkan banyak karakter, karena untuk mempertahankan bilangan bulat, saya harus mengubah string ke array untuk membalikkannya, lalu kembali ke string untuk mencetaknya. ( say forAlih-alih $_=join$",dapat menyimpan 2 byte, tetapi membutuhkan -Eatau -M5.010dan itu tidak menarik).

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

    Cobalah online!

Dada
sumber
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 dapat berupa nilai non-numerik.

Cobalah online

caird coinheringaahing
sumber
1

Batch, 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%

Ini lebih sulit daripada yang seharusnya.

  • Meskipun Batch dapat menghitung hasil pemisahan string, ia tidak dapat dengan mudah menghapus elemen dari enumerasi.
  • Itu dapat menghapus item pertama, tetapi hanya jika ada setidaknya satu item. Kalau tidak, Anda mendapatkan sampah.

Ini berarti bahwa saya a) perlu memiliki penanda end-of-queue, yang tidak dapat dihapus, dan b) harus memanipulasi antrian kembali ke depan, sehingga item baru dimasukkan tepat sebelum penanda akhir, sehingga barang lama dapat dihapus dari depan, yang kemudian berarti I c) harus membalikkan antrian sebelum mencetaknya.

Neil
sumber
1

PHP, 70 byte

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

C #, 115 byte +33 byte untuk digunakan

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

Metode anonim yang mengembalikan daftar bilangan bulat setelah melakukan operasi en-queuing dan dequeuing. Bilangan bulat negatif digunakan untuk menghapus elemen dari antrian.

Program lengkap dengan metode ungolfed dan test case

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

Sebagai input, fambil daftar dengan 0elemen "dequeue". Ia menggunakan ekor-rekursi dengan parameter kedua ( b), bertindak sebagai akumulator. Awalnya, badalah kosong Seq( Nil).

Penjelasan:

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

Catatan: b dropRight 1 digunakan sebagai pengganti b.tailuntuk menghindari pengecualian: tail of empty list.

Kasus uji:

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)

fjuga dapat bekerja dengan jenis lain ( String, char, ..., bahkan daftar heterogen jenis orang!):

f(Seq(false, '!', "world", 0, "Hello"), Nil)    // List(Hello, world, !)
norbjd
sumber
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

Mengambil string yang dipisahkan spasi, mencetak string yang dipisahkan spasi

idrougge
sumber
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 menunjukkan suatu dequeue.

Cobalah online!

Steadybox
sumber
1

Swift 3, 70 byte

Dengan asumsi kita memiliki array seperti Ints let x = [1, 2,-1,3,-1,4]

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

Perhatikan bahwa [].prefix(0)ini adalah cara licik untuk mendapatkan ArraySlice kosong

Mat
sumber