Brainf ** k - Unary ve Geri


15

Kısıtlı kaynak ve diğer tür zorlukları çok faydalı olan bir dildir Birli , programlar yalnızca bir karakter yazılır edildiği bir brainfuck türevi. İşiniz, her iki programı da aynı dilde yapmak için, programlari brainfuck'tan tekliye dönüştüren bir program ve tersini yapacak bir program yazmaktır. Puanınız iki programın uzunluğunun toplamı olacaktır.

Nasıl Brainfuck'tan Unary'e dönüşürsün?

  • Önce bu tabloya göre size beyin kodunu ikili dosyaya dönüştürün:

Dönüşüm tablosu

  • Şimdi kodu, kod sırasına göre dev bir ikili sayı olarak birleştirin.
  • Benzersiz bir 1ikili sayı sağlamak için dizenin başına a ekleyin .
  • Herhangi bir karakteri kullanarak ikili sayıdan tek sayıya dönüştürme.
  • Örn: +.olacaktır 000000000000000000000000000000000000000000000000000000000000000000000000000000000000(84 sıfır).

Brainfuck -> Unary Özellikleri

  • Ortaya çıkan programlar imkansız bir şekilde büyük olacağından, gerçek programı değil, yalnızca ortaya çıkan programın uzunluğunu yazdırın.
  • Brainfuck programını stdin, işlev arg, vb. Aracılığıyla bir dize olarak alın ve uzunluğu çıktılayın.
  • Program her zaman geçerli olacak ve içinde sadece bu 8 karakter bulunacaktır.

Unary -> Brainfuck Özellikleri

  • Yukarıdaki algoritmanın tersini uygulamanız gerekecektir.
  • Yine söz konusu büyük boyutlar nedeniyle, girdi Unary kodunun uzunluğunu açıklayan bir sayı olacaktır.
  • Her zamanki gibi aynı G / Ç kuralları.
  • Program her zaman geçerli olacak ve içinde sadece bu 8 karakter bulunacaktır.

Test Durumları

  • Merhaba Dünya - ++++++[>++++++++++++<-]>.>++++++++++[>++++++++++<-]>+.+++++++..+++.>++++[>+++++++++++<-]>.<+++[>----<-]>.<<<<<+++[>+++++<-]>.>>.+++.------.--------.>>+.=239234107117088762456728667968602154633390994619022073954825877681363348343524058579165785448174718768772358485472231582844556848101441556
  • Fibonacci - ++++++++++++++++++++++++++++++++++++++++++++>++++++++++++++++++++++++++++++++>++++++++++++++++>>+<<[>>>>++++++++++<<[->+>-[>+>>]>[+[-<+>]>+>>]<<<<<<]>[<+>-]>[-]>>>++++++++++<[->-[>+>>]>[+[-<+>]>+>>]<<<<<]>[-]>>[++++++++++++++++++++++++++++++++++++++++++++++++.[-]]<[++++++++++++++++++++++++++++++++++++++++++++++++.[-]]<<<++++++++++++++++++++++++++++++++++++++++++++++++.[-]<<<<<<<.>.>>[>>+<<-]>[>+<<+>-]>[<+>-]<<<-]<<++...=13067995222095367150854793937817629722033205198624522624687536186118993888926522550140580142585590431635487113180955099384652678100247403485397450658564826143160529351955621991895221530908461364045400531236124980271740502887704217664044858614821622360156740992393765239123681327824577149595724956207165558106099868913919959549896553103116795519592552089266360725543244154867904980260

Bu kod golf yani bayt kazanır en düşük puanı!

Unary'de çözüm arayan var mı? P


7
Daha uygun bir başlık muhtemelen " Golunar ve Geri Brainfuck " olacaktır
Sp3000

@ Sp3000 iyi bir nokta, ama sanırım çoğu insan bunu gerçekten duymadı (kendim dahil).
Maltysen

@Maltysen Test vakalarınızın doğru olduğunu düşünmüyorum. Örneğin, ikili sayıdaki ilk sayının önde gelen rakamları, 10101010101010olması gerektiği zaman1010010010010
isaacg 5

@isaacg üzgünüm, onları farklı bir çeviri mekanizması kullanan bir web sitesinden çıkardı, düzeltir.
Maltysen

1
Bunları tam olarak eşit olmayan, ancak aynı şeyi yapan bir programa dönüştürebilir miyiz?
jimmy23013

Yanıtlar:


12

Pyth, 17 + 17 = 34 bayt

BF -> Tekli, 17 bayt

i+1xL"><+-.,[]"z8

Unary -> BF, 17 bayt

s@L"><+-.,[]"tjQ8

7

brainfuck , 5633335318 316 296 + 529373366336 = 632 bayt

Bunun ilgili bir dilde açıkça bir çözümü olmadığı için, burada brainfuck ve Golunar'daki çözüm var. Ben tek bir cevap gönderemedim, çünkü bu evrende atomlardan birkaç fantastik milyonlarca kat daha fazla belleğe ihtiyaç duyacaktır ^^

"Geri" rutini Golunar / Unary kodunun geçerli olup olmadığını kontrol etmez. Bit sayısı mod 3! = 1 ise, sonsuz bir döngüye girer ve birçok ">" s yazdırılır.

Nitrodon'a bf için kodun 300 kodunun altına girmeme yardımcı olduğu için teşekkürler

beyin fırtınası

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

Çevrimiçi deneyin!

ve geri

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

Çevrimiçi deneyin!

Golunar / tekli-hane, 509 303 288 286 268 + 478 337 331 304 = 572 bayt

beyin fırtınası

2845581296974449674357817038179762273623136917867627972159702240227366875240878616687779429553529795902322625321040063298921498529640547483869509829184440577052825434462245755576011912505085065586076069824710351537537205287083477698633592357950165322060367940923703887

ve geri

3775574485023133646619269732540391678811443648964274086227256847322821618228135493733703990523803451383315165001915937932498966394771849173263120467073642011339214182483748816052890450078070151307011943625602391238338941712116968736593594971620990210178757280976709140113340322124688909388916094040773207

Kaynak kodları

beyin fırtınası

[
unary:
><+-.,[]
01234567

62 > 62
60 < -2
45 - 15
43 + 2
44 , 1
46 . 2
91 [ 45
93 ] 2

tape (while reading input): Left tape end marker/LTE, [binary data], input, 15, (15 multiplicator)
tape (while base conversion): LTE, [binary data], Value Start/VS, [decimal digits]

decimal digits: digit used/DU, value
]

-                       set LTE
>+                      set leading 1
>>>>,[                  while input
  >+++[>+++++<-]        set 15 (multiplicator)
  >[<+<---->>-]         set 15 and decrease input by 60

                    check for greater than
                        set current bits = 000 (greater than)
  <<--[                 if input != 62 try next char

                    check for less than
  <+>                   set current bits = 001 (less than)
  ++[                   if input != 60 try next char

                    check for minus
  <<+>>                 set current bits = 011 (minus)
  >[<+>-]<[             if input != 45 try next char

                    check for plus
  <->                   set current bits = 010 (plus)
  ++[                   if input != 43 try next char

                    check for comma
  <<<+>->+>             set current bits = 101 (comma)
  -[                    if input != 44 try next char

                    check for dot
  <->                   set current bits = 100 (dot)
  --[                   if input != 46 try next char

                    check for left bracket
  <<+>>                set current bits = 110 (left bracket)
  >+++++++++[<----->-]<[   if input != 91 go to next char


                    use right bracket
  <+>                   set current bits = 111 (right bracket)
  --                    decrease input by 2 / should be 0 now

  ]]]]]]]               close all ifs
  >[-]>>                delete 15 if still existant
  ,                     input next character
]
<<<<+[<+]>[>]           add one to each bit and delete LTE (for shorter search routine)

                    Start of binary to decimal routine

-                       set value start marker (VS)
>+                      set digit used marker (DU)
[<]                     go to LTE

                    binary to decimal loop: use "double and add algorithm" to calculate the digits of the decimal value
>+[                     if not on VS then
  [->+]-                restore current bit value and go to VS
  >                     go to first DU
  [                     digit doubling loop
    ->                  remove DU and go to corresponding digit
    [
      <++>-             decrement current value and add 2 to temp value four times
      [
        <++>-
        [
          <++>-
          [
            <++>-
            [                   if value was greater than 4 then
              <---- ----        subtract 8 from temp
              >>[-]++           set next digit temp = 2 (DU plus 1)
              <-                decrement current digit
              [<++>-]           set temp = remaining value * 2
            ]
          ]
        ]
      ]
    ]
    <[>+<-]             set current digit = temp
    +                   set DU
    >>                  go to next digit
  ]                     end of digit doubling loop
  <<[<<]>[<]>           go to current bit
  -[                    if bit is 2 (used plus 1)
    [->+]-              delete bit and go to VS
    >>+                 increment least significant digit
    <[<<]>[<]           go to current bit
  ]
  >+                    if not on VS then repeat  
]                   end of binary to decimal loop

>[>>]<                  go to most significant digit
<[                  printing loop: for each DU print corresponding value
  +++++++[>++++++<-]>.  add 48 to value (ASCII 0) and print
  <<<                   go to next DU
]

ve geri

[
tape: left tape end marker/LTE(-1), [digits], digit end marker/DE(0), carry, SB(-1), [binary data], 60, 15
digits: digit used marker/DU(1), digit, remainder, solution, 0
        else]                                    [exit else, exit if
binary data: value (, else, exit if, exit else)
]

                    input decimal value
->>                     set LTE
,[                      while input
  <++++++[>--------<-]  decrease input by 48
  +                     set DU
  >>>>> >,              input next digit
]
>->-                    set start of bits (SB) and first CCB
<<<+[-<+]>              delete LTE and go to first DU

                    division loop: calculate the remainders of the input divided by 2 repeatedly to get the (inverted) bits
[
                        divide each digit by 2
  [                     for each DU
    -                   delete DU (for exit if)
    >                   go to digit
    [->+<               dec digit / set remainder
      [->->+>]          if digit gt 0: dec digit / del remainder / inc solution / goto 0
                        pointer: (value(0) remainder is set) or (0 solution gt 1)
      <[<<<]            go to DU
      >                 go to digit
    ]
    <+                  set DU
    >>>[-<<+>>]         move solution to digit
    <[                  if remainder
      >>>>              go to next digit
      +++++ +++++       add 10 to digit/carry
      <<<<-             go back and delete remainder
    ]
    >>>                 go to next DU
  ]

                    append new bit
  >>>+[->+]             go to and delete CCB
  >-                    set new CCB
  <+[-<+]-<             go to carry
  [                     if carry
    >>+[->+]-<+         set last bit
    +[-<+]-<[-]         go to and clear carry
  ]

                    check if first digit became 0 / neccessary to check if value has been completely processed
  < <<<<<[<<<<<]>>>>>   go to first DU
  >[                    if digit gt 0
    <<                  go to exit if
  ]<[                   else
    -                   delete DU
    >>>                 go to exit else of next digit
  ]
  >>                    go to DU / DE if all digits processed
]                   end of division loop

                    decode binary values
>>>+[->+]               go to and delete CCB (after last bit)
<-                      delete leading 1
<                       go to first bit


                    Start of bit decoder
[
unary:
><+-.,[]
01234567

62 > 62
60 < -2
43 + -17
45 - 2
46 . 1
44 , -2
91 [ 47
93 ] 2

tape: start of bytes marker/SB(-1), [binary data], 60(print char/PC), 15
]

+[-                     while not SB

                    Set least significant to octal value of three bits
  [<++>-]               if first bit set add 2 to second bit
  <[<++>-]              for each second bit add 2 to third bit

  >+++[>+++++<-]        multiplier 15
  >[<+<++++>>-]         setup table 60 15

                    run through the 8 possibilities

                    0 greater than
  <<++                  set PC = 62 (greater than)
  <[                    if value gt 0 go to next char

                    1 less than
  >--                   set PC = 60 (less than)
  <-[                   if value gt 1 go to next char

                    2 plus
  >>[<->-]<--           set PC = 43 (plus)
  <-[                   if value gt 1 go to next char

                    3 minus
  >++                   set PC = 45 (minus)
  <-[                   if value gt 1 go to next char

                    4 dot
  >+                    set PC = 46 (dot)
  <-[                   if value gt 1 go to next char

                    5 comma
  >--                   set PC = 44 (comma)
  <-[                   if value gt 1 go to next char

                    6 left bracket
  >+[>+<-]>[<++>-]<+    set PC = 91 (left bracket) (inc (45) / double (90) / inc (91))
  <-[                   if value gt 1 go to next char

                    7 right bracket
  >++                   set PC = 93 (right bracket)
  <-                    decrease value the last time to exit if

  ]]]]]]]               close all ifs
  >.[-]                 print char and clear PC
  >[-]                  clear 15 if still existant

  <<<                   go to next bits
  +                     repeat if not SB
]

1
Unary'e dönüştürürken, ilk önce kendi hücresine koymak yerine 16 bayt kaydederek 60'ı doğrudan giriş hücresinden çıkarabilirsiniz. 45 baytı hemen oluşturmayarak 4 bayt daha kaydedilebilir (böylece bant düzenini daha da sıkıştırabilir). Ayrıca, 01325467 sırasına göre giriş baytlarını kontrol etmek biraz daha golfçüdür.
Nitrodon

Demek istediğim alternatif, giriş hücresine 15 eklerken 45'i oluşturmaktı.
Nitrodon

6

Python 2, 80 79 63 55 + 86 64 = 119 Bayt

Sp3000'e sayısız önerisi için teşekkürler , çok fazla bayt tasarrufu.

Brainfuck - Unary, 78 77 61 53 + 2 = 55 bayt

Girdideki çevreleyenleri hesaba katmak için iki bayt eklendi.

print int(`[1]+map("><+-.,[]".find,input())`[1::3],8)

Brainfuck için unary, 86 64 bayt

print''.join("><+-.,[]"[int(i)]for i in oct(input())[2:]if'L'>i)

Burada ideone üzerinde kontrol edin.



3

CJam, 35 bayt

Brainfuck - Unary, 17 bayt

1r"><+-.,[]"f#+8b

Çevrimiçi deneyin.

Nasıl çalışır

 r                e# Read a whitespace-separated token from STDIN.
            f     e# For each character in the token:
  "><+-.,[]" #    e#     Find its index in this string.
1             +   e# Prepend a 1 to the results.
               8b e# Convert to integer, using base 8 conversion.

Brainfuck için unary, 18 bayt

ri8b"><+-.,[]"f=1>

Çevrimiçi deneyin.

Nasıl çalışır

r                  e# Read a whitespace separated token from STDIN.
 i                 e# Interpret as integer.
  8b               e# Convert to array using base 8 conversion.
              f    e# For each digit:
    "><+-.,[]" =   e#     Select the corresponding character from the string.
                1> e# Discard the first character.

2

Bash + coreutils, 39 + 47 = 86

b2u.sh:

dc -e8i1`tr '<>+-.,[]' 0-7`p|tr -dc 0-9

u2b.sh:

dc -e8o?p|tr -dc 0-9|tr 0-7 '<>+-.,[]'|cut -c2-

Test çıktısı:

$ echo "++++++[>++++++++++++<-]>.>++++++++++[>++++++++++<-]>+.+++++++..+++.>++++[>+++++++++++<-]>.<+++[>----<-]>.<<<<<+++[>+++++<-]>.>>.+++.------.--------.>>+." | ./b2u.sh
239234206933197750788456456928845900180965531636435002144714670872282710109774487453364223333807054152602699434658684117337034763550216789 
$ echo 239234206933197750788456456928845900180965531636435002144714670872282710109774487453364223333807054152602699434658684117337034763550216789 | ./u2b.sh
++++++[>++++++++++++<-[>.>++++++++++[>++++++++++<-[>+.+++++++..+++.>++++[>+++++++++++<-[>.<+++[>----<-[>.<<<<<+++[>+++++<-[>.>>.+++.------.--------.>>+.
$

1
tr -dc 0-9 (ve kod golf ?de iyi kaçış olduğunu varsayabilirsiniz )
izabera

1

Japt , 13 + 13 = 26 bayt

Brainfuck - Unary

i< n"><+-.,[]

Dene!

Açıklama:

i<               :Insert a "<" at the start of the string (representing 1)
   n             :Convert string to decimal by interpreting as:
    "><+-.,[]    : A base 8 number represented by the 8 characters of BF

Brainfuck için unary

s"><+-.,[]" Å

Dene!

Açıklama:

s                :Convert decimal to string representation of:
 "><+-.,[]"      : Base 8 using the BF characters to represent the 8 digits
            Å    :Remove the extra "<" at the front

notlar

Meta yazıyı bulamıyorum, ancak hafızam doğru bir şekilde hizmet veriyorsa, cevaplar, dil daha büyük sayıları desteklemeye başlarsa çalışacak bir algoritma uyguladıkları sürece, I / O'yu kendi dillerinin destekleyebileceği sayılarla sınırlandırmaya izin verilir. Burada durum böyle, Japt'un bir dizeyi " basamaklar için nbu nkarakterleri kullanan taban" olarak işleme yeteneği , yalnızca numberişlemin diğer tarafındaki veri türünü kullanabilir ve bu nedenle test senaryoları gerçekten başarılı olmaz; çıkış ilk program ve giriş , ikinci programı olarak temsil edilebilir bir numara zorlamak olacak numberyerine gerçek sayı kullanmak yerine,. Japt tarafından mükemmel bir şekilde temsil edilebilen sayılar içinnumberveri türü bu programlar istendiği gibi çalışır ve numberveri türü daha büyük sayıları destekleyecek şekilde değişirse, bu programlar da bu sayıları desteklemeye başlar.


0

05AB1E , 33 (17 + 16) bayt

Tekli uzunlukta Brainfuck:

"><+-.,[]"sSk1š8β

Çevrimiçi deneyin veya tüm test senaryolarını doğrulayın .

Açıklama:

"><+-.,[]"           # Push string "><+-.,[]"
          s          # Swap to take the (implicit) input
           S         # Convert it to a list of characters
            k        # Check for each the index in the string
             1š      # Prepend a 1 to the list of indices
               8β    # Convert the list to Base-8 (and output implicitly)

Brainfuck'a tek uzunluk

8в¦"><+-.,[]"sèJ

Çevrimiçi deneyin veya tüm test senaryolarını doğrulayın .

Açıklama:

8в                  # Convert the (implicit) input-list from Base-8 to Base-10
  ¦                 # Remove the first 1
   "><+-.,[]"       # Push string "><+-.,[]"
             s      # Swap the list and string on the stack
              è     # Index each integer into this string
               J    # Join everything together (and output implicitly)

0

Dart , 77 + 142 = 219 bayt

f(s)=>BigInt.parse('1'+s.split('').map('><+-.,[]'.indexOf).join(''),radix:8);

F(n)=>BigInt.parse(n).toRadixString(8).split('').map((s)=>'><+-.,[]'.substring(int.parse(s),int.parse(s)+1)).join('').toString().substring(1);

Çevrimiçi deneyin!


0

C (gcc) , 254 bayt

#include"gmp.h"
f(i,o)char*i,*o;{mpz_t l;char*c="><+-.,[]";if(*i>47&*i<58)for(mpz_init_set_str(l,i,0),mpz_get_str(o,8,l);*o;*o++=o[1]?c[o[1]-48]:0);else for(mpz_init_set_si(l,1);mpz_get_str(o,10,l),*i;mpz_mul_si(l,l,8),mpz_add_ui(l,l,strchr(c,*i++)-c));}

Çevrimiçi deneyin!

Girdiye göre hangi yöne gidileceğini belirler (i ) , sonucu iletilen arabellekte ( o) saklar . Bazı derleyicilerin o ++ uygulamasının tanımlı sırasına göre 4 bayt tasarruf sağladığını unutmayın. Bu durumlarda, sağlanan çözüm Unary-> BF dönüşümünden fazladan bir karakter keser ve davranışı kurtarmak için o[1]bunların tümü ile değiştirilebilir *o.


Dil burada "C (gcc) + GMP" olmalıdır
ASCII-yalnızca

Ayrıca, bu bir program olarak 2'den daha kısa mı? Ayrıca #include <string.h>, bu içe aktarma olmadan çalıştığını göstermek için üstbilgi yerine altbilgi koymanızı da öneririm . Ayrıca C ++, operatörün aşırı yüklenmesi nedeniyle daha kısa olmaz mı? : P
ASCII-sadece

Ayrıca önemli değil, ama her sibirini uibelki de değiştirirdim
ASCII-sadece

*i>47&*i<58-> *i%48<10?
Yalnızca ASCII

ayrıca mpz_init_set_str->mpz_set_str
ASCII-sadece
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.