ตรวจสอบโปรแกรม Brainfuck


17

อีกปัญหาหนึ่งในการแยกวิเคราะห์ Brainfuck แต่คราวนี้ ... ต่างออกไป

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

เนื่องจากเครื่องทัวริง (โดยเฉพาะอย่างยิ่งเครื่องเร็ว) มีราคาแพง (หลังจากทั้งหมดเครื่องเหล่านี้มี RAM แบบอินฟินิตี้ซึ่งมีค่าใช้จ่าย) มันจะดีกว่าเพื่อให้แน่ใจว่าโปรแกรมจะไม่มีข้อผิดพลาดทางไวยากรณ์ใด ๆ บริษัท ของคุณกำลังเรียกใช้รหัสจำนวนมากดังนั้นการตรวจสอบด้วยตนเองจะไม่ทำงาน เขียนโปรแกรมที่อ่านรหัส STDIN สำหรับ Brainfuck และออกด้วยสถานะการออกที่ตั้งค่าเป็นสิ่งอื่นที่ไม่ใช่ 0 (ข้อผิดพลาด) หากโปรแกรมมีข้อผิดพลาดทางไวยากรณ์ (ตัวอย่างเช่น]เป็นข้อผิดพลาดทางไวยากรณ์เนื่องจากไม่มีการจับคู่[) ออกโดยตั้งค่าสถานะการออกเป็น 0 หากโปรแกรมนั้นสมบูรณ์

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

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


1
แล้วภาษาที่ไม่อนุญาตให้ตั้งรหัสทางออกกระบวนการล่ะ
Kendall Frey

1
@KendallFrey: เรียบง่ายใช้อย่างอื่น หรือใน GolfScript ฝังโค้ด Ruby บางทีบล็อกนี้ภาษาโปรแกรมบางอย่างลึกลับ แต่ดี ...
คอนราด Borowski

1
การตั้งรหัสข้อผิดพลาดเป็นสิ่งอื่นที่ไม่ใช่ 1 (ตราบใดที่ไม่ใช่ของหลักสูตร 0) หากล้มเหลว
marinus

@marinus: ฉันไม่รู้ว่าทำไมคุณถึงต้องการมัน แต่ฉันคิดว่ามันดี
Konrad Borowski

@GlitchMr: เพราะงั้นฉันก็สามารถใช้GCD(a,b)แทน0 != a || bได้
marinus

คำตอบ:


6

GolfScript, 18 ตัวอักษร

.{[]`?)},~](`91?./

รหัสนี้ทำงานได้สำเร็จด้วยรหัสการออก 0 (และพิมพ์ขยะบางส่วนไปยัง stdout) หากเครื่องหมายวงเล็บเหลี่ยมในอินพุตมีความสมดุล หากไม่เป็นเช่นนั้นจะล้มเหลวด้วยรหัสออกที่ไม่เป็นศูนย์และพิมพ์ข้อความแสดงข้อผิดพลาดไปยัง stderr เช่น:

(eval):2:in `/': divided by 0 (ZeroDivisionError)

หรือ

(eval):1:in `initialize': undefined method `ginspect' for nil:NilClass (NoMethodError)

เนื่องจากความท้าทายไม่ได้พูดอะไรเกี่ยวกับเอาต์พุตไปยัง stdout / stderr ฉันคิดว่าสิ่งนี้มีคุณสมบัติ ในกรณีใด ๆ /dev/nullคุณสามารถเปลี่ยนเส้นทางเหล่านั้นไป

คำอธิบาย:

รหัส{[]`?)},ดึงทุกอย่างยกเว้นเครื่องหมายวงเล็บเหลี่ยมจากอินพุตและ~ประเมินผลลัพธ์เป็นโค้ด GolfScript ส่วนที่ยุ่งยากคือวงเล็บที่ไม่สมดุลนั้นสมบูรณ์แบบใน GolfScript (และแน่นอนว่ารหัสของฉันมีอยู่ด้วย!) ดังนั้นเราจึงต้องการวิธีอื่นในการทำให้รหัสพัง

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

  • หากการป้อนข้อมูลสิ้นสุดลงใน unclosed การ[พยายามย้ายองค์ประกอบออกจากอาร์เรย์ว่างจะทำให้ล่าม (ซึ่งในกรณีนี้เป็นสิ่งที่เราต้องการ!)
  • หากวงเล็บในอินพุตมีความสมดุลองค์ประกอบที่เลื่อนจะเป็นสตริงอินพุตดั้งเดิม
  • มิฉะนั้น (ถ้าอินพุตมีการเปิด]หรือไม่เปิดเผย[) มันจะเป็นอาร์เรย์

รายการ 14- char ต้นฉบับของฉันจากนั้นเปรียบเทียบค่าที่ถูกเลื่อนกับสตริงซึ่งจะล้มเหลวหากเป็นอาร์เรย์ที่ซ้อนกัน น่าเสียดายที่การเปรียบเทียบอาเรย์แบน (หรือโดยเฉพาะอย่างยิ่งว่าง) กับสตริงนั้นเป็นสิ่งที่ถูกต้องตามกฎหมายใน GolfScript ดังนั้นฉันต้องเปลี่ยนแทค

การส่งปัจจุบันของฉันแทนใช้วิธีการดุร้ายมากเพื่อบอกอาร์เรย์จากสตริง: มันยกเลิกการทำ evals และพยายามค้นหาการเกิดขึ้นครั้งแรกของ[(รหัส ASCII 91) ซึ่งจะเป็นศูนย์ถ้าและไม่ถูกยกเลิก ตัวแปรคืออาร์เรย์ ถ้าเป็นเช่นนั้นการหารศูนย์ด้วยตัวเองจะก่อให้เกิดความผิดพลาดที่ต้องการ

ps โซลูชัน 18-char อีกสองข้อคือ:

.{[]`?)},{.}%~](n<

และ

.{[]`?)},~]([n]+n<

อนิจจาฉันยังไม่พบวิธีที่สั้นกว่าในการแก้ "ปัญหาอาเรย์ว่าง"


สิ่งนี้สมดุลหรือไม่: ][(เช่นโปรแกรมของคุณล้มเหลวหรือไม่)
Justin

@Quincunx: มันล้มเหลวอย่างที่ควรจะเป็น
Ilmari Karonen

แต่ก็ไม่ได้เปิดออกมายอมรับ[[]; ตอนนี้ฉันได้ทำการแก้ไขด้วยตัวอักษร 4 ตัวและผ่านการทดสอบทั้งหมดของฉันแล้ว
Ilmari Karonen

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

@PeterTaylor: .{[]`?)},~](n<ใช่ครับมันเป็น ฉันลองของคุณ1+แล้ว แต่ดูเหมือนว่าอาเรย์จะต้องมีสิ่งอื่นที่ไม่ใช่ตัวเลข (สมมุติว่าล่ามจะล้มเหลวเมื่อพยายามเปรียบเทียบตัวละครซ้ำกับอาเรย์ / สตริง) ซ้ำ ๆ การใช้n+ไม่ทำงานอย่างใดอย่างหนึ่งเนื่องจากมัน coerces อาร์เรย์เพื่อสตริง; [n]+ ไม่ทำงาน แต่ยังคงทำให้ฉันที่ 18 ตัวอักษร
Ilmari Karonen

17

Brainfuck 76 ไบต์

>>+[<+++++++++[->---------<]+>-[--[[-]<->]<[<[->-]>[<+]<]>]<[-<+>]+>,]<<[<+]

สิ่งนี้จะออกมาจากพันธะถ้าวงเล็บสี่เหลี่ยมไม่สมดุลการเปลี่ยน bf interpreter / compiler ให้ล้มเหลวขณะรันไทม์และบางส่วนมีรหัสทางออกเพื่อสะท้อนว่า

ต้องการ eof = 0, ค่าการห่อและจำนวนเซลล์สูงสุด

ใน Ubuntu คุณสามารถใช้ล่ามbf( sudo apt-get install bf)

% echo '[[[]' | bf -n bf_matching.bf
Error: Out of range! Youwanted to '<' below the first cell.
To solve, add some '>'s at the beginning, for example.
an error occured
% echo $? 
5
% bf -n bf_matching.bf < bf_matching.bf
% echo $?
0

5
ฉันชอบวิธีที่คุณใช้ Brainfuck แม้ว่าคำถามจะบอกว่ามันเป็นไปไม่ได้
Riking

โอ้ว้าว. ฉันประหลาดใจจริงๆ ฉันคิดว่ามันเป็นไปไม่ได้ แต่ไม่ใช่
Konrad Borowski

1
@xfix: brainfuck เป็นทัวริงสมบูรณ์เพื่อที่จะสามารถทำอะไร (รับ จำกัด I / O.)
marinus

2
@marinus ทัวริงสมบูรณ์หมายความว่ามันสามารถทำการคำนวณทั้งหมด Brainfuckกำลังทำให้ทัวริงสมบูรณ์โดยไม่มี I / O เนื่องจากคุณสามารถเรียกใช้โปรแกรมที่คำนวณการคำนวณใด ๆ และดูผลลัพธ์ได้โดยการตรวจสอบหน่วยความจำหลังจากเรียกใช้ BF ที่ไม่มี I / O จะทำให้ผู้คนสนใจน้อยลงเพราะจะทำสาธารณูปโภคได้ยาก เช่นผมอาจจะไม่เคยได้ทำฉันล่ามกระเพื่อม
Sylwester

14

Befunge 98 - 26 31 20 19 ตัวอักษร

~:']-!\'[-!-+:0`j#q

กำจัดเงื่อนไขที่มีขนาดใหญ่ ตอนนี้โปรแกรมทำงานดังนี้:

~:   read an input char and duplicate it

']-! push a 1 if the char is the ] char, 0 otherwise

\    swap the comparison value for the duplicated input char

'[-! push a 1 if the char is the [ char, 0 otherwise

-    subtract the two comparison values. If the second one is 1, the first is 0, 
     so the result is -1. Else if the second one is 0, the first is 1 and the result is
     1. Else, the first and the second are both 0 and the result is 0

+    Add the number to the counter (which is 0 if there is none already)

:0`  test if the counter is positive (that'd mean an invalid program). Pushes a 1 if 
     positive, 0 otherwise.

j#q  if the counter is positive, then this jumps to the q. Otherwise, it skips the q 
     and continues to the ~ at the beginning of the line. If there are no more chars in
     the input, then the IP will be sent back to the q. 

qออกจากโปรแกรมและแสดงค่าสูงสุดเป็นค่าความผิดพลาด ค่าความผิดพลาดจะเป็น-1 1 ถ้ามีมากเกินไป]'s, 0 ถ้าพวกเขามีความสมดุลและในเชิงบวกเชิงลบหากมีมากเกินไป[' s หากจำนวนนั้นเป็นค่าลบเป็นบวกแสดงว่า]จำเป็นต้องใช้ค่าสัมบูรณ์ของจำนวนนั้นเพื่อสร้างสมดุลโปรแกรม

แก้ไข:เปลี่ยนการเพิ่มและการลดลง [ใช้เพื่อเพิ่มตัวนับและ]ใช้เพื่อลดมัน ด้วยการสลับมันฉันประหยัด 1 ถ่านเพราะสำหรับเงื่อนไขทางออกฉันต้องตรวจสอบว่าตัวนับเป็นบวกไม่ใช่เชิงลบ


เวอร์ชั่นเก่า

~:'[-!j;\1+\#;']-!j;1-#;:0\`j#q

รหัสนี้ทำงานดังต่อไปนี้:

~    read one char of input
:    duplicate it
'[-! push 1 if the character is [, 0 otherwise
j    jump that number of characters
;    skip until next ;
\1+\ increment counter

similarily for ].

#q when end of input is reached, ~ reflects the IP back. q ends the program with the error value on the stack.

แก้ไข:ตระหนักว่าอินพุตที่ยอมรับนี้เป็นเหมือน][ตอนนี้มันจะจบลงเมื่อจำนวนที่ได้รับเป็นลบโดยใช้

:0\`j


@ โจกิ้งนั้นค่อนข้างดีใช้ระยะห่างระหว่าง[และ]ทำการเปรียบเทียบกับทั้งคู่
Justin

6

J ( 38 35)

exit({:+.<./)+/\+/1 _1*'[]'=/1!:1[3

คำอธิบาย:

  • 1!:1[3: อ่าน stdin
  • '[]'=/: สร้างเมทริกซ์โดยที่แถวแรกเป็นบิตมาสค์ของ[s ในอินพุตและแถวที่สองคือ]s
  • 1 _1*: คูณแถวแรกด้วย 1 และแถวที่สองด้วย -1
  • +/: รวมคอลัมน์ของเมทริกซ์เข้าด้วยกันโดยให้การเยื้องเดลต้าต่ออักขระ
  • +/\: สร้างผลรวมทั้งหมดของการทำงานเหล่านี้ให้ระดับการเยื้องในตัวละครแต่ละตัว
  • ({:+.<./): คืน GCD ขององค์ประกอบสุดท้าย ( {:) และองค์ประกอบที่เล็กที่สุด ( <./) หากจัดฟันทั้งหมดที่ตรงกับทั้งสองเหล่านี้ควรจะดังนั้นนี้จะกลับมา0 0หากวงเล็บปีกกาไม่ตรงกันจะส่งคืนค่าที่ไม่ใช่ศูนย์
  • exit: ตั้งค่าออกไปที่และออก

รายละเอียดดี ...
คริส Cashwell

6

ทับทิม (64)

exit $<.read.tr('^[]','').tap{|x|0while x.gsub!('[]','')}.empty?

ก่อนหน้า (68) มันเป็น:

exit ARGF.read.tr('^[]','').tap{|x| 0 while x.gsub!('[]','')}.empty?

อีกโซลูชันที่เทียบเท่าใช้

exit $<.read.tr('^[]','').tap{|x|0while x.gsub!('[]','')}.size>0

ไม่สามารถใช้sizeคนเดียวได้เพราะจะให้ค่าเป็นลบเท็จ (!!!) เมื่อจำนวนรวมของวงเล็บไม่สมดุลมีค่าเท่ากับ 256


นี่คือ codegolf ฉันแน่ใจว่าคุณสามารถลบช่องว่างออกได้ที่นี่ ทับทิมเป็นช่องว่างที่ค่อนข้างอ่อนไหว แต่ก็ไม่สนใจในหลาย ๆ กรณี ในการเริ่มต้นคุณไม่ต้องการช่องว่างใกล้=ตัวดำเนินการ
Konrad Borowski

รุ่นที่ดีกว่า (ได้รับแรงบันดาลใจจากโซลูชัน sed + tr) ฉันไม่แน่ใจว่าฉันจะดีกว่านี้ได้มาก อย่างน้อยก็มีช่องว่างให้ต่ำสุด 4 ช่อง!
เขียนใหม่

1
และถึงกระนั้นฉันสามารถลบพวกเขาสองคน
Konrad Borowski

2
ฉันคิดว่าช่องว่างรอบ ๆ0สามารถไปได้
marinus

เคล็ดลับพื้นที่ที่น่ากลัวขอบคุณ!
เขียนใหม่ใน

5

Perl, 30 ตัวอักษร

Perl ขั้นพื้นฐานของคุณแบบเรียกซ้ำเพื่อช่วยเหลือ:

perl -0ne 'exit!/^(([^][]|\[(?1)\])*)$/'

สำหรับผู้ที่ไม่คุ้นเคยกับอาร์กิวเมนต์บรรทัดคำสั่งที่ใช้ที่นี่: -0อนุญาตให้หนึ่งตั้งค่าอักขระสิ้นสุดบรรทัดสำหรับวัตถุประสงค์ของอินพุตไฟล์; การใช้โดย-0ไม่มีอาร์กิวเมนต์ตั้งค่าอักขระสิ้นสุดบรรทัดเป็น EOF -nอ่านอินพุตโดยอัตโนมัติ (ในกรณีนี้ทั้งไฟล์) เข้า$_ไว้ล่วงหน้า

หาก regex ตรงกันจะส่งคืนค่าจริงซึ่งถูกส่งคืนเป็น 0 สำหรับรหัสออก มิฉะนั้นค่าส่งคืนที่ผิดจะให้รหัสการออกเป็น 1


เดาว่าฉันจะต้องตีกอล์ฟคำตอบของฉันให้ดีกว่าเพื่อเอาชนะ 30 char char
Justin

ที่นั่น โซลูชันของฉันตอนนี้สั้นกว่าเดิมมาก ทางออกที่ดี +1
Justin

4

bash (tr + sed) - 42

[ -z `tr -Cd []|sed ":a;s/\[\]//g;t a"` ]

หากคุณไม่สนใจข้อความแสดงข้อผิดพลาดคุณสามารถลบช่องว่างสุดท้ายระหว่าง`และ]เพื่อให้ได้ความยาว 41


ถ้าฉันไม่ได้พลาดอะไรคุณมีประโยชน์catและ$()(ก็"[]"สามารถเขียนเป็น[]) ฉันยอมรับคำตอบนี้ แต่จนกว่าฉันจะเห็นการปรับปรุงความยาวฉันจะไม่ลงคะแนนให้กับเรื่องนี้เพราะในขณะที่สั้น ๆ มันอาจจะสั้นลงสำหรับการทุบตี
Konrad Borowski

ที่จริงฉันไม่รู้ว่าสคริปต์ของ shell นั้นดี ฉันไม่สามารถทำงานเหล่านั้นให้ได้มากที่สุด ฉันแทนที่$()ด้วย backticks และทำ"[]"-> ที่[]คุณแนะนำ
shiona

ยังคงมีการใช้งานที่ไร้ประโยชน์ของแมว
Konrad Borowski

1
ฉันได้ดาบที่ฉันลองและล้มเหลว แต่ฉันคิดผิด
shiona

3

Perl (56 ตัวอักษร)

$/=0;$r=qr/[^][]*(\[(??{$r})\])*[^][]*/;<>=~m/^$r$/||die

โซลูชัน Perl ที่ชัดเจน: regex แบบเรียกซ้ำ น่าเสียดายที่มันเป็นโครงสร้างที่ค่อนข้างละเอียด


3

แฮสเคลล์ (143)

import System.Exit
f=exitFailure
v c []|c==0=exitSuccess|True=f
v c (s:t)|c<0=f|s=='['=v(c+1)t|s==']'=v(c-1)t|True=v c t
main=getContents>>=v 0

to jgon: การใช้ 2 guards ดูเหมือนว่าจะมีความหนาแน่นสูงกว่า if-then-else นอกจากนี้ฉันไม่คิดว่าคุณตรวจสอบว่าวงเล็บอยู่ในลำดับที่ถูกต้อง ("] [" ผ่าน)


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

3

C, 73 64 ตัวอักษร

ขอขอบคุณข้อเสนอแนะจาก breadbox (แม้ว่าอาจต้องใช้ผู้ที่มีความรู้น้อย):

i;main(c){while(read(0,&c,1)*(i+1))i+=(c==91)-(c==93);return i;}

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

  • โดยนัย int ทั่วโลก iรับค่าเริ่มต้นเป็น 0
  • c กลายเป็น int โดยนัยที่ได้รับ argc (เริ่มต้นที่ 1 แต่เราไม่สนใจตราบใดที่บิตที่สูงกว่าไม่ได้ถูกตั้งค่าไว้)
  • read(0,&c,1) อ่านอักขระหนึ่งตัวในไบต์ต่ำของ c (บนสถาปัตยกรรมแบบ end-endian) และส่งกลับค่า 0 ที่ EOF i+1 != 0นอกเสียจากว่าเครื่องหมายวงเล็บเหลี่ยมสมดุลไปถึง -1; การคูณพวกมันเข้าด้วยกันจะทำงานเป็นบูลีน (ที่ปลอดภัย) และใช้เวลาน้อยกว่าถ่านหนึ่งตัว&&
  • c==91ประเมินค่าเป็น 1 สำหรับ'['และc==93ประเมินเป็น 1 สำหรับ']'1 (อาจมีเคล็ดลับที่เล่นซอที่จะเล็ก แต่ฉันไม่สามารถคิดอะไร)
  • return iออกด้วยรหัสสถานะ 0 หากมีความสมดุลไม่เป็นศูนย์ถ้าไม่ใช่ การส่งคืน -1 เป็นการละเมิด POSIX ทางเทคนิค แต่ไม่มีใครสนใจจริง ๆ

รุ่นก่อนหน้า:

main(i){char c;i=0;while(read(0,&c,1)*(i+1))i+=(c==91)-(c==93);return i;}

การใช้getchar()แทนการอ่านจะทำให้รหัสสั้นลงและอนุญาตให้คุณใช้ (โดยปริยาย) intแทนการcharใช้ตัวแปรของคุณ โปรดจำไว้ว่า globals จะเริ่มต้นเป็นศูนย์โดยอัตโนมัติ
breadbox

ขอบคุณฉันลืมเกี่ยวกับ getchar () ไม่แน่ใจว่า init ระดับโลกช่วยได้อย่างไร - การกำหนด Global int i ใช้อักขระมากกว่าการใช้ argc หนึ่งโดยนัย
ปุย

1
ลูกโลกยังสามารถบอกเป็นนัยได้ ด้านนอกของฟังก์ชั่นc;กำหนด int ระดับโลก
breadbox

ในขณะเดียวกัน getchar (c) ก็ไม่ได้ทำให้สั้นลงอย่างน้อยก็ใช้วิธีนี้เพราะมันจะต้องมีการทดสอบ> = 0 ในบางวิธีและ int สำหรับ c ผ่านเข้าไปอ่าน () ไม่ได้รับประกัน ทำงานเนื่องจาก endianness
ปุย

เกี่ยวกับ][อะไร ฉันแน่ใจว่ามันไม่สมดุล คุณไม่ต้องติดตามว่ามันจะเป็นลบอย่างน้อยหนึ่งครั้งหรือไม่?
vsz

2

ลัวะอายุ 56 ปี

os.exit(("["..io.read"*a".."]"):match"^%b[]$"and 0 or 1)

"^%b[]$"นี่คืออะไร? คุณสามารถอธิบาย? แน่นอนว่านี่ไม่ใช่ regex?
Cruncher

@ Cruncher: มันไม่ใช่ มันเป็นลวดลาย Lua ไม่ใช่ regex (ลวดลาย Lua คล้ายกับ regexes แต่ไม่ใช่) ในกรณีนี้มันตรงกับจุดเริ่มต้นของสตริง ( ^), ชุดที่สมดุลของ[และ]กับสิ่งที่อยู่ระหว่าง ( %b[]) และจุดสิ้นสุดของสตริง ( $)
Konrad Borowski


1

คณิตศาสตร์, 88 ตัวอักษร

s = "[ [ my crazy code ] [ don't explode please! [] [ :)Ahh) ]  [] []]]";

r=StringReplace;
StringLength@FixedPoint[r[#,"[]"-> ""]&,r[s,Except@Characters["[]"]-> ""]]

ด้วยฟังก์ชั่นs name like RegularExpression` และStringLengthฉันไม่สามารถเอาชนะบริบทข้อความกอล์ฟด้วย Mathematica ได้! :)
Murta

ฉันรู้ว่าคุณหมายถึงอะไร :) ToCharacterCodeก็นานกว่าordเช่นกัน ... PS: แล้วการตั้งรหัสทางออก?
Ajasja

Length[StringCases[s,"["|"]"]//.{x___,"[","]",y___}:>{x,y}]
alephalpha

1

ทับทิม, 59 58

สแกนเพื่อเปิดและปิดวงเล็บนับ[เป็น 1 และ]เป็น -1 และออกถ้านับลดลงต่ำกว่า 0

b=0
$<.read.scan(/\]|\[/){exit 1if(b+=92-$&.ord)<0}
exit b

1
เพิ่มขึ้นและย่อให้เหลือตัวละครตัวหนึ่ง (ฉันลบช่องว่างหลังจากexit 1ในกรณีที่คุณถาม)
Konrad Borowski


1

รหัสเครื่องทัวริง, 286 276 ไบต์

อีกครั้งฉันกำลังใช้ไวยากรณ์ตารางกฎที่กำหนดไว้ที่นี่

0 * * l 1
1 _ ! r Q
5 _ _ r 5
5 * * * W
W [ ! l E
W ] ! l T
W _ _ l I
W * ! r *
E ! ! l *
E * * * R
R _ [ r O
R * * l *
T ! ! l *
T * * * Y
Y _ _ r U
Y * * l *
U [ _ r O
U ! ! * halt-err
I ! ! l *
I _ _ r halt
I * * l halt-err
O ! ! r Q
O _ _ l I
O * * r *
Q ! ! r *
Q * * * W

สิ้นสุดในสถานะhaltเพื่อรับอินพุตและhalt-errปฏิเสธ


halt-errสามารถสั้นกว่าเช่นhalt*เช่น
Erik the Outgolfer


1

แฮสเคลล์ ( 167 , 159)

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

import System.Exit
p x y b|b=x|True=y
main=getContents>>=(return.all (>=0).scanl (\v->p (v-1) (v+1).(==']')) 0.filter (`elem`"[]"))>>=p exitSuccess exitFailure

แก้ไข:แก้ไขปัญหาที่ชี้ให้ฉันในความคิดเห็น (เพิ่ม 11 ไบต์)

แก้ไข 2:สร้างฟังก์ชันเสริมสำหรับการทดสอบภาคแสดงโดยใช้ guards ที่ได้แรงบันดาลใจจากผู้ใช้ 13350 โดยลบ 8 ไบต์



@ user202729 นั่นเป็นจุดที่ยอดเยี่ยมนั่นคือความประมาท ค่อนข้างแน่ใจว่ามันได้รับการแก้ไขแล้ว
jgon

1

Stax , 14 11 ตัวอักษร

╬Äτ↔EªÉs «Ü

เรียกใช้และแก้ไขข้อบกพร่อง

เครดิตเป็น @recursive สำหรับ -3 ไบต์

ASCII เทียบเท่า:

.[]Y|&{yz|egp!

ลบอักขระทั้งหมดยกเว้น[]แล้วลบ[]จนกว่าสตริงจะไม่เปลี่ยนแปลงอีกต่อไป ส่งคืน1ถ้าสตริงสุดท้ายว่างเปล่า


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