Phiên dịch /// (phát âm là 'dấu gạch chéo')


30

Bởi vì chúng ta không thể có đủ các sân golf ngôn ngữ bí truyền, phải không?

/// - chém phát âm là một ngôn ngữ nhỏ vui nhộn dựa trên s///chức năng thay thế regex của danh tiếng Perl. Nó chỉ chứa hai ký tự đặc biệt, dấu gạch chéo /và dấu gạch chéo ngược \. Bạn có thể tìm thấy một bài viết đầy đủ về nó tại wiki esolang , nhưng tôi sẽ sao chép một mô tả về ngôn ngữ dưới đây, cũng như một số ví dụ.

Nói tóm lại, nó hoạt động bằng cách xác định /pattern/repl/resttrong chương trình và thực hiện thay thế nhiều lần nhất có thể. Không có ký tự nào đặc biệt ngoại trừ /\: /phân định các mẫu và thay thế trong chương trình, trong khi \cho phép bạn chèn chữ /hoặc \ký tự vào mã của mình. Đáng chú ý, đây không phải là biểu thức chính quy, chỉ là sự thay thế chuỗi đơn giản.

Thách thức của bạn là tạo ra một trình thông dịch cho ngôn ngữ ///, vì một chương trình đọc STDIN hoặc một hàm lấy một đối số chuỗi, càng ít ký tự càng tốt.

Bạn có thể sử dụng bất kỳ ngôn ngữ nào ngoại trừ ///. Bạn không được sử dụng bất kỳ thư viện nào diễn giải ///; tuy nhiên, bạn có thể sử dụng regexes, thư viện regex hoặc thư viện khớp chuỗi.


Chấp hành

Có bốn trạng thái, in , mẫu , thay thếthay thế . Ở mọi tiểu bang ngoại trừ thay thế :

  • Nếu chương trình trống, thực thi tạm dừng.
  • Khác, nếu nhân vật đầu tiên là \, làm một cái gì đó với nhân vật tiếp theo (nếu có) và loại bỏ cả hai khỏi chương trình.
  • Khác, nếu ký tự đầu tiên là /, loại bỏ nó, và thay đổi sang trạng thái tiếp theo.
  • Khác, làm một cái gì đó với nhân vật đầu tiên và loại bỏ nó khỏi chương trình.
  • Nói lại.

Các trạng thái chu kỳ thông qua in , mẫu , thay thếthay thế theo thứ tự.

  • Trong chế độ in , 'làm điều gì đó' có nghĩa là xuất ký tự.
  • Trong chế độ mẫu , 'làm điều gì đó' có nghĩa là thêm ký tự vào Mẫu hiện tại.
  • Trong chế độ thay thế , 'làm điều gì đó' có nghĩa là thêm ký tự vào Thay thế hiện tại.

Trong chế độ thay thế , bạn tuân theo một bộ quy tắc khác. Liên tục thay thế lần xuất hiện đầu tiên của Mẫu hiện tại bằng Thay thế hiện tại trong chương trình, cho đến khi không thể thay thế nữa. Tại thời điểm đó, xóa Mẫu và Thay thế và trở về chế độ in .

Trong chương trình /foo/foobar/foo foo foo, những điều sau đây xảy ra:

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

Vòng lặp này mãi mãi và không bao giờ thoát khỏi chế độ thay thế . Tương tự, nếu Mẫu trống, thì lần xuất hiện đầu tiên của chuỗi rỗng ở đầu chương trình, luôn luôn khớp, do đó, chế độ thay thế lặp lại mãi mãi, không bao giờ dừng lại.


Ví dụ

no

Đầu ra : no.

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

Đầu ra : Hello, world!.

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

Đầu ra : Hello, world!.

a/ab/bbaa/abb

Đầu ra : a. Chương trình không dừng lại.

//

Đầu ra: không có.

///

Đầu ra: không có. Chương trình không dừng lại.

/\\/good/\/

Đầu ra : good.

Ngoài ra còn có một quine trên wiki bạn có thể thử.


/-/World//--/Hello//--W/--, w/---!Không yêu là gì? (Thử xóa dấu gạch ngang từ cuối)
seequ

@Loovjo Nhân \ vật thoát khỏi bất kỳ nhân vật nào theo sau nó, bao gồm /, sau này có thể được sử dụng như bình thường. Mặc dù điều này trông không giống lắm, nhưng điều này làm cho /// Turing-Complete .
thuật toán

Tôi nghĩ rằng đây là một lời giải thích tốt hơn về ngôn ngữ so với bài viết wiki esolang. Sẽ sử dụng thông tin này trong ///IDE của tôi mà tôi đang thực hiện!
clabe45

Câu trả lời:


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}

Đây là một hàm lấy ///mã làm đối số đúng của nó.

Ungolfed, với lời giải thích:

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
}

"nếu không còn ký tự, dừng lại." Điều này có hoạt động chính xác trên /////foo/(tức là vòng lặp mãi mãi)?
thuật toán

@alerskymshark: có, trong tình huống /đó vẫn sẽ bị bỏ lại tại thời điểm đó.
bến tàu

11

J - 181 190 170 char

Đây là một cơn ác mộng. Tôi viết lại từ đầu, hai lần, bởi vì nó cứ làm phiền tôi. Đây là một hàm lấy một đối số chuỗi đơn, xuất ra 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=. ::](^:_)

Để giải thích, tôi sẽ chia nó thành các phần phụ.

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(viết tắt của iterate ) là một trạng từ. Nó nhận một đối số động từ ở bên trái và trả về một động từ (f)i, khi được áp dụng cho một đối số, áp dụng flặp lại cho đối số cho đến khi một trong hai điều xảy ra: nó tìm thấy một điểm cố định ( y = f y) hoặc nó ném lỗi. Hành vi điểm cố định vốn có ^:_::]xử lý lỗi.

  • parsemã hóa đầu vào thành dạng mà tôi gọi dạng được phân tích một nửa , và sau đó cắt nó ở dạng '/' không được giải mã. Nó liên kết thoát các dấu gạch chéo ngược đến các ký tự của chúng, nhưng không thoát khỏi dấu gạch chéo ngược, vì vậy chúng ta có thể hoàn nguyên nó hoặc hoàn thành nó tùy theo ý muốn.

    Phần lớn các công việc thú vị xảy ra trong ;:. Đây là một trình thông dịch máy tuần tự nguyên thủy, lấy một mô tả về máy ( (0;(0,:~1 0,.2);'\';&<1 0)) ở bên trái và một cái gì đó để phân tích ở bên phải. Điều này không tokenizing. Tôi sẽ lưu ý rằng cỗ máy cụ thể này thực sự đối xử với nhân vật đầu tiên không đặc biệt, ngay cả khi đó là một \và nên ràng buộc. Tôi làm điều này vì một vài lý do: (1) bảng trạng thái đơn giản hơn, vì vậy nó có thể được đánh gôn hơn nữa; (2) chúng ta có thể dễ dàng thêm một nhân vật giả vào phía trước để tránh vấn đề; và (3) nhân vật giả đó được phân tích cú pháp một nửa mà không mất thêm chi phí, vì vậy tôi có thể sử dụng nó để thiết lập cho giai đoạn cắt, tiếp theo.

    Chúng tôi cũng sử dụng <;._1để cắt kết quả tokenized trên unescted /(đó là những gì tôi chọn là char đầu tiên). Điều này rất thuận tiện để rút đầu ra, mẫu và thay thế từ out/patt/repl/resttất cả trong một bước, nhưng không may cũng cắt giảm phần còn lại của chương trình, nơi chúng ta cần những thứ đó /không bị ảnh hưởng. Tôi ghép chúng lại trong suốt eval, bởi vì làm cho <;._1chúng một mình cuối cùng tốn kém hơn rất nhiều.

  • Cái ngã ba (eval [ print)thực hiện printtrên kết quả từ parsecác tác dụng phụ của nó, và sau đó chạy eval. printlà một động từ đơn giản mở ra hộp đầu tiên (cái mà chúng ta biết chắc chắn là đầu ra), hoàn thành phân tích cú pháp và gửi nó đến STDOUT. Tuy nhiên, chúng tôi cũng tận dụng cơ hội để xác định một động từ tiện ích p.

    pđược định nghĩa là >@{.@[, do đó, nó lấy đối số bên trái của nó (hoạt động giống như danh tính nếu chỉ được cung cấp một đối số), lấy mục đầu tiên của điều đó (danh tính khi được cung cấp vô hướng) và bỏ hộp thư (danh tính nếu đã được bỏ hộp). Điều này sẽ đến rất tiện dụng trong sub.

  • evalđánh giá phần còn lại của chương trình được xử lý. Nếu chúng ta không có một mẫu đầy đủ hoặc một sự thay thế hoàn toàn, hãy evalném nó ra và chỉ trả về một danh sách trống, điều này chấm dứt việc đánh giá bằng cách đưa ra ;:(từ parse) lỗi trong lần lặp tiếp theo. Khác, evalphân tích đầy đủ các mẫu và thay thế, sửa phần còn lại của nguồn, và sau đó chuyển cả hai sang sub. Bằng vụ nổ:

                                                  @}.  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
    
  • sublà nơi xảy ra một vòng (có thể là vô hạn). Do cách chúng tôi thiết lập eval, nguồn là đối số đúng và mẫu và thay thế được gói cùng nhau ở bên trái. Vì các đối số được sắp xếp như thế này và chúng tôi biết mô hình và sự thay thế không thay đổi trong một vòng thay thế, nên chúng tôi có thể sử dụng một tính năng khác của isự thật là nó chỉ sửa đổi đối số bên phải và tiếp tục chuyển sang cùng một bên trái để ủy quyền để J cần phải lo lắng về việc theo dõi trạng thái.

    Có hai điểm rắc rối, mặc dù. Đầu tiên là các động từ J có thể có nhiều nhất hai đối số, vì vậy chúng ta không có cách dễ dàng để truy cập bất kỳ cụm từ nào được gói lại với nhau, như mẫu và thay thế, ở đây. Thông qua việc sử dụng thông minh các ptiện ích mà chúng tôi đã xác định, đây không phải là vấn đề lớn. Trong thực tế, chúng ta có thể truy cập vào mẫu trong một ký tự, chỉ bằng cách sử dụng p, vì >@{.@[định nghĩa của nó : Unbox của mục đầu tiên của đối số bên trái. Nhận được sự thay thế là khó khăn hơn, nhưng cách ngắn nhất sẽ là p&|., 2 ký tự ngắn hơn so với việc lấy nó ra bằng tay.

    Vấn đề thứ hai là ithoát ra trên các điểm cố định thay vì lặp đi lặp lại mãi mãi, và nếu mô hình và sự thay thế bằng nhau và bạn thay thế, nó trông giống như một điểm cố định với J. Chúng tôi xử lý điều này bằng cách nhập một vòng lặp vô hạn phủ định 1 và hơn nếu chúng tôi phát hiện chúng bằng nhau: đây là -i@=`p@.~:~/phần, thay thế 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
    
  • Chu kỳ này lặp lại do việc sử dụng i, cho đến khi có sublỗi bên ngoài. Theo như tôi biết, điều này chỉ có thể xảy ra khi chúng ta không có nhân vật, khi chúng ta đưa ra một bộ mẫu và thay thế không hoàn chỉnh.

Sự thật thú vị về môn đánh gôn này:

  • Đối với một lần, sử dụng ;:ngắn hơn so với lặp thủ công thông qua chuỗi.
  • 0{nên có cơ hội để lỗi trước khi subđi vào một vòng lặp vô hạn, vì vậy nó sẽ hoạt động tốt nếu mẫu phù hợp với sự thay thế nhưng không bao giờ xuất hiện trong phần còn lại của nguồn. Tuy nhiên, điều này có thể hoặc không thể là hành vi không xác định, vì tôi không thể tìm thấy một trích dẫn nào trong các tài liệu. Rất tiếc.
  • Ngắt bàn phím được xử lý như lỗi tự phát bên trong các chức năng đang chạy. Tuy nhiên, do bản chất của i, những lỗi đó cũng bị mắc kẹt. Tùy thuộc vào thời điểm bạn nhấn Ctrl + C, bạn có thể:
    • Thoát khỏi vòng lặp phủ định mãi mãi, lỗi ra khỏi subvòng lặp bằng cách thử nối một số thành một chuỗi, sau đó tiếp tục diễn giải /// như thể bạn đã thay thế một chuỗi bằng chính số lần vô hạn.
    • Để lại submột nửa và tiếp tục diễn giải một biểu thức /// nửa chìm.
    • Thoát ra khỏi trình thông dịch và trả lại chương trình /// không được đánh giá cho REPL (mặc dù không phải STDOUT).

Ví dụ sử dụng:

   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

Ồ Tôi sẽ gọi đây là khổ dâm. +1
xem

Khi tôi chạy cái này, tôi nhận được chuỗi rỗng từ mọi trường hợp thử nghiệm. Tôi đang sử dụng jqt64, bạn đang sử dụng cái gì để chạy cái này?
bcsb1001

@ bcsb1001 Tôi đã trực tiếp sử dụng nhị phân jconsole (64-bit). Kiểm tra jqt bây giờ, tôi thực sự nhận được kết quả dự định ngoại trừ /\\/good/\/trường hợp thử nghiệm; gỡ lỗi cho tôi biết vấn đề là do tôi sử dụng 1!:2&4, vì jqt không có stdin / out. Sẽ điều tra. Bạn là gì 9!:12''9!:14''?
thuật toán

@alerskymshark My 9!:12''là 6 và 9!:14''là 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=''}}

Đọc ///chương trình từ stdin cho đến EOF.


Liệu một cách tiếp cận dọc theo các dòng m/^(.*?)(?<!\\)\/(.*?)(?<!\\)\/(.*?)(?<!\\)\/(.*)$/s--ie khớp đầu ra, mô hình và thay thế tất cả cùng một lúc - sẽ tạo ra một sân golf ngắn hơn? Tôi không biết bất kỳ Perl, bản thân mình.
thuật toán

Tôi tin rằng điều này thất bại với/a/\0/a
Asone Tuhid

3

Pip , 100 102 byte

Tôi chưa bao giờ chứng minh Pip là Turing-perfect (mặc dù nó khá rõ ràng) và thay vì đi theo con đường BF thông thường, tôi nghĩ /// sẽ rất thú vị. Khi tôi đã có giải pháp, tôi nghĩ rằng tôi sẽ chơi nó và đăng nó ở đây.

101 byte mã, +1 cho -rcờ:

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

Đây là phiên bản vô văn hóa của tôi với nhiều bình luận:

; 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
}

Hãy thử trực tuyến! (Lưu ý rằng TIO không cung cấp bất kỳ đầu ra nào khi chương trình không kết thúc và nó cũng có giới hạn thời gian. Đối với các ví dụ lớn hơn và các vòng lặp vô hạn, nên chạy Pip từ dòng lệnh.)


Tôi nghĩ rằng điều này nên là pip + -r, 101 byte
Asone Tuhid

3

C ++: Trực quan C ++ 2013 = 423, g ++ 4.9.0 = 442

Điều này sẽ không bao giờ chiến thắng nhưng vì tôi đã quyết định rằng tất cả các dự án phần mềm trong tương lai của tôi sẽ được viết bằng ngôn ngữ tuyệt vời này, tôi cần một người hướng dẫn cho nó và tôi nghĩ rằng tôi cũng có thể chia sẻ dự án tôi đã thực hiện ...

Sự khác biệt về điểm số là Visual C ++ không cần bao gồm đầu tiên nhưng g ++ thì không. Điểm số giả định rằng kết thúc dòng được tính là 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
Bạn có thể viết lại if(!o[i]);như if(Pđể lưu ký tự không, hoặc tôi hiểu nhầm cách #define hoạt động?
thuật toán

@alerskymshark làm thế nào tôi bỏ lỡ điều đó?! if (! P là hoàn hảo. Tôi sẽ thay đổi nó.
Jerry Jeremiah

Mỗi phiên bản Pin maincó một khoảng trắng sau nó, vì vậy bạn có thể lưu một ký tự bằng cách thay thế các khoảng trắng đó bằng dấu chấm phẩy và xóa nó khỏi #define. Sau đó, nếu bạn có thể sử dụng #definecủa bên người khác, bạn có thể tiết kiệm một số chi tiết bằng cách viết lại N(x)như (92==Pthay vì o[i]==92Otương tự như vậy.
thuật toán

@alerskymshark bạn rõ ràng là tốt hơn nhiều so với tôi. Cảm ơn vì sự giúp đỡ.
Jerry Jeremiah

Tôi biết đây là khoảng bốn tuổi, nhưng viết lại N(x)như P;else if(n<x)(P==92?và thay đổi các cuộc gọi đến Nphù hợp có thể tiết kiệm một vài byte.
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

Gọi là d(r"""/foo/Hello, world!//B\/\\R/foo/B/\R"""). Dấu ngoặc kép chỉ cần thiết nếu ///chương trình chứa dòng mới: nếu không thì trích dẫn đơn giản là ok.

EDIT: Trình thông dịch này hiện in các nội dung như mong đợi (trước đây nó chỉ được in ở cuối, nhận xét). Đối với Python 3, hãy xóa dòng đầu tiên (nhưng tôi không có Python 3 trên bản cài đặt cũ của mình, vì vậy không thể chắc chắn không có thay đổi nào khác).


thông dịch viên không in bất cứ điều gì cho đến khi chấm dứt là có vấn đề. viết một vòng lặp vô hạn trong /// là có thể, do đó trình thông dịch của bạn thất bại trong các chương trình không kết thúc-nhưng-vẫn-in-một cái gì đó.
tự hào

@proudhaskeller Đã sửa.
Bruno Le Floch

Trên thực tế, điều này không cố định, nó không in bất cứ điều gì cho /a/ab/bbaa/abb.
Beta Decay

@BetaDecay /a/ab/bbaa/abbsẽ bị kẹt trong một vòng lặp vô tận mà không in bất cứ điều gì, bởi vì sự thay thế đầu tiên là a=> ab. Các a/ab/bbaa/abbcông việc chính xác như quảng cáo.
thuật toán

@BetaDecay: bên cạnh thay đổi được đề xuất bởi thuật toán, bạn có thể cần bao gồm tùy chọn dòng lệnh -uđể buộc bộ đệm đầu ra không bị chặn.
Bruno Le Floch

2

Rắn hổ mang - 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

Ruby , 119 110 byte

Chấm dứt ngoại lệ

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}

Hãy thử trực tuyến!

Chấm dứt sạch sẽ (116 byte)

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}

Hãy thử trực tuyến!


1

Python 2/3 (211 byte)

Đoạn mã sau, dựa trên câu trả lời của Bruno Le Floch , tương thích với Python 2 và Python 3.

Hơn nữa, việc lặp đi lặp lại thay vì đệ quy, nó không có nguy cơ chạm vào độ sâu đệ quy tối đa của 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)

Xin chào và chào mừng đến với PPCG. Bạn có thể chơi golf in(0,1,2)đến in 0,1,2[""]*2+[1]đến ["","",1], kết quả là 211 byte .
Jonathan Frech

Tôi đã liên kết với câu trả lời được giới thiệu và thêm từ "byte". Nếu bạn không đồng ý với chỉnh sửa của tôi, vui lòng quay lại.
Jonathan Frech

Cảm ơn Jonathan, đề xuất của bạn rất hoan nghênh!
Carlos Luna

0

BaCon , 391 387 395 byte

Từ những đóng góp trên trang này, tôi chỉ có chương trình Python hoạt động. Những cái khác làm việc cho một số /// mẫu, hoặc hoàn toàn không hoạt động. Do đó, tôi quyết định thêm phiên bản của mình, đây là một triển khai trong BASIC.

Để cạnh tranh trong một cuộc thi CodeGolf với BASIC là không dễ, vì BASIC sử dụng các từ dài làm câu lệnh. Chữ viết tắt duy nhất thường thấy trong BASIC là '?' ký, có nghĩa là IN.

Vì vậy, chương trình dưới đây có thể không bao giờ thắng, nhưng ít nhất nó hoạt động với tất cả mã trình diễn trên trang Codegolf này và trên Esolangs Wiki . Bao gồm tất cả các phiên bản của "99 chai bia".

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$

Đã thêm câu lệnh INPUT để nhận đầu vào từ người dùng.
Peter
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.