단항과 뒤로 Brainf ** k


15

제한적인 소스와 그 밖의 도전에 매우 유용한 언어는 단 하나의 문자로 프로그램을 작성하는 뇌성 파생물 인 Unary 입니다. 당신의 임무는 프로그램을 brainfuck에서 단항으로 변환하는 프로그램을 작성하고 반대의 두 프로그램을 같은 언어로 작성하는 것입니다. 당신의 점수는 두 프로그램의 길이의 합이 될 것입니다.

brainfuck에서 unary로 어떻게 변환합니까?

  • 먼저 다음 표에 따라 brainfuck 코드를 바이너리로 변환하십시오.

변환 표

  • 이제 코드 순서대로 코드를 하나의 거대한 이진수로 연결하십시오.
  • 1고유 한 이진수를 보장하려면 문자열 앞에 a 를 추가하십시오 .
  • 임의의 문자를 사용하여 이진수에서 단항으로 변환하십시오.
  • 예는 : +.000000000000000000000000000000000000000000000000000000000000000000000000000000000000(84 제로).

Brainfuck-> 단항 사양

  • 결과 프로그램은 엄청나게 크므로 실제 프로그램이 아니라 결과 프로그램의 길이 만 인쇄하십시오.
  • stdin, function arg 등을 통해 brainfuck 프로그램을 문자열로 가져 와서 길이를 출력하십시오.
  • 이 프로그램은 항상 유효하며 그 안에 8 자만 있습니다.

단항-> Brainfuck 사양

  • 위 알고리즘의 반대를 구현해야합니다.
  • 문제의 크기가 너무 커서 입력 값은 단항 코드의 길이를 나타내는 숫자입니다.
  • 항상 같은 I / O 규칙.
  • 이 프로그램은 항상 유효하며 그 안에 8 자만 있습니다.

테스트 사례

  • 안녕하세요 세계- ++++++[>++++++++++++<-]>.>++++++++++[>++++++++++<-]>+.+++++++..+++.>++++[>+++++++++++<-]>.<+++[>----<-]>.<<<<<+++[>+++++<-]>.>>.+++.------.--------.>>+.=239234107117088762456728667968602154633390994619022073954825877681363348343524058579165785448174718768772358485472231582844556848101441556
  • 피보나치- ++++++++++++++++++++++++++++++++++++++++++++>++++++++++++++++++++++++++++++++>++++++++++++++++>>+<<[>>>>++++++++++<<[->+>-[>+>>]>[+[-<+>]>+>>]<<<<<<]>[<+>-]>[-]>>>++++++++++<[->-[>+>>]>[+[-<+>]>+>>]<<<<<]>[-]>>[++++++++++++++++++++++++++++++++++++++++++++++++.[-]]<[++++++++++++++++++++++++++++++++++++++++++++++++.[-]]<<<++++++++++++++++++++++++++++++++++++++++++++++++.[-]<<<<<<<.>.>>[>>+<<-]>[>+<<+>-]>[<+>-]<<<-]<<++...=13067995222095367150854793937817629722033205198624522624687536186118993888926522550140580142585590431635487113180955099384652678100247403485397450658564826143160529351955621991895221530908461364045400531236124980271740502887704217664044858614821622360156740992393765239123681327824577149595724956207165558106099868913919959549896553103116795519592552089266360725543244154867904980260

이것은 코드 골프이므로 바이트 단위로 가장 낮은 점수를 얻습니다!

단항 솔루션을 원하십니까? ;피


7
더 적절한 제목은 아마 "Brainfuck to Golunar and Back"
Sp3000

@ Sp3000 좋은 지적이지만, 대부분의 사람들은 그 자체에 대해 들어 본 적이 없다고 생각합니다 (자체 포함).
Maltysen

@ Maltysen 귀하의 테스트 사례가 정확하지 않다고 생각합니다. 예를 들어, 이진수에서 첫 번째 숫자의 선행 숫자는 다음과 같습니다 10101010101010.1010010010010
isaacg

@isaacg 죄송합니다, 다른 번역 메커니즘을 사용하고 있던 웹 사이트를 방문하여 해결해 드리겠습니다.
Maltysen

1
정확히 같지는 않지만 정확히 같은 프로그램으로 변환 할 수 있습니까?
jimmy23013

답변:


12

Pyth, 17 + 17 = 34 바이트

BF-> 단항, 17 바이트

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

단항-> BF, 17 바이트

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

7

브레인 퍽 , 563 335 318 316 296 + 529 373 366 336 = 632 바이트

이것은 분명히 관련 언어로 된 솔루션을 놓치고 있었으므로 여기 brainfuck 및 Golunar의 솔루션이 있습니다. 나는 우주에 원자가있는 것보다 환상적인 환상보다 몇 배나 많은 메모리가 필요하기 때문에 단항에 답을 올릴 수 없었습니다 ^^

"뒤로"루틴은 Golunar / Unary 코드가 유효한지 확인하지 않습니다. 비트 카운트 mod 3! = 1이면 많은 ">"를 인쇄하는 무한 루프가 발생합니다.

bf에서 단항 코드까지 300 자 미만으로 사용할 수 있도록 도와 준 Nitrodon에게 감사드립니다.

단항에 brainfuck

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

온라인으로 사용해보십시오!

그리고 다시

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

온라인으로 사용해보십시오!

Golunar / 단항 자릿수, 509 303 288 286 268 + 478 337 331 304 = 572 바이트

단항에 brainfuck

2845581296974449674357817038179762273623136917867627972159702240227366875240878616687779429553529795902322625321040063298921498529640547483869509829184440577052825434462245755576011912505085065586076069824710351537537205287083477698633592357950165322060367940923703887

그리고 다시

3775574485023133646619269732540391678811443648964274086227256847322821618228135493733703990523803451383315165001915937932498966394771849173263120467073642011339214182483748816052890450078070151307011943625602391238338941712116968736593594971620990210178757280976709140113340322124688909388916094040773207

소스 코드

단항에 brainfuck

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

그리고 다시

[
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
단항으로 변환 할 때 입력 셀에서 60을 먼저 빼지 않고 16 바이트를 절약 할 수 있습니다. 45 개를 즉시 만들지 않기 때문에 추가 4 바이트를 절약 할 수 있습니다 (따라서 테이프 레이아웃을 더욱 압축). 또한 01325467 순서로 입력 바이트를 확인하는 것이 약간 골퍼입니다.
Nitrodon

내가 의미하는 대안은 입력 셀에 15를 추가하는 동안 45를 만드는 것이 었습니다.
Nitrodon

6

파이썬 2, 80 79 63 55 + 86 64 = 119 바이트

많은 제안 을 해주신 Sp3000 덕분에 많은 바이트를 절약 할 수있었습니다.

단항에 대한 Brainfuck, 78 77 61 53 + 2 = 55 바이트

입력시 "s"를 설명하기 위해 2 바이트를 추가했습니다.

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

단항 대 Brainfuck, 86 64 바이트

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

이곳에서 확인하십시오.



3

CJam, 35 바이트

단항에 대한 Brainfuck, 17 바이트

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

온라인으로 사용해보십시오.

작동 원리

 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, 18 바이트

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

온라인으로 사용해보십시오.

작동 원리

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

배쉬 + 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-

테스트 출력 :

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

1
tr -dc 0-9 (그리고 코드 골프에서는 ?이스케이프 처리되지 않은 것으로 가정 할 수 있습니다 )
izabera

1

apt , 13 + 13 = 26 바이트

단항에 Brainfuck

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

시도 해봐!

설명:

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

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

시도 해봐!

설명:

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

노트

메타 게시물을 찾을 수 없지만 내 메모리가 올바르게 작동하면 언어가 더 큰 숫자를 지원하기 시작하면 작동하는 알고리즘을 구현하는 한 I / O를 해당 언어가 지원할 수있는 숫자로 제한 할 수 있습니다. 이 경우 문자열이 " nn문자를 숫자로 사용하는 기본"으로 문자열을 처리하는 Japt의 기능 number은 조작의 다른 쪽에서 만 데이터 유형을 사용할 수 있으므로 테스트 케이스가 실제로 성공적으로 실행되지 않습니다. 첫 번째 프로그램 의 출력입력 은 숫자를 number실제 숫자를 사용하지 않고 로 표현할 수있는 숫자로 강제 변환합니다 . Japt 's로 완벽하게 표현할 수있는 숫자number데이터 유형이 프로그램은 원하는대로 작동하며 데이터 유형이 number더 큰 숫자를 지원하도록 변경 되면 해당 프로그램도 해당 숫자를 지원하기 시작합니다.


0

05AB1E , 33 (17 + 16) 바이트

단항 길이에 대한 Brainfuck :

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

온라인으로 시도 하거나 모든 테스트 사례를 확인하십시오 .

설명:

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

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

온라인으로 시도 하거나 모든 테스트 사례를 확인하십시오 .

설명:

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

다트 , 77 + 142 = 219 바이트

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

온라인으로 사용해보십시오!


0

C (gcc) , 254 바이트

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

온라인으로 사용해보십시오!

입력 ( i)을 기준으로 진행 방향을 결정 하고 결과를 전달 된 버퍼 ( o) 에 저장합니다 . 일부 컴파일러는 o ++의 구현 정의 순서에 따라 4 바이트를 저장할 수 있습니다. 이 경우 제공된 솔루션은 단항-> BF 변환에서 추가 문자를 자르고 o[1]의 모든 문자 를*o 동작을 복구하기 위해를 할 수 있습니다.


언어는 여기에서 "C (gcc) + GMP"여야합니다
ASCII 전용

또한이 프로그램이 2보다 하나의 프로그램만큼 짧습니까? 그리고 #include <string.h>가져 오기없이 작동한다는 것을 보여주기 위해 머리글 대신 바닥 글을 넣는 것이 좋습니다 . 또한 연산자 오버로드로 인해 C ++이 더 짧지 않습니까? : P
ASCII 전용

또한 중요하지는 않지만 매번 변경 될 siui있습니다.
ASCII 전용

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

또한 mpz_init_set_str->mpz_set_str
ASCII 전용
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.