Brainfuck'u küçültün


22

Buradaki zorluk, Brainfuck kodunu aşağıdaki kurallara göre küçültmektir :

  • Bir olmayan şeyleri kaldırın +-><[].,.
  • Ardışık herhangi bir grup +veya -karakter için +s ve -s miktarı aynıysa bunları kaldırın.
  • Yukarıdaki gibi yapın, ancak >ve ile <.
  • +-><Hiçbir şey yapmazlarsa karakter dizilerini kaldırın . Örneğin, kaldırmalısınız +>-<->+<. (Bu, uygulanması en zor ve en zor olan olabilir.) +>-<+>-<Kaldırılmaması gereken herhangi bir yanlış pozitif almadığınızdan emin olun .

Test durumları:

Giriş

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

Çıktı

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

Giriş

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

Çıktı

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

İstediğiniz gibi giriş ve çıkış kabul edebilirsiniz - stdin / stdout, fonksiyon, vb., Ancak giriş kodlanmış olmayabilir.

Bu , karakter sayısındaki en kısa kod kazanacak.


4
Bunun eski bir zorluk olduğunu biliyorum, ancak test durumları yetersiz. ++>>++<<--çıktı >>++<<ve bu kaplı değildi. Lütfen daha fazla test durumu ekleyin.
mbomb007

@ mbomb007, son test durumunu incelediniz +++>-<+>---<mi? Gereksiz işaretçi hareketini önlemek için kısaltılabilir, ancak beklenen çıktı değişmeden kalır. Hem soruya hem de cevaba bakmaya dayanan anlayışım, Doorknob'un gevşek bir şekilde alınan spesifikasyonlarla iyi olduğunu; +-><açıkça belirtildiği gibi herhangi bir op olmayan bitişik diziyi ortadan kaldırmalıyız ve bunun ötesinde, örneğinizde olduğu gibi ekstra küçültme yapmanın mümkün olduğu ++>>++<<--ve ayrıca kodun işlevselliğini değiştirmediği sürece yeniden düzenlemeler yapabiliriz >+<+. +>+<.
Mitch Schwartz

@MitchSchwartz "nin Kaldır dizileri + -.> <Onlar hiçbir şey yaparsak karakterler Örneğin, kaldırmalısınız +>-<->+<. (. Bu uygulamaya en zor ve en zor biri olabilir) gibi emin herhangi yanlış pozitif alamadım olun +>-<+>-<, hangi kaldırılmaması gerekir. " - bu biraz belirsiz
mbomb007

@ mbomb007 Dördüncü mermi noktasına dahil edildiklerinden ikinci ve üçüncü mermi noktaları gereksiz ve gereksizdir. Ne olmuş yani? Güzel bir iş. Benim yorumum size saldırmamak için yapıcı olmak ve netlik sağlamak içindir. Lütfen istediğin gibi yap ya da nasıl farklı bir şekilde söylemem gerektiğini söyle. Çünkü yazdıklarımı tam olarak ele almadın; Sadece yapıcı olmadan kendini savunmaya çalışıyor gibisin. Hangi şekilde belirsiz buluyorsunuz? Nasıl yeniden yazarsın? Soruyu düzenlemek ister misiniz? Doorknob'a sormak ister misin?
Mitch Schwartz

1
Demek ki sadece bitişik dizileri kaldırmamız gerekiyor?
mbomb007

Yanıtlar:


10

REBEL - 104

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

Kullanımı:

Giriş: stdin'den bir satır okur.

Çıktı: Bir satırı stdout'a yazdırır.

Anomaliler *:

  • Girme _, hiçbir şey vermemek yerine başka bir satırın okunmasına ve kullanılmasına neden olur.
  • İkinci test ++++>----<yerine çıktı +++>-<+>---<. Ama sorun değil, değil mi? ;)
  • >-<+vb. ile değiştirilir +>-<.

Spoiler:

Anomalinin uygulanması # 3, işleri oldukça önemsiz kılıyor.

* Bu bir hata değil, bir özelliktir!


"Bu bir hata değil, bir özellik" +1!
Rohan Jhunjhunwala

36

Brainfuck, 579 bayt

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

Biçimlendirme ve bazı yorumlar ile:

,
[
  <<+>> >>+<<
  [
    [<+> >+<-]
    ++++++[>-------<-]
    >-
    [
      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
          ++.[-]
          >>>>>>>
        ]
        <
      ]
    ]
    >>
  ]
  <[>>>>>>>]
  +[-<<<<<[-]<<]
  ,
]

Bu, Keith Randall'ın çözümüyle aynı yaklaşımı kullanır ve tüm bitişik dizileri +-<>simülasyonla en aza indirir . Örneğin, +++>-<+>---<olur ++++>----<ve >+<+<<+>+<->>>>olur +<+>>+>.

Çevrimiçi deneyin. (Simüle edilmiş bir hücrenin mutlak değeri 256'ya yaklaşırsa, taşma sorunları olacaktır.)

Genel yapı

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

Bant 7 hücreli düğümlere ayrılmıştır; iç döngünün başında, bellek düzeni

0 s 0 c 0 a b

burada s, başlangıç hücresi için bir Boole bayrağıdır cakım karakteri, asimüle hücre değeri (artı bir) negatif bir parçasıdır ve bsimüle hücre değeri pozitif bir parçasıdır.

Küçültülmüş dizi yazdırılırken, bellek düzeni

d n e 0 0 a b

burada dyön için bir Boole bayrağıdır, ave bdaha önce olduğu gibi olan (bir basılı / sıfır ama olmak) ve nve euç düğüm için sadece sıfırdan farklı; ndüğümün kaç kez görüldüğü ile ilgilidir ve eiç çevrimi durduran char değerinin (artı bir) değeridir.

Başlangıçta düğüm başına daha fazla bilgiyi izlemeyi düşünmüştüm: boolean bayrakları olarak en soldaki ve en soldaki düğüm ve başlangıç ​​ve bitiş düğümleriyle ilgili olarak düğümün konumu. Ancak, gerektiğinde komşu hücrelere bakarak ve başlangıç ​​düğümünü bulmak için sol ve sağ taramalar yaparak bunu önleyebiliriz.

Küçültülmüş diziyi yazdırırken ve simüle edilen işaretçinin nasıl hareket ettirileceğine karar verirken, genel bir yaklaşım izleyebiliriz: başlangıç ​​düğümünden uzağa hareket ettirerek başlayabilir (başlangıç ​​ve bitiş düğümleri aynıysa keyfi bir yönde), en sola ve en sağa dönebilir düğümler ve bitiş düğümünün görülme sayısına bağlı olarak durma: başlangıç ​​ve bitiş düğümlerinin aynı olması durumunda 3 kez, aksi takdirde 2.


2
Kaynak: brainfuck. Hedef: beyin hastası. +1
Outgolfer Erik, 28:16


1
Bunun biraz dikkat çekmesine ve bir veya iki günde ödül almasına izin vereceğim
lirtosiast

1
@MitchSchwartz Kodunuzu kodunuza karşı test ettiniz mi? Aslında kısaltabilirsiniz! #meta
WallyWest

1
@WallyWest (Bu 7 bayt kurtarıyor gibi gözüküyor!) Boşuna, permalink'teki kod satır çizgilerine sahip.
Dennis,

7

Python, 404 karakter

Bu kod tüm alt dizilerinin mükemmel bir optimizasyonunu yapar +-<>. İstediğinden biraz daha fazla, ama işte gidiyorsun.

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) 

+-<>Bant üzerindeki işlemleri simüle ederek çalışır t. sbant üzerindeki başlangıç ​​pozisyonudur ve pmevcut pozisyondur. Simülasyondan sonra, [a,b]çalıştırılması gereken kapsamı hesaplar ve tüm +/- değerlerini tek bir optimum geçişte yapar.


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

Demo (lütfen burada bit.ly kullanımını bağışlayın, URL'nin tamamı işaretlemeyi bozacaktır)

Sıkıştırılmamış sürüm (w / debug kodu):

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 demolar gönderme alternatif bir yolu kullanmaktır JSFiddle . Sol kenarda, JS yerine CoffeeScript kullanmanıza izin veren bir "Diller" yapılandırma bölmesi vardır.
Peter Taylor

@PeterTaylor Teşekkürler, daha önce JSFiddle'ı biliyordum, ancak CoffeeScript'i kullanabileceğini bilmiyordum
TimWolla

Bu işlem başarısız olur >+.-<; boş dizgiyi değişmeden bırakmak yerine üretir.
Mitch Schwartz
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.