เมื่อจำนวนเต็มเข้าร่วมคิว


26

บทนำ

คิวเป็นชนิดข้อมูลนามธรรมที่องค์ประกอบเพิ่มไปด้านหน้า (enqueue) และลบออกจากด้านหลัง (dequeue) นอกจากนี้ยังเป็นที่รู้จักกันFIFO (First In First Out)หลักการ

มันจะแสดงที่ดีที่สุดด้วยตัวอย่าง:

ป้อนคำอธิบายรูปภาพที่นี่


ท้าทาย

รับอาร์เรย์ที่ไม่ว่างเปล่าที่มีจำนวนเต็มบวกและองค์ประกอบที่ระบุdequeue (ลบองค์ประกอบ) ออกรายการสุดท้ายของคิว

สมมุติว่าXเป็น dequeue ในตัวอย่างนี้ ลองดูรายการต่อไปนี้:

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

สิ่งนี้สามารถแปลเป็นรหัสคิวหลอกต่อไปนี้:

                   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

คุณจะเห็นว่าในท้ายที่สุดผลลัพธ์คือ[85, 97]ซึ่งเป็นผลลัพธ์สำหรับลำดับนี้


กรณีทดสอบ

โปรดทราบว่าคุณสามารถเลือกสัญลักษณ์หรือตัวละครXอื่นได้ตราบใดที่ไม่ใช่จำนวนเต็มบวก

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

นี่คือดังนั้นการส่งที่มีจำนวนไบต์น้อยที่สุดจะชนะ!


มันสามารถเป็นช่องว่างที่คั่นสตริงแทนที่จะเป็นอาร์เรย์ได้หรือไม่?
Riley

@Riley แน่นอนว่าสิ่งที่ดีที่สุดสำหรับคุณ
Adnan

2
เราสามารถใช้จำนวนลบสำหรับ x (Haskell ไม่รองรับรายการต่างกันได้)
ชื่อที่แสดงทั่วไป

2
... หรือจำนวนเต็มอื่นที่ไม่ใช่ลบเช่นศูนย์หรือครึ่ง?
Jonathan Allan

@GenericDisplayName อืมจุดดี ฉันจะให้มันตราบเท่าที่มันไม่ใช่จำนวนเต็มบวก
Adnan

คำตอบ:


4

เยลลี่ขนาด 8 ไบต์

F;@Ṗṛ?¥/

ใช้ค่าเท็จ ( 0หรือว่างเปล่า iterable) เพื่อ dequeue

ลองออนไลน์!

มันทำงานอย่างไร

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
จริงๆแล้วมันไม่ได้รับอนุญาต เฉพาะจำนวนเต็มบวกเท่านั้นที่ถูกห้าม 0 เป็นค่ากลาง
Erik the Outgolfer

นั่นไม่ใช่สิ่งที่พูดเมื่อฉันโพสต์คำตอบของฉัน แต่ขอบคุณสำหรับหัวขึ้น
Dennis


7

Mathematica, 102 ไบต์

ไม่ใช่วิธีแก้ปัญหาที่สั้นที่สุด แต่ฉันไม่สามารถต้านทานได้เพราะเป็นสิ่งที่ผิดปกติ

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

หลังจากฟังก์ชั่นตัวช่วยบางฟังก์ชั่นนี้จะกำหนดฟังก์ชั่นบริสุทธิ์ที่ใช้สตริงเป็นอินพุต: ในสตริงตัวเลขจะถูกคั่นด้วยเครื่องหมายจุลภาค (ช่องว่างเป็นทางเลือก); ตัวละคร dequeue คือ"]"; และรายการไม่มีตัวคั่นด้านหน้าหรือด้านหลัง ยกตัวอย่างเช่นตัวอย่างแรกใน OP "45,],],37,20,],97,],85"จะมีการป้อนข้อมูลเป็นสตริง ผลลัพธ์ของฟังก์ชันคือรายการตัวเลข

นับว่าหลายฟังก์ชั่น dequeues "]"อยู่ในสายป้อน, ผนวกที่สำเนาหลายไปยังด้านหน้าของสตริงแล้วล้อมรอบสิ่งที่ทั้งโดย"f[" "r[...]"ในตัวอย่างด้านบนสิ่งนี้ทำให้เกิด"r[f[f[f[f[45,],],37,20,],97,],85]"; สังเกตเห็นว่าวงเล็บมีความสมดุล

จากนั้นToExpressionตีความสตริงผลลัพธ์เป็นชิ้นส่วนของรหัส Mathematica และดำเนินการ ฟังก์ชั่นfถูกกำหนดไว้อย่างสะดวกสบายเพื่อรักษาข้อโต้แย้งทั้งหมดยกเว้นแรก (และยังละเว้นเครื่องหมายจุลภาคต่อท้าย; นี่เป็นสิ่งจำเป็นในการจัดการ dequeueing คิวว่างอยู่แล้ว) และrแปลงลำดับของตัวเลขที่เกิดขึ้นเป็นรายการของตัวเลขในลำดับที่ถูกต้อง


เครื่องหมายจุลภาคในบรรทัด 3 ที่b___,ตั้งใจจะอยู่ที่นั่นหรือไม่ มันใช้งานได้ แต่คอมม่าเปลี่ยนเป็นสีแดงเพราะมัน (เช่นกันความแตกต่างระหว่างบรรทัดที่ 2 และ 3 คืออะไร)
numbermaniac

1
ดีตา :) สาย 2 เทียบเท่ากับf[a_,b___]:=b(ไม่จุลภาค) ในขณะที่สาย 3 f[a_,b___,Null]:=bจะเทียบเท่ากับ ในทั้งสองกรณีb___อ้างถึงอาร์กิวเมนต์จำนวนเท่าใดก็ได้ (รวมถึงไม่มีเลย) บรรทัดที่ 3 มีความเฉพาะเจาะจงมากกว่าดังนั้นจึงมักใช้ก่อนบรรทัดที่ 2 ตามความเหมาะสม ดังนั้นฟังก์ชันละเว้นอาร์กิวเมนต์แรกของตนและยังละเว้นอาร์กิวเมนต์สุดท้ายถ้าอาร์กิวเมนต์ที่เป็นf Nullนี่เป็นสิ่งจำเป็นในการจัดการ dequeueing คิวที่ว่างเปล่า โปรดทราบว่าการป้อนข้อมูลโดยทั่วไปจะให้การแสดงออกเช่นr[f[f[f[5,3,],2,],],11]ที่แต่ละจุลภาคก่อนอีกครั้งหมายถึง] Null
Greg Martin

1
ว้าวดีมาก :) โดยวิธีการที่ฉันคิดว่ามันเป็นจริง 102 ไบต์; คุณอาจนับอักขระขึ้นบรรทัดใหม่พิเศษในตอนท้าย
numbermaniac

4

เรติน่า 30 ไบต์

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

ลองออนไลน์!

ซ้ำแล้วซ้ำอีกเอาหมายเลขแรกว่า (ไม่จำเป็นต้องใช้ทันที) ตามมาด้วยการXร่วมกับที่XหรือXที่จุดเริ่มต้นของสตริง จากนั้นกลับจำนวนที่เหลือ


4

JavaScript, 70 63 53 50 43 ไบต์

ขอบคุณ @Neil สำหรับการเล่นกอล์ฟ 10 ไบต์ด้วย x.map แทนการวนซ้ำและนิพจน์ที่สาม

ขอบคุณ @Arnauld สำหรับการเล่นกอล์ฟ 3 ไบต์

ขอบคุณ @ETHproductions สำหรับการเล่นกอล์ฟขนาด 7 ไบต์

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

ลองออนไลน์!

Dequeue สามารถเป็นค่าที่ไม่ใช่ตัวเลขใด ๆ นอกเหนือจากจริง


สิ่งนี้จะสั้นลงหากคุณใช้ ternary แทนที่จะเป็นif คำสั่งและจะสั้นลงถ้าคุณใช้mapแทนการวนซ้ำและยังสั้นลงถ้าคุณใช้นิพจน์แทนบล็อก ดูเคล็ดลับ
Neil

ฉันโพสต์รุ่นแรกที่ฉันทำงาน จากนั้นฉันกินข้าวเย็น: P
fəˈnɛtɪk

คุณสามารถทำได้x=>(t=[],x.map(a=>a>0?t.unshift(a):t.pop()),t)เพื่อบันทึกไม่กี่ไบต์ในreturn
ETHproductions

x=>x.map(a=>a>0?t.unshift(a):t.pop(),t=[])&&tสั้นกว่า
Neil

(หรือเพียงแค่a?พอฉันเดา?)
Neil

3

Mathematica, 46 45 ไบต์

ขอบคุณ ngenisis สำหรับการบันทึก 1 ไบต์

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

โดยพื้นฐานแล้วเหมือนกับคำตอบ Retina ของฉันโดยใช้การจับคู่รูปแบบ เราจับคู่หมายเลขแรกXและลบออกพร้อมกับหมายเลขแรก (หากมี) หลังจากเราทำเสร็จแล้วเราจะกลับรายการ



3

Haskell, 41 ไบต์

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

Ninja'd :) ดูเหมือนว่าเรามีความคิดเดียวกัน
ชื่อที่แสดงทั่วไป

(แม้ว่าคุณต้องการวงเล็บล้อมรอบ y: z เช่นx&(y:z)
ชื่อที่แสดงทั่วไป

มันทำงานได้ใน REPL ของฉันซึ่งเป็นส่วนหนึ่งของการกอด ฉันไม่แน่ใจว่าของรุ่นที่แน่นอน
Michael Klein

3

MATL , 13 12 ไบต์

vi"@?@wh}IL)

อินพุตคืออาร์เรย์ของตัวเลขโดยมีค่า0สำหรับ "dequeue"

ผลลัพธ์คือตัวเลขคั่นด้วยช่องว่าง ผลลัพธ์ที่ว่างเปล่าแสดงเป็นไม่มีอะไร

ลองออนไลน์! หรือตรวจสอบกรณีทดสอบทั้งหมด

คำอธิบาย

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 Bytes

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

ฟังก์ชั่นคือfoldl(#)[](รวมอยู่ใน bytecount ด้วยไบต์ของการแยกในระหว่าง)

ลองออนไลน์!

X เป็นจำนวนเต็มใด ๆ ที่ไม่เป็นบวก

แก้ไข: -1 ไบต์ขอบคุณ nimi


คุณสามารถพลิกสองการ์ดล่าสุดเพื่อบันทึกไบต์:|l>[]=init l|1>0=l
nimi

3

Julia, 78 76 73 57 ไบต์

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

ขอบคุณ Harrison Grodin สำหรับคำแนะนำการเล่นกอล์ฟที่ยอดเยี่ยมของ Julia แทนที่หาก / else ด้วย ternary และ for / end ด้วย list comprehension เพื่อการประหยัด 16 ไบต์

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

ลบช่องว่างที่ไม่จำเป็นออกเพื่อประหยัด 3 ไบต์

ก่อนอนุญาตให้ใช้จำนวนลบหรือศูนย์ได้:

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

ฉันค่อนข้างใหม่กับจูเลีย อาจมีวิธีที่ดีกว่า ใช้:Xสำหรับ X ซึ่งเป็นสัญลักษณ์ใน Julia อัปเดต: ตอนนี้อนุญาตให้ 0 ใช้ 0 (หรือจำนวนลบใด ๆ ) สำหรับ X บันทึกอักขระสองตัว อัปเดตอีกครั้งเพื่อลบพื้นที่ว่างบางส่วนที่ฉันไม่ทราบว่าไม่จำเป็น


2

05AB1E , 12 11 ไบต์

บันทึกเป็นไบต์ด้วยRiley

)Evyai¨ëy¸ì

ลองออนไลน์!

คำอธิบาย

Dequeues จะแสดงด้วยตัวอักษรใด

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

คะแนนรวมถึง +2 สำหรับการใช้งาน-rและ-nค่าสถานะ

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

ลองมันออนไลน์

คำอธิบาย

                            # 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 ไบต์

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

-8 ไบต์$vแทนis_int($v)ถ้าค่า dequeue ทุกค่าเป็นเท็จ



2

Perl 5 , 28 + 1 = 29 ไบต์

รหัสไบต์ 28 + -pธง

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

ลองออนไลน์!

มันใช้สตริง ( $\) เป็นคิว: เมื่ออินพุตมีจำนวนเต็ม ( /\d/?เราต่อท้ายที่จุดเริ่มต้นของ$\( $\=$_.$\) และมิฉะนั้นเราจะลบอันสุดท้ายด้วยs/.*\n$//ตอนท้าย$\จะถูกพิมพ์โดยปริยายขอบคุณ-pธง (และ ไม่ตรงกัน}{)


แนวทางอื่น ๆ :

  • 33 ไบต์โดยใช้อาร์เรย์เป็นคิว (เป็นวิธีที่ง่ายที่สุดใน Perl ฉันคิดว่า แต่ไม่ใช่สั้นที่สุด):

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

    ลองออนไลน์!

  • 52 bytes , ใช้ regex และreverse(มันเกิดขึ้นค่อนข้างตรงกับคำตอบของ Retina Ender ของ Martin Ender - ขอบคุณที่ฉันบันทึก 2 ไบต์ไว้) การย้อนกลับรายการใช้อักขระจำนวนมากเนื่องจากเพื่อรักษาจำนวนเต็มฉันต้องแปลงสตริงเป็นอาร์เรย์เพื่อย้อนกลับจากนั้นกลับสู่สตริงเพื่อพิมพ์ ( say forแทนที่จะ$_=join$",สามารถบันทึกได้ 2 ไบต์ แต่ต้องการ-Eหรือ-M5.010ไม่น่าสนใจ)

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

    ลองออนไลน์!



1

แบตช์ 160 ไบต์

@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%

มันยากกว่าที่คิด

  • แม้ว่าแบทช์สามารถระบุผลลัพธ์ของการแยกสตริงได้ แต่ก็ไม่สามารถลบองค์ประกอบออกจากการแจงนับได้อย่างง่ายดาย
  • มันสามารถลบรายการแรก แต่เฉพาะในกรณีที่มีอย่างน้อยหนึ่งรายการ มิฉะนั้นคุณจะได้รับขยะ

ซึ่งหมายความว่าฉันก) ต้องมีเครื่องหมายสิ้นสุดของคิวซึ่งไม่ได้ถูกลบออกและ b) ต้องจัดการคิวกลับไปกลับมาดังนั้นรายการใหม่จะถูกแทรกไว้ข้างหน้าเครื่องหมายสุดท้าย เพื่อให้สามารถลบรายการเก่าออกจากด้านหน้าซึ่งหมายความว่าฉันค) ต้องย้อนกลับคิวก่อนที่จะพิมพ์



1

C #, 115 ไบต์ +33 ไบต์สำหรับการใช้

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

วิธีไม่ระบุตัวตนซึ่งส่งคืนรายการจำนวนเต็มหลังจากดำเนินการ en-queuing และ dequeuing จำนวนเต็มลบใช้สำหรับลบองค์ประกอบออกจากคิว

โปรแกรมเต็มรูปแบบด้วยวิธีการที่ไม่ดีและกรณีทดสอบ:

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

สกาลา 97 ไบต์

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}

ในฐานะอินพุตให้fใช้รายการที่มี0องค์ประกอบ "dequeue" มันใช้การเรียกซ้ำแบบหางด้วยพารามิเตอร์ที่สอง ( b) ทำหน้าที่เป็นตัวสะสม เริ่มแรกbคือว่างเปล่าSeq( Nil)

คำอธิบาย:

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

หมายเหตุ: b dropRight 1ใช้แทนb.tailเพื่อหลีกเลี่ยงข้อยกเว้น: tail of empty list.

กรณีทดสอบ:

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)

fยังสามารถทำงานกับประเภทอื่น ๆ ( String, char... แม้รายการที่แตกต่างกันประเภทเหล่านั้น!):

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

1

REXX, 115 ไบต์

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

ใช้สตริงที่คั่นด้วยช่องว่างพิมพ์สตริงที่คั่นด้วยช่องว่าง



1

Swift 3, 70 bytes

สมมติว่าเรามีอาร์เรย์ของ 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)})

โปรดทราบว่า[].prefix(0)เป็นวิธีการลับๆเพื่อรับ ArraySlice ที่ว่างเปล่า

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.