เท่ากับชนิดวงเล็บเหลี่ยม


9

บนพื้นฐาน นี้คำถาม

กำหนดสตริงแทนที่แต่ละวงเล็บ()[]{}<>ด้วยวงเล็บของประเภทที่เหมาะสมเพื่อให้วงเล็บจับคู่และรอบซ้อนกันวงเล็บดังนี้

  1. สิ่งที่อยู่นอกสุดคือ ()
  2. ()ควรจะอยู่ข้างในโดยตรง[]
  3. []ควรจะอยู่ข้างในโดยตรง{}
  4. {}ควรจะอยู่ข้างในโดยตรง<>
  5. ด้านในตรงจาก<>จะเป็น()อีกครั้ง (รอบ)

ตัวอักษรที่ไม่ใช่วงเล็บทั้งหมดจะต้องคงอยู่เหมือนเดิม วงเล็บเปิดอาจถูกแทนที่ด้วยวงเล็บเปิดบางชนิดเท่านั้นและปิดวงเล็บด้วยวงเล็บปิด

อินพุตจะทำให้เป็นไปได้เสมอ นี่หมายความว่าวงเล็บนั้นจับคู่อย่างถูกต้องหากไม่ระบุประเภท ดังนั้น{ab<)c]เป็นอินพุตที่ถูกต้อง แต่มีab)(cdหรือab((cdไม่

ตัวอย่าง:

2#jd {¤>. = 2#jd (¤).
abcdef    = abcdef
(3×5+(4-1)) = (3×5+[4-1])
<<<>><<>><<<<<<>>>>>>> = ([{}][{}][{<([{}])>}])

ไม่อนุญาตให้ใช้การแปลงดั้งเดิมของอินพุตด้วยวิธีนี้ (ไวยากรณ์ภาษาอัตโนมัติ)

เช่นเคย: รหัสที่สั้นที่สุดชนะ


ฉันไม่เข้าใจความท้าทาย เอาต์พุตต้องเป็นอะไรในแง่ของอินพุต?
xnor

@ xnor เอาต์พุตควรเป็นสตริงเดียวกันกับอินพุตยกเว้นวงเล็บสี่ชนิด พวกเขาจะต้องเปลี่ยนเพื่อให้ตรงกับรูปแบบ
Dirk Reichel

ตอนนี้ฉันเห็นแล้ว ฉันไม่เข้าใจว่า "ควร" เป็นสิ่งที่คุณควรทำให้เป็นจริง ฉันจะแก้ไขเพื่อให้ชัดเจนยิ่งขึ้น
xnor

1
@ DirkReichel ฉันไม่คิดว่าเป็นสิ่งที่คุณต้องกังวลเกี่ยวกับ ฉันไม่สามารถจินตนาการได้ว่าภาษาใด ๆ ที่สามารถเปลี่ยนแปลงรูปแบบนี้ได้อย่างเป็นธรรมชาติและในกรณีที่ไม่น่าเป็นไปได้ที่จะมีภาษาดังกล่าวทั้งหมดนั่นหมายความว่าคำตอบในภาษานั้นจะไม่น่าสนใจมาก
Martin Ender

2
@ DirkReichel ประเด็นคืออะไร? เพียงแค่ติดกับ ASCII การใช้อักขระที่แตกต่างกันไม่ได้เพิ่มความท้าทายใด ๆ นอกเหนือจากข้อ จำกัด ที่ไม่จำเป็นสำหรับภาษา ASCII เท่านั้น
FlipTack

คำตอบ:


2

JavaScript (ES6), 79 ไบต์

s=>s.replace(/./g,c=>~(p=l.indexOf(c))?l[p&4?--k&3|4:k++&3]:c,l='([{<)]}>',k=0)

กรณีทดสอบ


1

เล็ก ๆ 132 ไบต์

%{
int i,o[4]={40,91,123,60};
%}
%%
[[({<] {putchar(o[i++&3]);}
[])}>] {putchar(o[--i&3]+2-!(i&3));}
%%
yywrap(){}
main(){yylex();}

คุณสามารถบันทึก 27 ไบต์ (portable lex) หรือ 30 bytes (ใช้flexเป็นคอมไพเลอร์) ผ่านการลบสองหรือสามบรรทัดสุดท้ายตามลำดับโดยมีค่าใช้จ่ายจำนวนไบต์ (อาจเป็น 2, 3 หรือ 4 กฎค่อนข้างไม่ชัดเจน) ในบทลงโทษสำหรับ-llตัวเลือกบรรทัดคำสั่งเมื่อเชื่อมโยงไฟล์ C ผลลัพธ์ (นั่นคือแทนที่จะรวบรวมlex brackets.l; cc lex.yy.cคุณรวบรวมด้วยlex brackets.l; cc lex.yy.c -ll) นั่นเป็นการแลกเปลี่ยนที่คุ้มค่าในสถานการณ์นี้

1

Java, 155 ไบต์

a->{String s="([{<)]}>";for(int i=0,j=0,k;i<a.length;i++){k=s.indexOf(a[i]);if(k>3){a[i]=s.charAt(--j%4+4);}else if(k>-1){a[i]=s.charAt(j++%4);}}return a;}

แลมบ์ดาที่รับเรื่องchar[]นี้เป็นข้อโต้แย้งเดียว เราวนรอบอาร์เรย์โดยเก็บตำแหน่งไว้ในสตริงของวงเล็บ ( s) ในตัวแปร ( k) เราตรวจสอบว่ามันเป็นวงเล็บเปิดหรือปิด ( s.indexAt()) และแทนที่ด้วยวงเล็บที่เหมาะสมตามระดับของการซ้อน ( s.charAt()) โดยวนซ้ำอย่างเหมาะสม%4


1

Haskell, 126 ไบต์

b="([{<"
d=")]}>"
y=cycle
(!)=elem
f(e:c)n(x:r)|x!b=y b!!n:f(y d!!n:e:c)(n+1)r|x!d=e:f c(n-1)r|1<3=x:f(e:c)n r
f c n s=s
f" "0

ลองใช้กับ ideone การใช้งาน:

*Main> f" "0 "<<<>><<>><<<<<<>>>>>>>"
"([{}][{}][{<([{}])>}])"

คำอธิบาย

fใช้เวลาสามข้อโต้แย้ง: สตริงที่ทำงานเป็นสแต็คสำหรับการปิดวงเล็บ int nสำหรับการนับความลึกการทำรังและสตริงการป้อนข้อมูล

f c n "" = ""                            -- base case for recursion: input string is empty
f (e:c) n (x:r)                          -- for the current char x
   | elem x "([{<" =                     -- check if it is an opening bracket
       (cycle "([{<")!!n :               --   if so, replace it with a bracket of the current nesting depth
           f ((cycle ")]}>")!!n : e : c) --   push the matching closing bracket on the stack
               (n+1) r                   --   increase depth level and check the next char
   | elem x ")]}>" =                     -- if x is a closing bracket
       e :                               --   replace it by the closing bracket from on top of the stack
           f c (n-1) r                   --   decrement depth level and check the next char
   | otherwise     = x : f (e:c) n r     -- otherwise keep x and check the next char
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.