Brainf ** k zu Unary und zurück


15

Eine Sprache, die bei eingeschränkten Quellen und anderen derartigen Herausforderungen sehr nützlich ist , ist Unary , ein Brainfuck-Derivat, in dem Programme mit nur einem Zeichen geschrieben sind. Ihre Aufgabe ist es, ein Programm zu schreiben, um Programme von Brainfuck nach Unary zu konvertieren, und ein Programm, um das Gegenteil zu tun, beide Programme in derselben Sprache. Ihre Punktzahl ist die Summe der Längen der beiden Programme.

Wie konvertiert man von Brainfuck zu Unary?

  • Zuerst konvertieren Sie Ihren Brainfuck-Code nach folgender Tabelle in einen Binärcode:

Umrechnungstabelle

  • Verketten Sie nun den Code in der Reihenfolge des Codes zu einer riesigen Binärzahl.
  • Stellen Sie 1der Zeichenfolge ein voran , um eine eindeutige Binärzahl sicherzustellen.
  • Wandeln Sie eine Binärzahl mit einem beliebigen Zeichen in eine unäre Zahl um.
  • Bsp .: +.wäre 000000000000000000000000000000000000000000000000000000000000000000000000000000000000(84 Nullen).

Brainfuck -> Unary Specs

  • Drucken Sie nicht das tatsächliche Programm, sondern nur die Länge des resultierenden Programms, da die resultierenden Programme unglaublich groß sein werden.
  • Nehmen Sie das brainfuck-Programm als String durch stdin, function arg usw. und geben Sie die Länge aus.
  • Das Programm ist immer gültig und enthält nur die 8 Zeichen.

Unary -> Brainfuck Specs

  • Sie müssen die Umkehrung des obigen Algorithmus implementieren.
  • Auch hier handelt es sich aufgrund der großen Größen um eine Zahl, die die Länge des Unary-Codes beschreibt.
  • Gleiche I / O-Regeln wie immer.
  • Das Programm ist immer gültig und enthält nur die 8 Zeichen.

Testfälle

  • Hallo Welt - ++++++[>++++++++++++<-]>.>++++++++++[>++++++++++<-]>+.+++++++..+++.>++++[>+++++++++++<-]>.<+++[>----<-]>.<<<<<+++[>+++++<-]>.>>.+++.------.--------.>>+.=239234107117088762456728667968602154633390994619022073954825877681363348343524058579165785448174718768772358485472231582844556848101441556
  • Fibonacci - ++++++++++++++++++++++++++++++++++++++++++++>++++++++++++++++++++++++++++++++>++++++++++++++++>>+<<[>>>>++++++++++<<[->+>-[>+>>]>[+[-<+>]>+>>]<<<<<<]>[<+>-]>[-]>>>++++++++++<[->-[>+>>]>[+[-<+>]>+>>]<<<<<]>[-]>>[++++++++++++++++++++++++++++++++++++++++++++++++.[-]]<[++++++++++++++++++++++++++++++++++++++++++++++++.[-]]<<<++++++++++++++++++++++++++++++++++++++++++++++++.[-]<<<<<<<.>.>>[>>+<<-]>[>+<<+>-]>[<+>-]<<<-]<<++...=13067995222095367150854793937817629722033205198624522624687536186118993888926522550140580142585590431635487113180955099384652678100247403485397450658564826143160529351955621991895221530908461364045400531236124980271740502887704217664044858614821622360156740992393765239123681327824577149595724956207165558106099868913919959549896553103116795519592552089266360725543244154867904980260

Dies ist Code-Golf, also gewinnt die niedrigste Punktzahl in Bytes!

Möchte jemand eine Lösung für Unary finden? ; P


7
Ein passenderer Titel wäre wahrscheinlich "Brainfuck to Golunar and Back"
Sp3000

@ Sp3000 guter Punkt, aber ich denke, dass die meisten Leute nicht wirklich davon gehört haben (ich selbst eingeschlossen).
Maltysen

@Maltysen Ich glaube nicht, dass deine Testfälle korrekt sind. Zum Beispiel sind die führenden Ziffern der ersten Zahl in der Binärdatei 10101010101010, wann sie sein sollten1010010010010
isaacg

@isaacg Entschuldigung, habe sie von einer Website, die einen anderen Übersetzungsmechanismus verwendet, zu beheben.
Maltysen

1
Können wir sie in ein Programm konvertieren, das nicht genau gleich ist, aber genau dasselbe tut?
Jimmy23013

Antworten:


12

Pyth, 17 + 17 = 34 Bytes

BF -> Unär, 17 Bytes

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

Unär -> BF, 17 Bytes

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

7

Brainfuck , 563 335 318 316 296 + 529 373 366 336 = 632 Bytes

Da hier offensichtlich eine Lösung in einer verwandten Sprache fehlte, hier die Lösung in Brainfuck und Golunar. Ich konnte keine Antwort auf unary posten, weil das ein paar fantastische Billionen Mal mehr Gedächtnis benötigen würde, als es Atome im Universum gibt ^^

Die "Zurück" -Routine prüft nicht, ob der Golunar / Unary-Code gültig ist. Wenn die Bitanzahl mod 3! = 1 ist, wird eine Endlosschleife mit vielen ">" ausgegeben.

Dank an Nitrodon, der mir geholfen hat, weniger als 300 Zeichen für den unären Code des BF zu erhalten

Brainfuck zu unary

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

Probieren Sie es online!

und zurück

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

Probieren Sie es online!

Golunar / unary -digits, 509 303 288 286 268 + 478 337 331 304 = 572 Bytes

Brainfuck zu unary

2845581296974449674357817038179762273623136917867627972159702240227366875240878616687779429553529795902322625321040063298921498529640547483869509829184440577052825434462245755576011912505085065586076069824710351537537205287083477698633592357950165322060367940923703887

und zurück

3775574485023133646619269732540391678811443648964274086227256847322821618228135493733703990523803451383315165001915937932498966394771849173263120467073642011339214182483748816052890450078070151307011943625602391238338941712116968736593594971620990210178757280976709140113340322124688909388916094040773207

Quellcodes

Brainfuck zu unary

[
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
]

und zurück

[
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
Bei der Konvertierung in Unary können Sie die 60 direkt von der Eingabezelle subtrahieren, anstatt sie zuerst in eine eigene Zelle zu stellen, wodurch 16 Byte eingespart werden. Weitere 4 Bytes können gespeichert werden, indem die 45 nicht sofort erstellt wird (wodurch das Bandlayout noch weiter komprimiert wird). Darüber hinaus ist es etwas Golfspieler, die Eingabebytes in der Reihenfolge 01325467 zu überprüfen.
Nitrodon

Als Alternative wollte ich die 45 erstellen, während Sie der Eingabezelle 15 hinzufügen.
Nitrodon

6

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

Vielen Dank an Sp3000 für seine zahlreichen Vorschläge, die viele Bytes gespart haben.

Brainfuck zu Unary, 78 77 61 53 + 2 = 55 Bytes

Zwei Bytes hinzugefügt, um die umgebenden Zeichen bei der Eingabe zu berücksichtigen.

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

Unär für Brainfuck, 86 64 Bytes

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

Schau es dir auf ideone hier an.



3

CJam, 35 Bytes

Brainfuck zu Unary, 17 Bytes

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

Probieren Sie es online aus.

Wie es funktioniert

 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.

Unär für Brainfuck, 18 Bytes

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

Probieren Sie es online aus.

Wie es funktioniert

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-

Testausgang:

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

1
tr -dc 0-9 (und im Code Golf kann man davon ausgehen, dass ?es gut ohne Flucht ist)
izabera

1

Japt , 13 + 13 = 26 Bytes

Brainfuck zu Unary

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

Versuch es!

Erläuterung:

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

Unär für Brainfuck

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

Versuch es!

Erläuterung:

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

Anmerkungen

Ich kann den Meta-Post nicht finden, aber wenn mein Gedächtnis die richtigen Antworten liefert, können die E / A-Vorgänge auf Zahlen beschränkt werden, die von ihrer Sprache unterstützt werden, sofern sie einen Algorithmus implementieren, der funktioniert, wenn die Sprache größere Zahlen unterstützt. Dies ist der Fall, wenn Japt eine Zeichenfolge als "Basis unter nVerwendung dieser nZeichen für die Ziffern" behandeln kann, wird nur der numberDatentyp auf der anderen Seite des Vorgangs verwendet, sodass die Testfälle nicht erfolgreich ausgeführt werden können. Die Ausgabe des ersten Programms und die Eingabe des zweiten Programms erzwingen, dass die Zahl zu einer Zahl wird, die als a dargestellt werden kann number, anstatt die tatsächliche Zahl zu verwenden. Für Zahlen, die von Japt perfekt dargestellt werden könnennumberDatentyp Diese Programme funktionieren wie gewünscht. Wenn sich der numberDatentyp ändert, um größere Nummern zu unterstützen, werden diese Programme auch diese Nummern unterstützen.


0

05AB1E , 33 (17 + 16) Bytes

Brainfuck zu Unary-Länge:

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

Probieren Sie es online aus oder überprüfen Sie alle Testfälle .

Erläuterung:

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

Unäre Länge nach Brainfuck

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

Probieren Sie es online aus oder überprüfen Sie alle Testfälle .

Erläuterung:

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

Pfeil , 77 + 142 = 219 Bytes

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

Probieren Sie es online!


0

C (gcc) , 254 Bytes

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

Probieren Sie es online!

Legt anhand von input ( i) fest, welche Richtung verwendet werden soll , und speichert das Ergebnis im übergebenen Puffer ( o). Beachten Sie, dass einige Compiler das Speichern von 4 Bytes basierend auf der implementierungsdefinierten Reihenfolge von o ++ erlauben. In diesen Fällen wird durch die bereitgestellte Lösung ein zusätzliches Zeichen aus der Unary-> BF-Konvertierung abgeschnitten, und o[1]alle können durch ersetzt werden *o, um das Verhalten wiederherzustellen.


Die Sprache sollte hier "C (gcc) + GMP" sein
ASCII

Ist dies auch kürzer als ein Programm als 2? Und ich würde auch empfehlen, #include <string.h>die Fußzeile anstelle der Kopfzeile einzufügen, um zu zeigen, dass es ohne diesen Import funktioniert. Wäre C ++ nicht auch kürzer, weil der Operator überladen ist? : P
Nur ASCII

Auch nicht wichtig, aber ich würde jeden siauf uivielleicht ändern
ASCII

*i>47&*i<58-> *i%48<10?
Nur ASCII

auch mpz_init_set_str->mpz_set_str
Nur ASCII
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.