สะเก็ดที่สาม!


19

ความท้าทายนี้ถูกโพสต์เป็นส่วนหนึ่งของความท้าทาย LotM เมษายน 2018


Brain-Flakเป็นภาษา turing-tarpit ซึ่งได้รับชื่อเสียงอย่างมากใน PPCG ความทรงจำของภาษานั้นประกอบด้วยสองกอง แต่มีการค้นพบสแต็กที่สามที่ "ซ่อน" โดยWh e at Wizardซึ่งนำไปสู่วิธีคิดใหม่ที่น่าสนใจในการคิดโปรแกรม Brain-Flak

แล้วจะให้การมองเห็นที่ดีกว่านั้นในสแต็คที่สามได้อย่างไร มาสร้างภาษาที่สแต็กที่สามมีการจดจำที่สมควรได้รับ! นี่ฉันนำเสนอคุณสาม Flak

ภาษา

ใน Third-Flak มีเพียงหนึ่งกองที่เรียกว่ากองที่สาม ผู้ประกอบการทำงานในกองที่สามในลักษณะเดียวกับที่พวกเขาทำใน Brain-Flak แต่ที่นี่ไม่มี[], {}, <>nilads และไม่มี{...}monad (เพื่อให้ตัวละครเท่านั้นที่ยอมรับในโปรแกรมที่สาม Flak มี()[]<>) นี่คือสิ่งที่ผู้ประกอบการแต่ละรายทำ (ตัวอย่างจะได้รับการแทนสแต็กที่สามพร้อมกับรายการที่องค์ประกอบสุดท้ายคือด้านบนของสแต็ก):

  • ()เป็นโอเปอเรเตอร์สองอักขระเพียงตัวเดียวใน Third-Flak เพิ่มด้านบนของสแต็กที่สามโดย 1 ตัวอย่าง: [1,2,3][1,2,4]

  • (, [, <: ทุกวงเล็บเปิดที่ไม่ได้รับการคุ้มครองโดยกรณีก่อนหน้านี้ดัน0ไปกองที่สาม ตัวอย่าง: [1,2,3][1,2,3,0]

  • )ดึงองค์ประกอบสองอย่างจากสแต็กที่สามและผลักกลับผลรวมของพวกเขา ตัวอย่าง: [1,2,3][1,5]

  • ]ดึงสององค์ประกอบจากสแต็กที่สามและผลักผลลัพธ์การลบแรกออกจากองค์ประกอบที่สอง ตัวอย่าง: [1,2,3][1,-1]

  • >ดึงองค์ประกอบจากสแต็กที่สาม ตัวอย่าง[1,2,3][1,2]

และนี่คือกฎอื่น ๆ ของภาษา:

  • ที่จุดเริ่มต้นของการดำเนินการสแต็กที่สามมีเพียง 0 เดียว

  • มันเป็นสิ่งต้องห้ามที่จะมีที่ว่างเปล่า[]หรือ<>ในโปรแกรม (พวกเขาจะเป็น noops ต่อไปนี้ถ้าตามความหมายของ Third-Flak แต่จริง ๆ แล้วพวกเขามีความหมายที่แตกต่างกันใน Brain-Flak ที่เป็นไปไม่ได้ที่จะสร้างที่นี่)

  • วงเล็บต้องมีความสมดุลเสมอยกเว้นความจริงที่ว่าวงเล็บปิดท้ายท้ายโปรแกรมอาจหายไป ตัวอย่างเช่น[()<(()เป็นโปรแกรม Third-Flak ที่ถูกต้อง (และสแต็กที่สามในตอนท้ายของโปรแกรมจะเป็น[1,0,1])

  • โปรแกรมสามารถมีอักขระที่อนุญาตได้หกตัวเท่านั้น ()[]<>เท่านั้น โปรแกรมมีการรับประกันว่าจะไม่ว่างเปล่า

หมายเหตุ: มันมีนัยโดยกฎก่อนหน้านี้ที่คุณไม่ต้องจัดการกับสถานการณ์ที่คุณจำเป็นต้องปรากฏขึ้นจากสแต็กที่ว่างเปล่า

ความท้าทาย

ง่ายเขียนล่ามสำหรับ Third-Flak โปรแกรมของคุณจะต้องใช้เป็นอินพุตโปรแกรม Third-Flak และกลับเป็นสถานะเอาต์พุตของสแต็กที่สามในตอนท้ายของโปรแกรม

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

ตัวเลือกผลลัพธ์ของคุณอาจ จำกัด ช่วงของตัวเลขที่คุณสามารถจัดการได้ตราบใดที่สิ่งนี้ไม่ได้เป็นการท้าทายเล็กน้อย (เนื่องจากเป็นช่องโหว่เริ่มต้น )

กรณีทดสอบ

สำหรับแต่ละกรณีทดสอบบรรทัดแรกคืออินพุตและบรรทัดที่สองสแต็กเอาท์พุทที่แสดงเป็นรายการที่คั่นด้วยช่องว่างของตัวเลขที่ด้านบนของสแต็กเป็นองค์ประกอบสุดท้าย

[()<(()
0 1 0 1

[((((()()()()()))
0 0 0 5

((([()][()][()])))
-3

[<<(((()()()())(((((
0 0 0 0 0 4 0 0 0 0 0

[()]<(([()])><[()]
-1 0 -1

(())(()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(())(()()())(())(()()()()())(())(())(())(())(()()()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(())(()()())(())(()()()()())(())(())(())(())(())(())(()())(())(())(())(()())(()()()())(())(()()()()())(()())(()())(()())(()()())(())(()())(())(()()()()())(()())(()()()()())(())(())(())(())(())(()())(())(())(())(()()()()())(())(())(()()()()())(())(())(()()()()())(())(())(()())(())(()())(())(()())(())(()())(())(()())(()())(()())(()())(()())(()())(()())(()())(())(()()()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(())(()()())(())(())(()()())(()())(())(()()()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(())(())(())(()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(()()())(())(()()())(())(())(())(()())(()()())(()())(())(()()()()())(()())(())(()()())(())(()()()()())(())(())(())(()()())(())(())(())(()())(())(()())(()()()())(())(())(()()()()())(()())(()())(())(()()())(())(())(())(())(()()())(()())(())(())(()()()()())(())(())(()()()()())(())(())(()()()()())(())(())(()())(())(()())(())(()())(())(()())(()())(()())(()())(())(()()()()())(()())(())(()()())(())(()()()()())(()()()()())(())(()()())(())(())(()())(())(()()()()())(())(()()()()())(())(())(())(()()()()())(())(())(()())(())(()())(())(()())(())(()())(())(()())(()())(()())(()())(())(()()()()())(()())(())(()()())(())(())(()())(())(()()()()())(()())(()()()()())(())(()()())(())(())(()()()()())(())(()()()()())(())(())(())(()())(())(()()()()())(())(())(()())(())(()())(())(()())(()())(()())(()())(())(()()()()())(()())(())(()()()()())(())(()()())(())(())(()())(())(()()()()())(()())(()()()()())(())(()()())(())(())(())(()())(()()()())(())(())(()())(())(()()()()())(())(())(()()()()())(())(())(()()()()())(())(())(()())(())(()())(())(()())(())(()())(())(()())(()())(()())(()())(()())(()())(())(()()())(())(())(()())(())(()()()()())(()())(()()()()())(()()())(())(())(()())(())(())(()()()()())(()()()())(()())(()())(()()())(())(()())(())(()()()()())(()())(()()()()())(())(())(())(()()()())(()()()())(()()
718 2

สแต็กเริ่มต้นด้วย 0 หรือไม่? มิฉะนั้น[()]จะทำผิดกฎที่เราไม่ต้องกังวลเกี่ยวกับการโผล่จากกองที่ว่างเปล่า
โจคิง

1
@JoKing Yep: "ที่จุดเริ่มต้นของการดำเนินการกองที่สามมีเพียง 0 เดียว" บางทีฉันควรเน้นที่ส่วนเล็กน้อยฉันกลัวว่ามันจะง่ายเกินไปที่จะพลาด
Leo

โอ๊ะฉันไม่ทราบว่าจะพลาดได้อย่างไร
Jo King

7
ข้ามออก e ยังคงเป็น e
ข้าวสาลีตัวช่วยสร้าง

2
ถ้าใครไม่เห็นว่าการเดินออกeคือที่นี่
user202729

คำตอบ:


21

Brain-Flakขนาด 276 ไบต์

{({}<>)<>}<>{(((()()()()()){})((({}){})())(({})({}{}([{}])(<>))))((()()(){[()]<{}>}{}){()<{{}}>}{}<<>({}({})())>{()(<{}>)}{}<>)<>}<>{(([{}]()<>)){{}({}())((){[()](<({}())((){[()](<({}())((){[()](<{}([{}]{})>)}{}){(<{}{}>)}{}>)}{}){(<{}({}{})>)}{}>)}{}){(<{}{}({}())>)}}{}<>}<>

ลองออนไลน์!

คุณต้องรู้ว่าสิ่งนี้กำลังจะมาถึง


4

เรติน่า 0.8.2 , 64 48 46 ไบต์

\(\)
_
[([<]
¶
+1`¶(.*)\)|(.*)¶\2]|¶.*>
$1
%`_

ลองออนไลน์! ส่งออกสแต็กจากล่างขึ้นบน ใช้งานได้เฉพาะกับจำนวนเต็มไม่เป็นลบและกรณีทดสอบล่าสุดช้าเกินไปดังนั้นลิงก์มีเพียงสามกรณีทดสอบ คำอธิบาย: สแต็กนำหน้าโปรแกรมโดยปริยายดังนั้นจึงเริ่มต้นเป็นสตริงว่างซึ่งแสดงถึงศูนย์เดียว ()nilad จะกลายเป็น_ที่ใช้ในการนับในเอกขณะที่วงเล็บอื่น ๆ ที่เปิดจะกลายเป็นบรรทัดใหม่ซึ่งผลักดันให้เป็นศูนย์ในการสแต็คที่พวกเขาจะพบ วงเล็บปิดจะถูกประมวลผลทีละครั้งเพื่อให้สแต็กถูกต้อง การ)ลบ newline ก่อนหน้าเพิ่มองค์ประกอบสองอันดับแรกด้วยกันการ]ลบองค์ประกอบด้านบนและจับคู่จากองค์ประกอบก่อนหน้าในสแต็กจึงลบออกและ>เพียงลบองค์ประกอบด้านบน ในที่สุดสแต็คจะถูกแปลงเป็นทศนิยม แก้ไข: บันทึก 2 ไบต์ขอบคุณ @Leo


อะไร$3หา? (คำตอบที่ดีอยู่แล้ว!)
Leo

@Leo นั่นเป็นซ้ายจากสนามกอล์ฟก่อนหน้านี้ ขอบคุณที่จำได้!
Neil

4

Python 3 , 145 144 132 122 116 109 104 ไบต์

-7 ไบต์ขอบคุณ Leo!

และ - 5 ต้องขอขอบคุณ Lynn!

s=[0]
for i in input().replace('()',' '):s+=i in']>) 'and(i<'!'or(2-ord(i)%5)*s.pop())+s.pop(),
print(s)

ลองออนไลน์!

ใช้งานมาตรฐานสวย ไม่สามารถอ่านได้ตอนนี้ ฉันผิดหวังฉันไม่สามารถหาวิธีที่สั้นกว่าในการตรวจสอบระหว่างวงเล็บเริ่มต้นและจุดสิ้นสุด

ความพยายามที่หนึ่งสมุทร:

  • 124 ไบต์ (ฟังก์ชันที่ไม่ระบุตัวตน):

    lambda c:[s.append(i in']>) 'and(i<'!'or~-']>)'.index(i)*s.pop())+s.pop())or s for s in[[0]]for i in c.replace('()',' ')][0]
  • 115 ไบต์ (โปรแกรมเต็มรูปแบบ):

    s=[0];[s.append(i in']>) 'and(i<'!'or~-']>)'.index(i)*s.pop())+s.pop())for i in input().replace('()',' ')];print(s)

ผนวกยาวกว่าการกำหนดธรรมดาอย่างน่ารำคาญ


~-']>)'.index(i)สามารถ(2-ord(i)%5)บันทึก 4 ไบต์
ลินน์

2

Ruby , 98 91 ไบต์

->s{a=[i=0];s.chars{|c|a<<("([<"[c]?s[i,2]["()"]?1:0:a.pop*~-"]>)".index(c)+a.pop);i+=1};a}

ลองออนไลน์!

โค้ดเริ่มต้นของฉันทำงานคล้าย ๆ กับคำตอบของ Python ของ Jo King ดังนั้นก่อนที่จะวนลูปผ่าน chars ต้นฉบับเราจึงแทนที่()substrings ทั้งหมดด้วยอักขระอื่นเป็นตัวดำเนินการที่แตกต่างกัน

อย่างไรก็ตามอย่างน้อยใน Ruby ก็กลายเป็นนักเล่นกอล์ฟที่จะไม่ทำสิ่งนี้ แต่ควรไปหาวิธีที่ยุ่งยากกว่านี้เล็กน้อย ที่นี่เรายังคงทำดัชนีเพิ่มเติมiติดตามการรักษาตำแหน่งของเราในสตริงแหล่งที่มาและเมื่อใดก็ตามที่วงเล็บเปิดจะพบเราทำ lookahead ตรวจสอบว่าปัจจุบัน + ตัวอักษรต่อไปของเราs[i,2]ในรูปแบบ()ผู้ประกอบการ ในกรณีนี้เรากด 1 แทน 0 ที่ด้านบนของสแต็กและให้การปิด)ทำงานในขั้นตอนถัดไป


1

05AB1E , 25 ไบต์

΄()1:v"0+0\0->"žuykè.V})

ลองออนไลน์!

คำอธิบาย

Î                           # initialize the stack with 0 and the input
 „()1:                      # replace any occurrence of "()" in the input with 1
      v                }    # for each char y in this string
                žuyk        # get its index in the string "()[]<>{}"
       "0+0\0->"    è       # use this to index into the string "0+0\0->"
                     .V     # eval
                        )   # wrap the stack in a list


1

R , 182 177 ไบต์

function(P){for(k in utf8ToInt(gsub("\\(\\)",7,P))%%8){if(k%in%0:4)F=c(0,F)
if(k==7)F[1]=F[1]+1
if(k==1)F=c(F[2]+F[3],F[-3:0])
if(k==5)F=c(F[2]-F[1],F[-2:0])
if(k==6)F=F[-1]}
F}

ลองออนไลน์!

ส่งคืนสแต็กโดยที่ด้านบนของสแต็กเป็นอันดับแรกและด้านล่างของสแต็กเป็นครั้งสุดท้าย

สลับ()กับ7แล้วคำนวณจุดรหัส mod 8 เพื่อรับค่าตัวเลขที่แตกต่างกันซึ่งง่ายกว่าและนักกอล์ฟจะทำงานได้ดีกว่าสตริง

เป็นนักกอล์ฟที่ทำงานกับจุดเริ่มต้นของเวกเตอร์ใน R ดังนั้นเราจึงสร้างกองซ้อนแบบนั้น

จากนั้นจะเห็น a )หรือเมื่อใดk==1ก็ตามจะเพิ่มศูนย์พิเศษให้กับด้านบนสุดของสแต็กเนื่องจากเป็น golfier ที่จะเพิ่มและลบออก



1

Ceylon, 285 266 ไบต์

function f(variable String c){variable Integer[]s=[0];value o=>[s[0]else nothing,s=s.rest][0];void u(Integer i)=>s=[i,*s];while(c!=""){if(c[0:2]=="()"){u(1);c=c.rest;}switch(c[0])case(')'){u(o+o);}case(']'){u(-o+o);}case('>'){noop(o);}else{u(0);}c=c.rest;}return s;}

ลองออนไลน์!

(บันทึก 19 ไบต์เนื่องจากคำแนะนำโดย Leo)

จัดรูปแบบและแสดงความคิดเห็น:

// Interpreter for ThirdFlak
// Question:    /codegolf//q/163242/2338
// This answer: /codegolf//a/163403/2338
//
// This function takes the code as a string, and returns the value
// of the stack as a sequence of Integers.
function f(variable String c) {
    // stack, in the beginning just a single 0.
    // Top element of the stack is the first, because push + pop is easier this way.
    variable Integer[] s = [0];
    // pop – used like an Integer variable (not a function – this saves the `()`), but has side effects.
    value o =>
        // `s[0]` is the first element of the stack. We tell the compiler
        // that it is non-null (otherwise we'll get an error at run time)
        // using the `else nothing`. `s.rest` is `s` without its first element.
        // Both together are wrapped into a 2-tuple, of which we then take just
        // the first element, to have both together in an expression instead
        // the longer way using an accessor block with a temporary variable and a return.
        // value o {
        //   value r = s[0] else nothing;
        //   s = s.rest;
        //   return r;
        // }
        [s[0] else nothing, s = s.rest][0];
    // push
    void u(Integer i) =>
        // a tuple enumeration, using the spread argument.
        s = [i, *s];
    // the main loop
    while (c != "") {
        if (c[0:2] == "()") {
            // »`()` is the only two-characters operator in Third-Flak. It increases the top of the third stack by 1.«
            // As `)` alone adds the two top elements together, we can just push a one here, and let the handling for `)` do the rest.
            u(1);
            c = c.rest;
        }
        switch (c[0])
        case (')') {
            // »`)` pops two elements from the third stack and pushes back their sum.«
            u(o + o);
        }
        case (']') {
            // »`]` pops two elements from the third stack and pushes back the result of subtracting the first from the second.«
            // As the o written first is the first one, we can't write this as a subtraction.
            u(-o + o);
        }
        case ('>') {
            // »`>` pops an element from the third stack.«
            // `o;` alone is not a valid statement, so we pass it to the `noop` function.
            noop(o);
        }
        else {
            // all other valid code characters are `(`, `[`, `<`, which all just push a 0.
            u(0);
        }
        c = c.rest;
    }
    return s;
}

ลองออนไลน์!


ฉันไม่รู้ Ceylon จริง ๆ แต่บางทีคุณสามารถลบกรณีแรกของสวิตช์และใช้ส่วนอื่นในการจัดการวงเล็บเปิดทั้งหมด :)
Leo

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