Khi số nguyên tham gia hàng đợi


26

Giới thiệu

Một hàng đợi là một kiểu dữ liệu trừu tượng mà yếu tố được thêm vào phía trước (enqueue) và lấy ra từ phía sau (dequeue). Điều này còn được gọi là FIFO (First In First Out) nguyên tắc .

Nó được hiển thị tốt nhất với một ví dụ:

nhập mô tả hình ảnh ở đây


Thử thách

Đưa ra một mảng không trống có chứa các số nguyênphần tử dương biểu thị một dequeue (loại bỏ một phần tử), xuất ra danh sách cuối cùng của hàng đợi.

Chúng ta hãy nói rằng Xbiểu thị một dequeue trong ví dụ này. Hãy xem danh sách sau đây:

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

Điều này có thể được dịch sang mã giả hàng đợi sau đây:

                   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

Bạn có thể thấy rằng cuối cùng, kết quả là [85, 97], đó là đầu ra cho chuỗi này.


Các trường hợp thử nghiệm

Lưu ý rằng bạn có thể chọn bất kỳ ký hiệu hoặc ký tự nào khác X, miễn là nó không phải là số nguyên dương.

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

Đây là , vì vậy bài nộp có số byte ít nhất sẽ thắng!


Nó có thể là một chuỗi phân tách không gian Thay vì một mảng?
Riley

@Riley Chắc chắn, bất cứ điều gì tốt nhất cho bạn
Adnan

2
Chúng tôi có thể sử dụng số âm cho x (Haskell không hỗ trợ danh sách không đồng nhất)
Tên hiển thị chung

2
... Hoặc các số nguyên không âm khác như 0 hay nửa?
Jonathan Allan

@GenericDisplayName Hmm, điểm tốt. Tôi sẽ cho phép miễn là nó không phải là số nguyên dương
Adnan

Câu trả lời:


4

Thạch , 8 byte

F;@Ṗṛ?¥/

Sử dụng bất kỳ giá trị giả ( 0 hoặc lặp lại trống) để dequeue.

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

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
Thật ra nó không bị cấm. Chỉ các số nguyên dương bị cấm, 0 là trung tính.
Erik the Outgolfer

Đó không phải là những gì nó nói khi tôi đăng câu trả lời của mình, nhưng cảm ơn vì đã ngẩng cao đầu.
Dennis


7

Toán học, 102 byte

Chắc chắn đó không phải là giải pháp ngắn nhất, nhưng tôi không thể cưỡng lại được vì đó là loại đồi trụy.

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

Sau một số hàm trợ giúp, hàm này xác định một hàm thuần túy lấy một chuỗi làm đầu vào: trong chuỗi, các số được phân tách bằng dấu phẩy (khoảng trắng là tùy chọn); nhân vật dequeue là "]"; và danh sách không có dấu phân cách ở phía trước hoặc phía sau. Chẳng hạn, ví dụ đầu tiên trong OP sẽ là đầu vào dưới dạng chuỗi"45,],],37,20,],97,],85" . Đầu ra của hàm là một danh sách các số.

Hàm này đếm xem có bao nhiêu dequeues "]"trong chuỗi đầu vào, nối thêm nhiều bản sao "f["vào phía trước chuỗi, và sau đó bao quanh toàn bộ "r[...]". Trong ví dụ trên, điều này tạo ra "r[f[f[f[f[45,],],37,20,],97,],85]"; chú ý các dấu ngoặc được cân bằng.

Sau đó, ToExpressiondiễn giải chuỗi kết quả dưới dạng một đoạn mã Mathicala và thực thi nó. Hàm fđược định nghĩa một cách thuận tiện để giữ lại tất cả các đối số của nó ngoại trừ đối số đầu tiên (và cũng bỏ qua dấu phẩy; điều này là cần thiết để xử lý hàng đợi trống bằng cách nào) vàr chuyển đổi chuỗi số kết quả thành một danh sách các số theo đúng thứ tự.


Là dấu phẩy trong dòng 3 b___,có nghĩa là ở đó? Nó hoạt động , nhưng dấu phẩy chuyển sang màu đỏ vì nó. (còn nữa, sự khác biệt giữa dòng 2 và 3 là gì?)
numbermaniac

1
Mắt tốt :) Dòng 2 tương đương với f[a_,b___]:=b(không có dấu phẩy), trong khi dòng 3 tương đương với f[a_,b___,Null]:=b. Trong cả hai trường hợp, b___đề cập đến bất kỳ số lượng đối số (bao gồm cả không có đối số). Dòng 3 cụ thể hơn, vì vậy luôn được sử dụng trước dòng 2 khi thích hợp. Vì vậy, hàm fbỏ qua đối số đầu tiên của nó và cũng bỏ qua đối số cuối cùng của nó nếu đối số đó là Null. Điều này là cần thiết để xử lý việc sắp xếp hàng đợi trống. Lưu ý rằng một đầu vào thông thường sẽ mang lại một biểu thức như r[f[f[f[5,3,],2,],],11], trong đó mỗi dấu phẩy trước đó ]lại biểu thị a Null.
Greg Martin

1
Wow, rất đẹp :). Nhân tiện, tôi nghĩ rằng nó thực sự là 102 byte; bạn có thể đã tính thêm một ký tự dòng mới vào cuối.
numbermaniac

4

Võng mạc , 30 byte

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

Hãy thử trực tuyến!

Lặp đi lặp lại loại bỏ số đầu tiên (không nhất thiết phải ngay lập tức) theo sau Xcùng với số đó Xhoặc Xở đầu chuỗi. Sau đó đảo ngược các số còn lại.


4

JavaScript, 70 63 53 50 43 byte

Cảm ơn @Neil vì đã chơi golf 10 byte với x.map thay vì biểu thức vòng lặp và ternary

Cảm ơn @Arnauld vì đã chơi golf 3 byte

Cảm ơn @ETHproductions đã chơi golf 7 byte

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

Hãy thử trực tuyến!

Dequeue có thể là bất kỳ giá trị không phải là số nào khác với true.


Điều này sẽ ngắn hơn nếu bạn sử dụng một ternary thay vì một if câu lệnh và ngắn hơn nếu bạn sử dụng mapthay vì một vòng lặp, và thậm chí ngắn hơn nếu bạn sử dụng một biểu thức thay vì một khối. Xem các mẹo .
Neil

Tôi đã đăng phiên bản đầu tiên tôi làm việc. Sau đó tôi ăn tối: P
fəˈnɛtɪk

Bạn có thể làm x=>(t=[],x.map(a=>a>0?t.unshift(a):t.pop()),t)để tiết kiệm khá nhiều byte trênreturn
ETHproductions

x=>x.map(a=>a>0?t.unshift(a):t.pop(),t=[])&&tthậm chí còn ngắn hơn.
Neil

(Hoặc chỉ là a?đủ, tôi đoán vậy?)
Neil

3

Toán học, 46 45 byte

Cảm ơn ngenisis vì đã tiết kiệm 1 byte.

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

Về cơ bản giống như câu trả lời Retina của tôi, sử dụng khớp mẫu. Chúng tôi liên tục khớp số đầu tiên Xvà xóa nó cùng với số đầu tiên (nếu có). Sau khi hoàn thành, chúng tôi đảo ngược danh sách.



3

Haskell, 41 byte

x&y:z|y<1=init x&z|w<-y:x=w&z
x&y=x
([]&)

Ninja'd :) có vẻ như chúng tôi có cùng một ý tưởng
Tên hiển thị chung

(Mặc dù bạn cần dấu ngoặc đơn quanh y: z likex&(y:z)
Tên hiển thị chung

Nó hoạt động trong REPL của tôi, một phần của những cái ôm. Tôi không chắc chắn về phiên bản chính xác mặc dù.
Michael Klein

3

MATL , 13 12 byte

vi"@?@wh}IL)

Đầu vào là một dãy số, với 0"dequeue".

Đầu ra là các số được phân tách bằng dấu cách. Một kết quả trống được hiển thị là không có gì.

Hãy thử trực tuyến! Hoặc xác minh tất cả các trường hợp thử nghiệm .

Giải trình

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

Hàm là foldl(#)[](Cũng được bao gồm trong bytecount với một byte phân tách ở giữa)

Hãy thử trực tuyến!

X là bất kỳ số nguyên không dương nào

EDIT: -1 byte nhờ nimi


Bạn có thể lật hai vệ sĩ cuối cùng để lưu một 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))

Cảm ơn Harrison Grodin cho một số gợi ý chơi golf tuyệt vời của Julia. Đã thay thế if / other bằng ternary và for / end bằng cách hiểu danh sách để tiết kiệm 16 byte.

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

Đã xóa một số khoảng trống không cần thiết để tiết kiệm 3 byte.

Trước khi số âm hoặc số 0 được cho phép:

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

Ung dung:

function dequeue(list)
    queue = []

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

    reverse(queue)
end

Tôi khá mới mẻ với Julia; có thể có một cách tốt hơn Sử dụng :Xcho X, đó là một Biểu tượng trong Julia. Đã cập nhật: Bây giờ 0 được cho phép, sử dụng 0 (hoặc bất kỳ số âm nào) cho X, lưu hai ký tự. Cập nhật lại để xóa một số khoảng trắng mà tôi không nhận ra là không cần thiết.


2

05AB1E , 12 11 byte

Đã lưu một byte nhờ Riley

)Evyai¨ëy¸ì

Hãy thử trực tuyến!

Giải trình

Dequeues được ký hiệu bằng bất kỳ chữ cái .

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

Điểm bao gồm +2 để sử dụng -r-ncờ.

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

Hãy thử trực tuyến .

Giải trình

                            # 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 $vthay vì is_int($v)nếu mọi giá trị dequeue thuộc về 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])

Hãy thử trực tuyến!

Cũng 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 mã + -pcờ.

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

Hãy thử trực tuyến!

Nó sử dụng một chuỗi ( $\) làm hàng đợi: khi đầu vào chứa một số nguyên ( /\d/?, chúng tôi sẽ thêm nó vào đầu $\( $\=$_.$\) và nếu không, chúng tôi sẽ xóa chuỗi cuối cùng với s/.*\n$//. Cuối cùng, $\được in ngầm nhờ -pcờ (và những người chưa từng có }{).


Các cách tiếp cận khác:

  • 33 byte , sử dụng một mảng làm hàng đợi (đó là cách tự nhiên nhất để làm điều đó trong Perl tôi nghĩ, nhưng không phải là ngắn nhất):

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

    Hãy thử trực tuyến!

  • 52 byte , sử dụng regex và reverse(nó hoàn toàn giống với câu trả lời Retina của Martin Ender - nhờ tôi đã lưu 2 byte trên đó). Việc đảo ngược danh sách cần rất nhiều ký tự, vì để bảo toàn các số nguyên, tôi phải chuyển đổi chuỗi thành một mảng để đảo ngược nó, sau đó quay lại chuỗi để in. ( say forthay vì $_=join$",có thể lưu 2 byte, nhưng nó yêu cầu -Ehoặc -M5.010không thú vị lắm).

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

    Hãy thử trực tuyến!



1

Mẻ, 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%

Điều này là khó khăn hơn nó cần phải được.

  • Mặc dù Batch có thể liệt kê kết quả của việc tách một chuỗi, nhưng nó không thể dễ dàng loại bỏ một phần tử khỏi bảng liệt kê.
  • Nó có thể loại bỏ mục đầu tiên, nhưng chỉ khi có ít nhất một mục. Nếu không bạn nhận được rác.

Điều này có nghĩa là tôi a) cần phải có điểm đánh dấu cuối hàng đợi, không bị xóa và b) phải thao tác hàng đợi ngược về phía trước, để các mục mới được chèn ngay trước điểm đánh dấu kết thúc, để các mục cũ có thể được gỡ bỏ từ phía trước, điều đó có nghĩa là tôi c) phải đảo ngược hàng đợi trước khi in.



1

C #, 115 byte +33 byte để sử dụng

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

Phương thức ẩn danh trả về danh sách các số nguyên sau khi thực hiện các thao tác sắp xếp hàng và sắp xếp. Số nguyên âm được sử dụng để loại bỏ các phần tử khỏi hàng đợi.

Chương trình đầy đủ với phương pháp vô căn cứ và các trường hợp thử nghiệm:

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}

Là đầu vào, flấy một danh sách với 0phần tử "dequeue". Nó sử dụng đệ quy đuôi với tham số thứ hai ( b), hoạt động như một bộ tích lũy. Ban đầu, blà trống rỗng Seq(Nil ).

Giải thích:

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

Lưu ý: b dropRight 1 được sử dụng thay vì b.tailđể tránh ngoại lệ : tail of empty list.

Các trường hợp thử nghiệm:

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)

fcũng có thể làm việc với các loại khác ( String, char, ..., thậm chí danh sách không đồng nhất của các loại!):

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

Tạo một chuỗi được phân tách bằng dấu cách, in một chuỗi được phân tách bằng dấu cách



1

Swift 3, 70 byte

Giả sử chúng ta có một mảng Ints như let x = [1, 2,-1,3,-1,4]

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

Lưu ý rằng đó [].prefix(0)là một cách lén lút để có được một ArraySlice trống

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.