ตีความ /// (ออกเสียง 'ทับ')


30

เพราะเราไม่สามารถเล่นกอล์ฟที่เป็นภาษาลึกลับได้มากพอใช่ไหม?

/// - เครื่องหมายทับ - เป็นภาษาเล็ก ๆ น้อย ๆ ที่สนุกสนานตามs///ฟังก์ชั่นการแทนที่ regex ของชื่อเสียงของ Perl มันมีเพียงสองตัวละครพิเศษเฉือน/และเครื่องหมายทับขวา\เท่านั้น คุณสามารถค้นหาบทความฉบับเต็มได้ที่วิกิ esolangsแต่ฉันจะทำซ้ำคำอธิบายของภาษาด้านล่างรวมถึงตัวอย่างบางส่วน

ในระยะสั้นมันทำงานโดยระบุ/pattern/repl/restในโปรแกรมและทำการทดแทนได้หลายครั้งเท่าที่จะทำได้ ไม่มีอักขระพิเศษยกเว้น/และ\: /แบ่งเขตรูปแบบและการแทนที่ในโปรแกรมในขณะที่\ให้คุณแทรกตัวอักษร/หรือ\อักขระลงในรหัสของคุณ ยวดเหล่านี้ไม่ใช่การแสดงออกปกติเพียงทดแทนสตริงธรรมดา

ความท้าทายของคุณคือการผลิตล่ามสำหรับ /// ภาษาไม่ว่าจะเป็นโปรแกรมที่อ่าน STDIN หรือฟังก์ชั่นที่รับอาร์กิวเมนต์สตริงในตัวละครน้อยที่สุด

คุณสามารถใช้ภาษาใดก็ได้ยกเว้น /// ตัวเอง คุณไม่สามารถใช้ไลบรารีใด ๆ ที่ตีความ ///; อย่างไรก็ตามคุณสามารถใช้ไลบรารี regex, regex หรือไลบรารีที่จับคู่สตริง


การกระทำ

มีสี่รัฐมีการพิมพ์ , รูปแบบ , ทดแทนและเปลี่ยนตัว ในทุกรัฐยกเว้นการทดแทน :

  • หากโปรแกรมว่างเปล่าการทำงานจะหยุดทำงาน
  • มิฉะนั้นถ้าตัวละครตัวแรกคือ\ทำอะไรกับตัวละครต่อไป (ถ้ามี) และลบทั้งสองจากโปรแกรม
  • มิฉะนั้นถ้าอักขระตัวแรกคือ/ให้ลบออกและเปลี่ยนเป็นสถานะถัดไป
  • อื่นทำอะไรกับตัวละครตัวแรกและลบออกจากโปรแกรม
  • ทำซ้ำ

วงจรรัฐผ่านการพิมพ์ , รูปแบบ , ทดแทนและทดแทนในการสั่งซื้อ

  • ในโหมดการพิมพ์ 'ทำอะไร' หมายถึงเอาท์พุทตัวละคร
  • ในโหมดรูปแบบ 'ทำบางสิ่งบางอย่าง' หมายถึงการเพิ่มตัวละครในรูปแบบปัจจุบัน
  • ในโหมดการแทนที่ 'ทำบางสิ่ง' หมายถึงการเพิ่มตัวละครในการเปลี่ยนปัจจุบัน

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

ในโปรแกรม/foo/foobar/foo foo fooต่อไปนี้จะเกิดขึ้น:

/foo/foobar/foo foo foo
foo foo foo
foobar foo foo
foobarbar foo foo
foobarbarbar foo foo
...

สิ่งนี้จะวนซ้ำตลอดไปและไม่ออกจากโหมดการแทนที่ หากรูปแบบว่างเปล่าการเกิดขึ้นครั้งแรกของสตริงว่าง - ที่จุดเริ่มต้นของโปรแกรม - จะจับคู่เสมอดังนั้นโหมดการแทนที่จึงวนซ้ำตลอดไปไม่หยุดนิ่ง


ตัวอย่าง

no

ผลลัพธ์: no.

/ world! world!/Hello,/ world! world! world!

ผลลัพธ์: Hello, world!.

/foo/Hello, world!//B\/\\R/foo/B/\R

ผลลัพธ์: Hello, world!.

a/ab/bbaa/abb

ผลลัพธ์: a. โปรแกรมไม่หยุด

//

เอาท์พุท: ไม่มี

///

เอาท์พุท: ไม่มี โปรแกรมไม่หยุด

/\\/good/\/

ผลลัพธ์: good.

นอกจากนี้ยังมีปัญหาในวิกิที่คุณสามารถลอง


/-/World//--/Hello//--W/--, w/---!จะไม่รักอะไร (ลองลบเครื่องหมายขีดคั่นจากท้ายสุด)
seequ

@Loovjo \ ตัวละครหนีจากตัวละครที่ตามมารวมถึง/ซึ่งสามารถใช้งานได้ตามปกติในภายหลัง ขณะนี้ไม่ได้ดูชอบมากทำให้นี้ /// ทัวริงสมบูรณ์
algorithmshark

ฉันคิดว่านี่เป็นคำอธิบายภาษาที่ดีกว่าบทความของ esolangs wiki จะใช้ข้อมูลนี้ใน///IDE ของฉันที่ฉันทำ!
clabe45

คำตอบ:


7

APL (133)

{T←''∘{(0=≢⍵)∨'/'=⊃⍵:(⊂⍺),⊂⍵⋄(⍺,N⌷⍵)∇⍵↓⍨N←1+'\'=⊃⍵}⋄⍞N←T⍵⋄p N←T 1↓N⋄r N←T 1↓N⋄''≡N:→⋄∇{⍵≡p:∇r⋄∨/Z←p⍷⍵:∇(r,⍵↓⍨N+≢p),⍨⍵↑⍨N←1-⍨Z⍳1⋄⍵}1↓N}

นี่คือฟังก์ชั่นที่ใช้ ///รหัสเป็นอาร์กิวเมนต์ที่ถูกต้อง

Ungolfed พร้อมคำอธิบาย:

slashes←{
   ⍝ a function to split the input string into 'current' and 'next' parts,
   ⍝ and unescape the 'current' bit
   split←''∘{
       ⍝ if the string is empty, or '/' is reached,
       ⍝ return both strings (⍺=accumulator ⍵=unprocessed)
       (0=≢⍵)∨'/'=⊃⍵:(⊂⍺),⊂⍵
       ⍝ otherwise, add current character to accumulator,
       ⍝ skipping over '\'s. (so if '\/' is reached, it skips '\',
       ⍝ adds '/' and then processes the character *after* that.)
       idx←1+'\'=⊃⍵
       (⍺,idx⌷⍵)∇idx↓⍵
   }

   ⍞   next ← split ⍵      ⍝ output stage
   pat next ← split 1↓next ⍝ pattern stage, and eat the '/'
   rpl next ← split 1↓next ⍝ replacement stage, and eat the '/'

   ⍝ if there are no characters left, halt.
   ''≡next:⍬

   ⍝ otherwise, replace and continue.
   ∇{  ⍝ if the input string equals the pattern, return the replacement and loop
       ⍵≡pat:∇rpl

       ⍝ otherwise, find occurences, if there are, replace the first and loop
       ∨/occ←pat⍷⍵:∇(rpl, (idx+≢pat)↓⍵),⍨ (idx←(occ⍳1)-1)↑⍵

       ⍝ if no occurences, return string
       ⍵

   }1↓next
}

"ถ้าไม่มีตัวอักษรเหลือให้หยุด" ทำงานอย่างถูกต้อง///และ//foo/(เช่นวนซ้ำตลอดไป) หรือไม่
algorithmshark

@ อัลกอริทึม: ใช่ในสถานการณ์นั้น/จะยังคงอยู่ที่จุดนั้น
marinus

11

J - 181 190 170 ถ่าน

นี่เป็นฝันร้าย ฉันเขียนมันใหม่ตั้งแต่ต้นสองครั้งเพราะมันทำให้ฉันดักฟังอยู่ตลอดเวลา นี่คือฟังก์ชั่นการรับอาร์กิวเมนต์สตริงเดี่ยวซึ่งส่งออกไปยัง STDOUT

(0&$`((2{.{:@>&.>)((j{.]),-i@=`p@.~:~/@[,]}.~#@p+j=.0{p I.@E.])i 5;@}.&,'/';"0;&.>)@.(2<#)@}.[4:1!:2~{:@>@p=.>@{.@[)@((0;(0,:~1 0,.2);'\';&<1 0)<;._1@;:'/'&,)i=. ::](^:_)

เพื่ออธิบายฉันจะแยกย่อยเป็นนิพจน์ย่อย

i =. ::](^:_))
parse =: ((0;(0,:~1 0,.2);'\';&<1 0)<;._1@;:'/'&,)
print =: 4:1!:2~{:@>@p=.>@{.@[
eval  =: 0&$`((2{.{:@>&.>)sub 5;@}.&,'/';"0;&.>)@.(2<#)@}.
sub   =: ((j{.]),-i@=`p@.~:~/@[,]}.~#@p+j=.0{p I.@E.])i

interp =: (eval [ print) @ parse i
  • i(ย่อมาจากiterate ) เป็นคำวิเศษณ์ ใช้กริยาอาร์กิวเมนต์ด้านซ้ายและส่งกริยา(f)iซึ่งเมื่อนำไปใช้กับอาร์กิวเมนต์ให้ใช้fซ้ำกับอาร์กิวเมนต์จนกระทั่งเกิดสิ่งใดสิ่งหนึ่งเกิดขึ้นสองอย่าง: พบจุดคงที่ ( y = f y) หรือมีข้อผิดพลาดเกิดขึ้น ลักษณะการทำงานของจุดคงที่มีอยู่โดยธรรมชาติ^:_และ::]ทำการจัดการข้อผิดพลาด

  • parsetokenizes การป้อนข้อมูลเป็นสิ่งที่ฉันเรียกครึ่งแจงแล้วตัดมันที่ '/' ที่ไม่ใช้ค่า Escape มันเชื่อมโยงการหลบหลีกแบ็กสแลชของตัวละคร แต่ไม่สามารถกำจัดแบ็กสแลชได้ดังนั้นเราสามารถย้อนกลับหรือจบมันขึ้นอยู่กับว่าเราต้องการ

    ;:เป็นกลุ่มของการทำงานที่น่าสนใจที่เกิดขึ้นใน นี่คือตัวแปลดั้งเดิมของเครื่องตามลำดับโดยให้คำอธิบายของเครื่อง ( (0;(0,:~1 0,.2);'\';&<1 0)) ทางด้านซ้ายและบางอย่างเพื่อแยกทางด้านขวา สิ่งนี้ทำให้โทเค็น ฉันจะสังเกตเห็นว่าเครื่องจักรเฉพาะนี้ปฏิบัติกับตัวละครตัวแรกโดยเฉพาะแม้ว่ามันจะเป็น\และควรผูกมัดก็ตาม ฉันทำสิ่งนี้ด้วยเหตุผลบางประการ: (1) ตารางสถานะง่ายขึ้นดังนั้นมันจึงสามารถตีกอล์ฟต่อไปได้ (2) เราสามารถเพิ่มตัวละครจำลองที่ด้านหน้าเพื่อหลบปัญหาได้อย่างง่ายดาย และ (3) ตัวละครหุ่นจำลองครึ่งตัวโดยไม่มีค่าใช้จ่ายเพิ่มเติมดังนั้นฉันสามารถใช้มันเพื่อตั้งค่าสำหรับขั้นตอนการตัดต่อไป

    นอกจากนี้เรายังใช้<;._1เพื่อตัดผลลัพธ์โทเค็นที่ไม่ใช้ค่า Escape /(ซึ่งเป็นสิ่งที่ฉันเลือกให้เป็นอักขระตัวแรก) สิ่งนี้มีประโยชน์สำหรับการดึงเอาท์พุทรูปแบบและการแทนที่จากout/patt/repl/restทั้งหมดในขั้นตอนเดียว แต่น่าเสียดายที่ยังตัดส่วนที่เหลือของโปรแกรมที่เราต้องการ/ให้ผู้ใช้ไม่ต้องแตะต้อง ฉันประกบกันระหว่างevalนี้เพราะทำให้<;._1ทิ้งไว้คนเดียวจบลงด้วยการคิดต้นทุนมากขึ้น

  • ทางแยก(eval [ print)จะดำเนินการprintกับผลลัพธ์ที่ได้จากผลparseข้างเคียงของมันแล้วเรียกevalใช้ printเป็นกริยาง่าย ๆ ที่เปิดขึ้นในช่องแรก (อันที่เรารู้แน่นอนว่าเป็นเอาท์พุต) เสร็จสิ้นการแยกวิเคราะห์มัน pอย่างไรก็ตามเรายังใช้โอกาสที่จะกำหนดคำกริยายูทิลิตี้

    pถูกกำหนดเป็น>@{.@[ดังนั้นจึงใช้ ARG ด้านซ้ายของมัน (ทำหน้าที่เหมือนตัวตนถ้าให้ ARG เพียงอันเดียว) ใช้ไอเท็มแรกของนั้น (เอกลักษณ์เมื่อได้รับสเกลาร์) และปลดกล่องมัน subนี้จะมาในมีประโยชน์มาก

  • evalประเมินส่วนที่เหลือของโปรแกรมที่ดำเนินการ หากเราไม่มีรูปแบบเต็มรูปแบบหรือเปลี่ยนเต็มรูปแบบให้ส่งevalออกไปและเพิ่งส่งคืนรายการว่างซึ่งจะยกเลิกการประเมินโดยการทำ;:(จากparse) ข้อผิดพลาดในการทำซ้ำครั้งถัดไป อื่นอย่างเต็มที่แยกวิเคราะห์รูปแบบและเปลี่ยนแก้ไขที่เหลือของแหล่งที่มาและจากนั้นผ่านไปทั้งสองeval subจากการระเบิด:

                                                  @}.  NB. throw out printed part
                                           @.(2<#)     NB. if we have a pattern and repl:
          2{.                                          NB.  take the first two cuts:
                 &.>                                   NB.   in each cut:
             {:@>                                      NB.    drop escaping \ from chars
         (          )                                  NB.  (these are pattern and repl)
                                       &.>             NB.  in each cut:
                                      ;                NB.   revert to source form
                                '/';"0                 NB.  attach a / to each cut
                              &,                       NB.  linearize (/ before each cut)
                         5  }.                         NB.  drop '/pattern/repl/'
                          ;@                           NB.  splice together
        (            sub                  )            NB.  feed these into sub
       `                                               NB. else:
    0&$                                                NB.  truncate to an empty list
    
  • subคือบริเวณที่มีการเปลี่ยนตัวหนึ่งรอบ (ไม่สิ้นสุด) เนื่องจากวิธีที่เราตั้งค่าevalแหล่งที่มาคืออาร์กิวเมนต์ที่ถูกต้องและรูปแบบและการแทนที่ถูกรวมเข้าด้วยกันทางด้านซ้าย เนื่องจากอาร์กิวเมนต์มีการเรียงลำดับเช่นนี้และเรารู้ว่ารูปแบบและการแทนที่ไม่เปลี่ยนแปลงภายในการแทนที่หนึ่งรอบเราจึงสามารถใช้คุณลักษณะอื่นของi - ความจริงที่ว่ามันแก้ไขเฉพาะอาร์กิวเมนต์ที่ถูกต้องและส่งต่อไปทางซ้าย - เพื่อมอบหมาย ถึงเจจำเป็นต้องกังวลเกี่ยวกับการติดตามสถานะ

    แม้ว่าจะมีปัญหาสองจุด ข้อแรกคือคำกริยา J สามารถมีได้มากที่สุดสองข้อโต้แย้งดังนั้นเราจึงไม่มีวิธีง่ายๆในการเข้าถึงสิ่งที่รวมเข้าด้วยกันเช่นรูปแบบและการแทนที่ที่นี่ จากการใช้pยูทิลิตี้ที่เรากำหนดอย่างชาญฉลาดนี่ไม่ใช่ปัญหาใหญ่ ในความเป็นจริงเราสามารถเข้าถึงรูปแบบในตัวละครตัวหนึ่งเพียงแค่ใช้pเพราะความ>@{.@[หมายของมัน: Unbox ของรายการแรกของ ARG ด้านซ้าย การเปลี่ยนเป็นเรื่องหลอกลวง แต่วิธีที่สั้นที่สุดp&|.คือ 2 ตัวอักษรสั้นกว่าการลบออกด้วยตนเอง

    ปัญหาที่สองคือการiออกจากจุดคงที่แทนที่จะวนซ้ำไปตลอดกาลและถ้ารูปแบบและการแทนที่เท่ากันและคุณทำการทดแทน, ดูเหมือนว่าจุดคงที่ของ J เราจัดการเรื่องนี้โดยป้อนวนอนันต์ 1 กว่าหากเราตรวจพบว่าพวกเขามีค่าเท่ากัน: นี่คือส่วนหนึ่งแทน-i@=`p@.~:~/p&|.

                                        p    E.]    NB. string search, patt in src
                                          I.@       NB. indices of matches
                                      0{            NB. take the first (error if none)
                                   j=.              NB. assign to j for later use
                               #@p+                 NB. add length of pattern
                           ]}.~                     NB. drop that many chars from src
                       /@[                          NB. between patt and repl:
                      ~                             NB.  patt as right arg, repl as left
                  @.~:                              NB.  if equal:
            -i@=                                    NB.   loop forever
                `p                                  NB.  else: return repl
     (j{.])                                         NB. first j chars of src
           ,              ,                         NB. append all together
    (                                           )i  NB. iterate
    
  • วัฏจักรนี้ซ้ำเนื่องจากการใช้iจนกว่าจะมีบางสิ่งที่อยู่นอกsubข้อผิดพลาดหมดไป เท่าที่ฉันทราบสิ่งนี้สามารถเกิดขึ้นได้เมื่อเรามีตัวละครไม่เพียงพอเมื่อเราทิ้งชุดรูปแบบและการแทนที่ที่ไม่สมบูรณ์

ข้อเท็จจริงที่สนุกสนานเกี่ยวกับกอล์ฟนี้:

  • สำหรับหนึ่งครั้งการใช้;:จะสั้นกว่าการวนซ้ำด้วยตนเองผ่านสตริง
  • 0{ ควรมีโอกาสผิดพลาดก่อน subจะเข้าสู่วงวนไม่ จำกัด ดังนั้นจึงควรใช้งานได้ดีหากรูปแบบนั้นตรงกับการแทนที่ แต่ไม่ปรากฏในส่วนที่เหลือของแหล่งที่มา อย่างไรก็ตามสิ่งนี้อาจเป็นหรือไม่เป็นพฤติกรรมที่ไม่ระบุเนื่องจากฉันไม่สามารถหาการอ้างอิงด้วยวิธีใดวิธีหนึ่งในเอกสาร อุ๊ย
  • การขัดจังหวะของแป้นพิมพ์จะถูกประมวลผลเป็นข้อผิดพลาดที่เกิดขึ้นเองภายในฟังก์ชันที่เรียกใช้ อย่างไรก็ตามเนื่องจากลักษณะของiข้อผิดพลาดเหล่านั้นก็ถูกดักจับด้วยเช่นกัน ขึ้นอยู่กับเมื่อคุณกด Ctrl + C คุณอาจ:
    • ออกจากวงวนลบตลอดกาลข้อผิดพลาดออกจากsubวงโดยพยายามเชื่อมต่อตัวเลขกับสตริงจากนั้นดำเนินการตีความ /// ราวกับว่าคุณเสร็จสิ้นการแทนที่สตริงด้วยตัวเองจำนวนอนันต์
    • ปล่อยให้subผ่านไปครึ่งทางและไปตีความการแสดงออกครึ่ง subbed ///
    • แยกออกจากล่ามและส่งคืนโปรแกรม /// ที่ไม่ได้ประเมินค่าไปที่ REPL (ไม่ใช่ STDOUT)

ตัวอย่างการใช้งาน:

   f=:(0&$`((2{.{:@>&.>)((j{.]),-i@=`p@.~:~/@[,]}.~#@p+j=.0{p I.@E.])i 5;@}.&,'/';"0;&.>)@.(2<#)@}.[4:1!:2~{:@>@p=.>@{.@[)@((0;(0,:~1 0,.2);'\';&<1 0)<;._1@;:'/'&,)i=. ::](^:_)
   f 'no'
no
   f '/ world! world!/Hello,/ world! world! world!'
Hello, world!
   f '/foo/Hello, world!//B\/\\R/foo/B/\R'
Hello, world!
   f '//'  NB. empty string

   f '/\\/good/\/'
good

ว้าว. ฉันจะเรียกสิ่งนี้ว่าร้าย +1
seequ

เมื่อฉันเรียกใช้งานนี้ฉันจะได้รับสตริงว่างจากทุกกรณีทดสอบ ฉันใช้ jqt64 คุณใช้อะไรเพื่อเรียกใช้งานนี้
bcsb1001

@ bcsb1001 ฉันใช้ไบนารี jconsole (64 บิต) โดยตรง การตรวจสอบ jqt ตอนนี้ฉันได้รับผลลัพธ์ตามจริงแล้วยกเว้น/\\/good/\/กรณีทดสอบ การดีบักบอกฉันว่าปัญหาคือสิ่งที่ฉันใช้1!:2&4เนื่องจาก jqt ไม่มี stdin / out จะทำการสอบสวน คุณ9!:12''และ9!:14''อะไร
algorithmshark

@algorithmshark My 9!:12''is 6 และ9!:14''is j701 / 2011-01-10 / 11: 25
bcsb1001

4

Perl - 190

$|=1;$/=undef;$_=<>;while($_){($d,$_)=/(.)(.*)/;eval(!$e&&({'/','$a++','\\','$e=1'}->{$d})||('print$d','$b.=$d','$c.=$d')[$a].';$e=0');if($a==3){while($b?s/\Q$b/$c/:s/^/$c/){}$a=0;$b=$c=''}}

อ่าน///โปรแกรมจาก stdin จนกระทั่ง EOF


วิธีการตามแนวของm/^(.*?)(?<!\\)\/(.*?)(?<!\\)\/(.*?)(?<!\\)\/(.*)$/s--ie จับคู่เอาท์พุตรูปแบบและการเปลี่ยนทั้งหมดในครั้งเดียว - ทำให้กอล์ฟสั้นลงหรือไม่ ฉันไม่รู้ Perl ใด ๆ เลย
algorithmshark

ฉันเชื่อว่าสิ่งนี้ล้มเหลวด้วย/a/\0/a
Asone Tuhid

3

Pip , 100 102 ไบต์

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

รหัส 101 ไบต์ +1 สำหรับการ-rตั้งค่าสถานะ:

i:gJnf:{a:xW#i&'/NE YPOia.:yQ'\?POiya}W#iI'\Q YPOiOPOiEIyQ'/{p:VfY0s:VfIyQ'/WpNi&YviR:Xp{++y?ps}}E Oy

นี่คือเวอร์ชั่นที่ฉันไม่ได้แสดงความคิดเห็นมากมาย:

; Use the -r flag to read the /// program from stdin
; Stdin is read into g as a list of lines; join them on newline and assign to c for code
c : gJn

; Loop while c is nonempty
W #c {
 ; Pop the first character of c and yank into y
 Y POc
 ; If y equals "\"
 I yQ'\
  ; Pop c again and output
  O POc
 ; Else if y equals "/"
 EI yQ'/ {
  ; Build up pattern p from empty string
  p : ""
  ; Pop c, yank into y, loop while that is not equal to "/" and c is nonempty
  W #c & '/ NE Y POc {
   ; If y equals "\"
   I yQ'\
    ; Pop c again and add that character to p
    p .: POc
   ; Else, add y to p
   E p .: y
  }

  ; Yank 0 so we can reliably tell whether the /// construct was completed or not
  Y0
  ; Build up substitution s from empty string
  s : ""
  ; Pop c, yank into y, loop while that is not equal to "/" and c is nonempty
  W #c & '/ NE Y POc {
   ; If y equals "\"
   I yQ'\
    ; Pop c again and add that character to s
    s .: POc
   ; Else, add y to s
   E s .: y
  }

  ; If the last value yanked was "/", then we have a complete substitution
  ; If not, the code must have run out; skip this branch, and then the outer loop
  ; will terminate
  I yQ'/ {
   ; While pattern is found in code:
   W pNc {
    ; Set flag so only one replacement gets done
    i : 0
    ; Convert p to a regex; replace it using a callback function: if ++i is 1,
    ; replace with s; otherwise, leave unchanged
    c R: Xp {++i=1 ? s p}
   }
  }
 }
 ; Else, output y
 E Oy
}

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


ฉันคิดว่าน่าจะเป็นpip + -r101 ไบต์
Asone Tuhid

3

C ++: Visual C ++ 2013 = 423, g ++ 4.9.0 = 442

สิ่งนี้จะไม่มีวันชนะ แต่เนื่องจากฉันได้ตัดสินใจว่าโครงการซอฟต์แวร์ในอนาคตของฉันทั้งหมดจะถูกเขียนในภาษาที่ยอดเยี่ยมนี้ฉันต้องการผู้บุกรุกและฉันคิดว่าฉันอาจแบ่งปันสิ่งที่ฉันทำ ...

ความแตกต่างของคะแนนคือ Visual C ++ ไม่จำเป็นต้องรวมก่อน แต่ g ++ คะแนนสมมติว่าการสิ้นสุดของบรรทัดนับเป็น 1

#include<string.h>
#include<string>
#define M(x)memset(x,0,99);
#define P o[i])
#define N(x)P;else if(n<x)(P==92?
#define O (o[++i]):(P==47?n++:
#define S std::string
int main(int n,char**m){S o=m[1];char p[99],*q=p,r[99],*s=r;M(p)M(r)for(int i=0,t;i<=o.size();++i){if(!N(3)putchar O putchar(N(4)*q++=O(*q++=N(5)*s++=O(*s++=P;if(n>4){for(;;){if((t=o.find(p,i+1))==S::npos)break;o=o.substr(0,t)+r+o.substr(t+strlen(p));}M(p)M(r)n=2;q=p;s=r;}}}

1
คุณสามารถเขียนif(!o[i]);เป็นif(Pเพื่อบันทึกตัวอักษรหรือฉันเข้าใจผิดว่า #define ทำงานอย่างไร
algorithmshark

@ อัลกอริทึมฉันจะทำพลาดอย่างไร! ถ้า (! P สมบูรณ์แบบฉันจะเปลี่ยนมัน
Jerry Jeremiah

ตัวอย่างของทุกคนPในมีพื้นที่หลังจากที่มันเพื่อให้คุณสามารถบันทึกตัวอักษรโดยการแทนที่ช่องว่างเหล่านั้นด้วยเครื่องหมายอัฒภาคและลบออกจากmain #defineแล้วถ้าคุณสามารถใช้#defineอยู่ข้างคนอื่น ๆ คุณสามารถบันทึกบางมากขึ้นโดยการเขียนใหม่N(x)เป็น(92==Pแทนo[i]==92และOในทำนองเดียวกัน
algorithmshark

@ อัลกอริธึมเห็นได้ชัดว่าคุณดีกว่าฉันมากกว่านี้ขอบคุณสำหรับความช่วยเหลือ
Jerry Jeremiah

ฉันรู้ว่านี้คืออายุประมาณสี่ปี แต่เขียนN(x)เป็นP;else if(n<x)(P==92?และการเปลี่ยนแปลงการโทรไปNตามจะสามารถประหยัดไม่กี่ไบต์
Zacharý

2

Python 2 (236), Python 3 (198?)

from __future__ import print_function
def d(i):
 t=0;p=['']*3+[1]
 while i:
  if'/'==i[0]:t+=1
  else:
   if'\\'==i[0]:i=i[1:]
   p[t]+=i[0]
  i=i[1:]
  print(end=p[0]);p[0]=''
  if t>2:
   while p[1]in i:i=i.replace(*p[1:])
   d(i);i=0

d(r"""/foo/Hello, world!//B\/\\R/foo/B/\R""")เรียกว่าเป็น การเสนอราคาแบบสามครั้งจำเป็นสำหรับ///โปรแกรมที่มีการขึ้นบรรทัดใหม่เท่านั้น: ไม่เช่นนั้นการเสนอราคาแบบง่าย ๆ ก็โอเค

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


ล่ามไม่พิมพ์สิ่งใดจนกว่าการยกเลิกจะเป็นปัญหา การเขียนวงวนไม่สิ้นสุดใน /// เป็นไปได้ดังนั้นล่ามของคุณจึงล้มเหลวในโปรแกรมบางอย่างที่ไม่สิ้นสุด แต่ยังคงพิมพ์
ภูมิใจ Haskeller

@proudhaskeller แก้ไขแล้ว
Bruno Le Floch

ที่จริงแล้วมันไม่ได้รับการแก้ไข แต่ไม่ได้พิมพ์อะไร/a/ab/bbaa/abbเลย
Beta Decay

@BetaDecay /a/ab/bbaa/abbจะได้รับการติดอยู่ในวงไม่มีที่สิ้นสุดโดยไม่ต้องพิมพ์อะไรเพราะการเปลี่ยนตัวผู้เล่นเป็นครั้งแรก=>a งานที่abถูกต้องa/ab/bbaa/abbตามที่โฆษณาไว้
algorithmshark

@BetaDecay: นอกเหนือจากการเปลี่ยนแปลงที่แนะนำโดย algorithmshark แล้วคุณอาจต้องรวมตัวเลือกบรรทัดคำสั่ง-uเพื่อบังคับให้บัฟเฟอร์เอาต์พุตไม่ถูกบัฟเฟอร์
Bruno Le Floch

2

คอบร้า - 226

sig Z as String
def f(l='')
    m=Z(do=[l[:1],l=l[1:]][0])
    n as Z=do
        if'/'<>(a=m())>'',return if(a=='\\',m(),a)+n()
        else,return''
    print n()stop
    p,s=n(),n()
    if''<l
        while p in l,l=l[:l.indexOf(p)+1]+s+l[p.length:]
        .f(l)

2

ทับทิม , 119 110 ไบต์

สิ้นสุดด้วยข้อยกเว้น

r=->s,o=$>{s[k=s[0]]='';k==?/?o==$>?s.gsub!([r[s,''],e=r[s,'']][0]){e}:t=o:o<<(k==?\\?s[0]+s[0]='':k);t||redo}

ลองออนไลน์!

สิ้นสุดอย่างเรียบร้อย (116 ไบต์)

r=->s,o=$>{s[k=s[0]||exit]='';k==?/?o==$>?s.gsub!([r[s,''],e=r[s,'']][0]){e}:t=o:o<<(k==?\\?s[0]+s[0]='':k);t||redo}

ลองออนไลน์!


1

Python 2/3 (211 ไบต์)

รหัสต่อไปนี้ตามคำตอบของ Bruno Le Flochคือรองรับ Python 2 และ Python 3

ยิ่งไปกว่านั้นการทำซ้ำมากกว่าการเรียกซ้ำมันไม่เสี่ยงที่จะกดปุ่ม Python ซ้ำ

def S(c):
 while c:
  B=["","",1]
  for m in 0,1,2:
   while c:
    if"/"==c[0]:c=c[1:];break
    if"\\"==c[0]:c=c[1:]
    if m:B[m-1]+=c[0]
    else:yield c[0]
    c=c[1:]
  while c and B[0]in c:c=c.replace(*B)

สวัสดีและยินดีต้อนรับสู่ PPCG คุณสามารถกอล์ฟin(0,1,2)ไปin 0,1,2และ[""]*2+[1]จะ["","",1]ส่งผลให้ใน211 ไบต์
Jonathan Frech

ฉันเชื่อมโยงกับคำตอบที่อ้างถึงและเพิ่มคำว่า "ไบต์" หากคุณไม่เห็นด้วยกับการแก้ไขของฉันคุณสามารถย้อนกลับได้
Jonathan Frech

ขอบคุณโจนาธานคำแนะนำของคุณยินดีต้อนรับอย่างมาก!
Carlos Luna

0

เบคอน , 391 387 395 ไบต์

จากการมีส่วนร่วมในหน้านี้ฉันมีโปรแกรม Python ให้ใช้งานเท่านั้น ส่วนอื่น ๆ ใช้ได้กับตัวอย่าง //// บางตัวหรือไม่ทำงานเลย ดังนั้นฉันตัดสินใจเพิ่มเวอร์ชันของฉันซึ่งเป็นการนำไปใช้ในภาษาเบสิก

การแข่งขันในการแข่งขัน CodeGolf กับ BASIC นั้นไม่ใช่เรื่องง่ายเนื่องจาก BASIC ใช้คำที่ยาวเป็นคำพูด ตัวย่อที่พบได้ทั่วไปใน BASIC คือ '?' เครื่องหมายซึ่งหมายความว่า PRINT

ดังนั้นด้านล่างโปรแกรมอาจจะไม่เคยชนะ แต่อย่างน้อยก็ทำงานร่วมกับรหัสการสาธิตทั้งหมดในหน้า Codegolf นี้และในEsolangs วิกิพีเดีย รวมถึง "99 ขวดเบียร์ทุกรุ่น"

p$=""
r$=""
INPUT i$
WHILE LEN(i$)
t$=LEFT$(i$,1)
i$=MID$(i$,2)
IF NOT(e) THEN
IF t$="\\" THEN
e=1
CONTINUE
ELIF t$="/" THEN
o=IIF(o<2,o+1,0)
IF o>0 THEN CONTINUE
FI
FI
IF o=1 THEN
p$=p$&t$
ELIF o=2 THEN
r$=r$&t$
ELIF o=0 THEN
IF LEN(p$) THEN i$=REPLACE$(i$,p$,r$)
IF NOT(INSTR(t$&i$,"/")) THEN
?t$;
BREAK
ELSE
?LEFT$(i$,INSTR(i$,"/")-1);
i$=MID$(i$,INSTR(i$,"/"))
FI
p$=""
r$=""
FI
e=0
WEND
?i$

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