ลดขนาด Brainfuck


22

ความท้าทายของคุณคือการย่อขนาดโค้ดBrainfuckตามกฎเหล่านี้:

  • +-><[].,อะไรที่ลบไม่ได้เป็นหนึ่ง
  • สำหรับกลุ่มที่ต่อเนื่องกัน+หรือ-ตัวอักษรใด ๆหากจำนวน+s และ-s เท่ากันให้ลบออก
  • ทำเช่นเดียวกันกับข้างต้น แต่ด้วยและ><
  • ลบลำดับของ+-><อักขระหากไม่ทำอะไรเลย +>-<->+<ตัวอย่างเช่นคุณควรลบ (นี่อาจเป็นสิ่งที่ยุ่งยากและยากที่สุดที่จะนำมาใช้) ตรวจสอบให้แน่ใจว่าคุณไม่ได้รับผลบวกที่ผิดพลาดเช่น+>-<+>-<ซึ่งไม่ควรลบออก

กรณีทดสอบ:

อินพุต

++++++[->++++++<]>.   prints a $
[-]<                  resets tape
>,[>,]<[.<]           reverses NUL terminated input string
++-->><<              does nothing

เอาท์พุต

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

อินพุต

Should disappear: ++>>+<+++<->-->-<<->-<
Should disappear: +++>-<--->+<
Should stay: +++>-<+>---<

เอาท์พุต

+++>-<+>---<

คุณอาจยอมรับอินพุตและเอาต์พุตอย่างไรก็ตามคุณต้องการ - stdin / stdout, ฟังก์ชั่น ฯลฯ แต่อินพุตอาจไม่ได้รับการเข้ารหัส

นี่คือดังนั้นรหัสที่สั้นที่สุดในการนับตัวละครจะชนะ


4
ฉันรู้ว่านี่เป็นความท้าทายที่เก่า แต่กรณีทดสอบไม่เพียงพอ ++>>++<<--ควรส่งออก>>++<<และที่ไม่ครอบคลุม โปรดเพิ่มกรณีทดสอบเพิ่มเติม
mbomb007

@ mbomb007 คุณตรวจสอบกรณีทดสอบสุดท้าย+++>-<+>---<หรือไม่ สามารถย่อให้สั้นลงเพื่อหลีกเลี่ยงการเคลื่อนไหวของตัวชี้ที่ไม่จำเป็น ความเข้าใจของฉันจากการดูทั้งคำถามและคำตอบก็คือ Doorknob นั้นเจ๋งมากกับสเป็คที่ถ่ายอย่างหลวม ๆ เราต้องกำจัดที่ต่อเนื่องกันใด ๆ -op +-><ลำดับตามที่ระบุไว้อย่างชัดเจนและเกินกว่าที่ได้รับอนุญาตในการทำการลดรูปเป็นพิเศษในตัวอย่างของคุณ++>>++<<--และเรายังสามารถทำให้การเรียบเรียงใหม่ตราบใดที่พวกเขาไม่ได้เปลี่ยนแปลงการทำงานของรหัสเช่น>+<+เข้า+>+<.
Mitch Schwartz

@MitchSchwartz "ลำดับลบของ + -.> <ตัวละครถ้าพวกเขาทำอะไรตัวอย่างเช่นคุณควรลบ+>-<->+<. (. นี้อาจจะยากและยากที่สุดในการดำเนินการอย่างใดอย่างหนึ่ง) ให้แน่ใจว่าคุณไม่ได้รับผลบวกปลอมใด ๆ เช่น+>-<+>-<, ซึ่งไม่ควรลบออก " - นี่มันคลุมเครือ
mbomb007

@ mbomb007 และสัญลักษณ์แสดงหัวข้อย่อยที่สองและที่สามซ้ำซ้อนและไม่จำเป็นเพราะพวกเขาจะรวมอยู่ในกระสุนนัดที่สี่ แล้วอะไรล่ะ มันเป็นงานที่ยอดเยี่ยม ความคิดเห็นของฉันหมายถึงสร้างสรรค์และให้ความกระจ่างไม่ใช่เพื่อโจมตีคุณ โปรดใช้วิธีที่ฉันตั้งใจไว้หรือบอกฉันว่าฉันควรพูดอย่างไร เพราะคุณไม่ได้พูดถึงสิ่งที่ฉันเขียนจริงๆ ดูเหมือนว่าคุณกำลังพยายามปกป้องตัวเองโดยที่ไม่ได้สร้างสรรค์ คุณคิดว่ามันคลุมเครือในทางใด? คุณจะเขียนมันใหม่ยังไง? คุณต้องการแก้ไขคำถามหรือไม่? คุณต้องการถาม Doorknob หรือไม่?
Mitch Schwartz

1
โอ้ดังนั้นเราจะต้องลบลำดับที่ต่อเนื่องกันเท่านั้น?
mbomb007

คำตอบ:


10

REBEL - 104

_/^_$/$</([^][<>.,+-]|\+-|-\+|<>|><)//((?<X>(<|>))+[+-]+(?!\2)(?<-X><|>)+(?(X)(?!)))([+-]+)/$3$1/.+/$>$&

การใช้งาน:

อินพุต: อ่านหนึ่งบรรทัดจาก stdin

เอาท์พุท: พิมพ์หนึ่งบรรทัดเพื่อ stdout

ความผิดปกติ *:

  • การป้อน_จะทำให้เกิดการอ่านและใช้บรรทัดอื่นแทนที่จะแสดงผลอะไร
  • การทดสอบที่สองเอาท์พุทแทน++++>----< +++>-<+>---<แต่ไม่เป็นไรใช่มั้ย ;)
  • >-<+ฯลฯ จะถูกแทนที่ด้วย+>-<ฯลฯ

สปอยเลอร์:

การใช้ความผิดปกติ # 3 ทำให้สิ่งต่าง ๆ ค่อนข้างเล็กน้อย

* มันไม่ใช่ข้อผิดพลาดมันเป็นคุณสมบัติ!


"ไม่ใช่ข้อผิดพลาดที่เป็นคุณลักษณะ" +1!
Rohan Jhunjhunwala

36

Brainfuck, 579 ไบต์

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

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

,
[
  <<+>> >>+<<
  [
    [<+> >+<-]
    ++++++[>-------<-]
    >-
    [
      not plus
      -
      [
        not comma
        -
        [
          not minus
          -
          [
            not period
            --------------
            [
              not less than
              --
              [
                not greater than
                <+++++[>------<-]>+
                [
                  not open bracket
                  --
                  [
                    not close bracket
                    <<[-]>>-
                  ]
                ]
                <
              ]
              >
              [
                greater than
                >>-<<
                <<<[-]<[<]<<<[<]
                >>>>>>>>[<]
                <-[+>]
                +[->+]
                >>>>+>[<-]
                <[>+<-<]
                >
              ]
              <
            ]
            >
            [
              less than
              <<<[-]-[<]
              >>>> >>>>>>>[<]
              <<<<<<[<]
              <-[+>]
              +[-<+]
              <<<+<[>-<<<]
              >[-<+<]
            ]
          ]
          <
        ]
        >
        [
          minus
          +>[-<]
          <[<<]
          <[-]>>
        ]
      ]
      <
    ]
    +>
    [
      plus
      -[<-]
      <[>+>+<<-<]
      <[-]>+>
    ]
    <<
    [
      comma or period or bracket
      >-
    ]
    >[,>]
    <
  ]
  comma or period or bracket or eof
  <+<
  [
    start and end same cell
    >
  ]
  >
  [
    >>>
    [
      <<<<[-<]<<<
    ]
    >>>+>>>>
    [
      start right of end
      <<<<->>>>
      [>>>[-<]>>>>]
    ]
  ]
  >
  [
    <<<
    [
      <+[-->>]
    ]
    >[-[.[-]]]
    >[<]
    >
    [
      <<++++++[>+++++++<-]>+>>
      [<<.>>-]
      <<++>-[<.>-]
      +++[<+++++>-]
      +<<<<< <+>
      [
        <<
        [
          go left
          >->>>>>.
          [[-]<<<<]
          <<<+>>>
        ]
        >
        [
          toggle left right
          ->->>>>[-]
        ]
      ]
      <
      [
        toggle right left
        ->+[>>>>>]>>[<]
        <<<<<<<<
        [
          [-]<
        ]
        >
        [
          go right
          ++.[-]
          >>>>>>>
        ]
        <
      ]
    ]
    >>
  ]
  <[>>>>>>>]
  +[-<<<<<[-]<<]
  ,
]

วิธีนี้ใช้วิธีการเดียวกับวิธีการแก้ปัญหาของ Keith Randall ซึ่งจะลดลำดับที่ต่อเนื่องทั้งหมดของ+-<>การจำลองให้เหมาะสม ยกตัวอย่างเช่น+++>-<+>---<กลายเป็น++++>----<และจะกลายเป็น>+<+<<+>+<->>>>+<+>>+>

ลองออนไลน์ (หากค่าสัมบูรณ์ของเซลล์จำลองมีค่าใกล้เคียงกับ 256 จะมีปัญหาล้น)

โครงสร้างโดยรวมคือ

while not EOF:
  while not EOF and next char not in ",.[]":
    process char
  print minified sequence (followed by the char in ",.[]" if applicable)

เทปแบ่งออกเป็นโหนด 7 เซลล์; ที่จุดเริ่มต้นของวงด้านในรูปแบบหน่วยความจำคือ

0 s 0 c 0 a b

โดยที่sแฟล็กบูลีนสำหรับเซลล์เริ่มต้นcคืออักขระปัจจุบันaเป็นส่วนลบของมูลค่าเซลล์จำลอง (บวกหนึ่ง) และbเป็นส่วนบวกของมูลค่าเซลล์จำลอง

เมื่อลำดับขั้นต่ำกำลังถูกพิมพ์รูปแบบหน่วยความจำคือ

d n e 0 0 a b

โดยที่dเป็นแฟล็กบูลีนสำหรับทิศทางaและbเป็นเหมือนก่อน (แต่จะกลายเป็นหนึ่ง / ศูนย์เมื่อพิมพ์) และnและไม่eเป็นศูนย์สำหรับโหนดสิ้นสุดเท่านั้น nเกี่ยวข้องกับจำนวนครั้งที่โหนดถูกมองเห็นและeเป็นค่าของถ่านที่หยุดวงภายใน (บวกหนึ่ง)

เดิมทีฉันพิจารณาการติดตามข้อมูลเพิ่มเติมต่อโหนด: โหนดด้านซ้ายและขวาสุดเป็นแฟล็กบูลีนและตำแหน่งของโหนดที่สัมพันธ์กับโหนดเริ่มต้นและสิ้นสุด แต่เราสามารถหลีกเลี่ยงสิ่งนั้นได้โดยดูที่เซลล์ข้างเคียงเมื่อต้องการและทำการสแกนทางซ้ายและขวาเพื่อหาจุดเริ่มต้น

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


2
ที่มา: brainfuck เป้าหมาย: brainfuck +1
Erik the Outgolfer

2
สิ่งนี้จะช่วยเติมเต็มความไม่แน่นอน
เลมอนที่ถูกทำลายได้

1
ฉันจะให้สิ่งนี้ดึงดูดความสนใจและมอบรางวัลให้ในวันหรือสองวัน
lirtosiast

1
@MitchSchwartz คุณเกิดรหัสทดสอบกับโค้ดของคุณหรือไม่ คุณอาจย่อให้สั้นลงได้จริง! #meta
WallyWest

1
@WallyWest (ที่ดูเหมือนว่าจะบันทึก 7 ไบต์!) ไม่เป็นไรรหัสใน Permalink มี linebreaks
Dennis

7

Python 404 ตัวอักษร

รหัสนี้จะเพิ่มประสิทธิภาพที่สมบูรณ์แบบของ subsequences +-<>ทั้งหมดของ มากกว่าที่คุณขอนิดหน่อย แต่คุณไป

M=lambda n:'+'*n+'-'*-n                                                           
def S(b):                                                                         
 s=p=0;t=[0];G,L='><'                                                             
 for c in b:                                                                      
  if'+'==c:t[p]+=1                                                                
  if'-'==c:t[p]-=1                                                                
  if G==c:p+=1;t+=[0]                                                             
  if L==c:s+=1;t=[0]+t                                                            
 if p<s:k=len(t)-1;t,p,s,G,L=t[::-1],k-p,k-s,L,G                                  
 r=[i for i,n in enumerate(t)if n]+[s,p];a,b=min(r),max(r);return(s-a)*L+''.join(M(n)+G for n in t[a:b])+M(t[b])+(b-p)*L                                           
s=b=''                                                                            
for c in raw_input():                                                             
 if c in'[].,':s+=S(b)+c;b=''                                                     
 else:b+=c                                                                        
print s+S(b) 

มันทำงานโดยการจำลองการดำเนินงานในเทป +-<> เป็นตำแหน่งเริ่มต้นบนเทปและเป็นตำแหน่งปัจจุบัน หลังจากการจำลองมันแสดงให้เห็นถึงขอบเขตที่ต้องดำเนินการและทำ +/- ทั้งหมดในการส่งผ่านที่ดีที่สุดเพียงครั้งเดียวtsp[a,b]


1

CoffeeScript - 403 397

i=prompt().replace /[^\]\[,.+-><]/g,''
x=(c)->
 t={};p=n=0
 for d in c
  t[p]?=0;switch d
   when'+'then n=1;t[p]++;when'-'then n=1;t[p]--;when'<'then p--;when'>'then p++
 (n=0if v!=0)for k,v of t;n
s=e=0;((e++;(i=(i.substr 0,s)+i.substr e;e=s=0)if x (i.substr s,e-s).split "")while(i[e]||0)!in['[',']',0];e=++s)while s<=i.length
r=/(\+-|-\+|<>|><|^[<>]$)/g
i=i.replace r,'' while r.test i
alert i

การสาธิต (โปรดยกโทษให้ใช้ bit.ly ที่นี่ URL ทั้งหมดจะทำให้ markdown แตกหัก)

รุ่นที่ไม่บีบอัด (รหัส w / debug):

console.clear()
input = """Should disappear: ++>>+<+++<->-->-<<->-<
Should disappear: +++>-<--->+<
Should stay: +++>-<+>---<"""

input = input.replace /[^\]\[,.+-><]/g, ''
console.log input

execute = (code) ->
  stack = {}
  item = 0
  console.log code
  nop = false
  for char in code
    switch char
      when '+' then nop = true; stack[item]?=0;stack[item]++
      when '-' then nop = true; stack[item]?=0;stack[item]--
      when '<' then item--
      when '>' then item++
  console.debug stack
  (nop = false if v != 0) for k,v of stack
  nop
start = 0
end = 0

while start <= input.length
 while input.charAt(end) not in [ '[', ']', '' ]
  end++
  if execute (input.substring start, end).split("")
    input = (input.substring 0, start) + input.substring end
    end = start = 0
    console.log input
 end = ++start
input = input.replace /(\+-|-\+|<>|><|^(<|>)$)/g, '' while /(\+-|-\+|<>|><)/.test input
console.log 'Result: ' + input

ทางเลือกของการโพสต์การสาธิต CoffeeScript คือการใช้JSFiddle ในระยะขอบด้านซ้ายมีบานหน้าต่างการตั้งค่า "ภาษา" ซึ่งช่วยให้คุณใช้ CoffeeScript แทนที่จะเป็น JS
Peter Taylor

@ PeterTaylor ขอบคุณฉันรู้เกี่ยวกับ JSFiddle มาก่อน แต่ก็ไม่สามารถใช้ CoffeeScript ได้
TimWolla

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