피즈 버즈 투 텍스트


29

소개

내가하지 않습니다 특히 소다 버즈 추세가 어디에서 왔는지 알고있다. 그것은 단지 밈 또는 무언가 일지 모르지만 다소 인기가 있습니다.

도전

오늘의 일은 Fizz Buzz를 각각 이진 (0, 1)으로 변환하고이 이진을 텍스트로 변환하는 것입니다. 꽤 표준적인 것들.

어떻게 작동합니까?

FizzBuzzBuzzFizzBuzzFizzFizzFizz FizzBuzzBuzzFizzBuzzFizzFizzBuzz는 01101000 01101001로 번역 된 다음 "hi"로 번역됩니다.

제약

  • 입력은 이진 관점에서 Fizz Buzz입니다 (아래 예 참조).
  • 출력은 텍스트 여야합니다.
  • FizzBuzz 입력이 올바른 것으로 가정 할 수 있습니다.
  • 이것은 이며 가장 짧은 바이트가 이깁니다.

입력

FizzBuzzBuzzFizzBuzzFizzFizzFizz FizzBuzzBuzzFizzBuzzFizzFizzBuzz FizzFizzBuzzFizzFizzFizzFizzBuzz

산출

"안녕!"


15
나 나? 이것은 초등학교 (초등학교) 게임입니다
Beta Decay

2
입력에 공백을 넣을 수 없습니까?
HyperNeutrino

2
우리는 그 공간을 가질 수 없습니까? 해당 공간을 입력하지 않아도 3 바이트를 절약 할 수 있습니다.
HyperNeutrino


8
@dmckee Joel이 언급 한 "또 다른 블로그"는 Stackoverflow의 다른 설립자 인 Jeff Atwood의 것입니다.
pilsetnieks

답변:


55

C, 59 바이트

i;f(char*s){while(*s&3?*s&9||(i+=i+*s%5):putchar(i),*s++);}

마법의 숫자, 어디서나 마법의 숫자!

(또한 C는 Python, JS, PHP 및 Ruby보다 짧습니까?

문자열을 입력으로 사용하여 STDOUT으로 출력하는 기능입니다.

연습

기본 구조는 다음과 같습니다.

i;           // initialize an integer i to 0
f(char*s){
while(...);  // run the stuff inside until it becomes 0
}

여기서 "내부 내용"은 ,*s++쉼표 연산자가 두 번째 인수의 값만 반환하는 코드 묶음입니다 . 따라서 이것은 문자열을 통해 실행 *s되며 ++종료하기 전에 후행 NUL 바이트를 포함하여 모든 문자로 설정 됩니다 (postfix 는 이전 값을 반환하므로).

나머지를 살펴 보자.

*s&3?*s&9||(i+=i+*s%5):putchar(i)

삼항 및 단락을 벗겨 내면 ||확장 할 수 있습니다.

if (*s & 3) {
    if (!(*s & 9)) {
        i += i + *s % 5;
    }
} else {
    putchar(i);
}

이 마법 번호는 어디에서 왔습니까? 다음은 관련된 모든 문자의 이진 표현입니다.

F  70  01000110
B  66  01000010
i  105 01101001
z  122 01111010
u  117 01110101
   32  00100000
\0 0   00000000

먼저 공백과 NUL을 나머지 문자와 분리해야합니다. 이 알고리즘은 작동 방식에 따라 "현재"숫자의 누산기를 유지하고 공백이나 문자열 끝에 도달 할 때마다 인쇄합니다 (예 :) '\0'. ' '그리고 '\0'2 개의 최하위 비트를 설정하지 않은 유일한 문자 라는 점을 인식 0b11하여 문자가 공백이거나 NUL이면 0을 얻기 위해 비트 단위 AND 문자를 사용 하고 그렇지 않으면 0이 아닙니다 .

첫 번째 "if"브랜치에서 더 깊이 파고 들면 이제 우리는 하나의 문자를 갖게 FBizu됩니다. Fs 및 Bs 의 누산기를 업데이트하기로 선택 했기 때문에 s를 필터링하는 방법이 필요했습니다 izu. 편리하게, F그리고 B둘은 제 2, 제 3, 또는 설정 일곱째 최하위 비트를, 그리고 다른 모든 숫자는 적어도 하나 개의 다른 비트 세트를 갖는다. 실제로, 이들은 모두 첫 번째 또는 네 번째 최하위 비트를 갖습니다. 따라서, 우리는 비트 단위 수와 함께 0b00001001, 9 인 0을 얻을 것이다 FB및 제로 그렇지.

우리는 우리가있는 것으로 확인되었습니다 후 F또는 B, 우리는 그들에게 매핑 할 수 01때문에, 그 계수 5를 복용하여 각각을 F하다 70하고 B있다 66. 그런 다음 스 니펫

i += i + *s % 5;

그냥 골치 아픈 말이다

i = (i * 2) + (*s % 5);

이는 다음과 같이 표현 될 수도 있습니다

i = (i << 1) | (*s % 5);

최소 비트 위치에 새 비트를 삽입하고 다른 모든 비트를 1 이상 이동시킵니다.

"하지만 기다려!" 당신은 항의 할 수 있습니다. "인쇄 한 후 i언제 다시 0으로 재설정됩니까?" 글쎄, putchar인수를으로 캐스팅하면 unsigned char크기는 8 비트가됩니다. 즉, 8 번째 최하위 비트 (즉, 이전 반복의 정크)를 지나친 모든 항목이 버려 지므로 걱정할 필요가 없습니다.

덕분에 @ETHproductions 대체하는 제안에 대한 579, 바이트를 저장!


putchar와 함께 좋은 트릭.
Computronium

이것은 엄청나게 훌륭합니다. C는 옳았다!
Gustavo Maciel

13
올바른 일을하는 것에 대해 말하자면, 이것은 겸손하지 않은 의견으로는 어떻게 코드 골프 응답을 수행해야 하는가입니다. 현명하고 통찰력있는 솔루션을 게시하고,보다 실제적이고 다른 상황에서 유용 할 수있는 언어에 대해 사람들에게 실제로 알려주는 완전하고 잘 쓰여진 설명이 함께 제공됩니다.
코디 그레이

3
@CodyGray 정확히 이것입니다. 내가 자주 방문하는 SE 위에 Code Golf가없는 이유 중 하나는 많은 답변이 "여기 코드"이기 때문입니다. 그것은 언어에 매우 익숙한 사람들에게는 멋지지만, 그것은 나에게 소음처럼 보입니다. 나는 대부분의 사람들이 코드 자체보다 훨씬 더 흥미로운 것으로 생각 하는 방법을 보여주기 때문에 여기에서 설명을보고 싶습니다 . 그냥 내 두 센트 ...
크리스 Cirefice 13:30에

아주 좋은 비트 핵이지만 MSB (왼쪽)에서 LSB (오른쪽)까지 비트를 계산합니까? IMO는 8 비트 바이트 (또는 128 비트 SIMD 벡터 등)에서 비트를 계산하는 유일한 방법은 LSB = 비트 0에서 MSB = 비트 7입니다.
Peter Cordes

10

젤리 , 9 바이트

Ḳm€4O%5ḄỌ

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


아, 똑똑해, 평평하지 않아도 돼 좋은.
HyperNeutrino

@HyperNeutrino 내가 당신에 대해 한 의견에 주목하십시오. 기술적으로 허용되지 않더라도 Duping을 피하기 위해 약간 다른 알고리즘을 사용했습니다.
Outgolfer Erik

@ downvoter : 드라이브 바이 다운 투표 전에 이것을 테스트 했습니까?
Outgolfer Erik


9

파이썬 3 , 169 101 93 91 85 81 바이트

lambda s,j="".join:j(chr(int(j('01'[b<"C"])for b in c[::4]),2))for c in s.split())

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

설명:

lambda s,j="".join:  # Create a lambda function
    j(  # call "".join, adds characters together with nothing in between
        chr(  # character by int
            int(  # string to int
                j(  # "".join again
                    '01'[b<"C"]  # 1 or 0, based on what character we get
                    for b in c[::4]  # For every first of 4 characters
                ),
                2)  # Base 2
        )
        for c in s.split()  # for every group of Fizz and Buzz with any whitespace character after it
    )

그것은 빠르다. +1
HyperNeutrino

나는 얼마 전에 이와 비슷한 일을했다, 그것은 단지 복사-붙여 넣기의 문제 였고 그것을 FizzBuzz로 바꾸었다. : P
Martmists

1
아 그 설명입니다. : P 그러나 당신은 outgolfed했다; _;
HyperNeutrino


1
혹시, 다시 한 번 85 바이트 lambda기능으로
Mr. Xcoder

8

자바 스크립트 (ES6), 80 79 바이트

let f =

s=>`${s} `.replace(/.{4} ?/g,m=>m[s=s*2|m<'F',4]?String.fromCharCode(s&255):'')

console.log(f("FizzBuzzBuzzFizzBuzzFizzFizzFizz FizzBuzzBuzzFizzBuzzFizzFizzBuzz FizzFizzBuzzFizzFizzFizzFizzBuzz"))


아주 좋아요 사용하여 여러 가지 다른 80 바이트 솔루션 있기는하지만 나는 시도하고 짧은 뭔가 들고 오지에 실패 .replace(/..zz/g,, '0b'+
ETHproductions

@ETHproductions 제거 n하면 79에 도달 할 수 있습니다. 슬프게도 입력에 추가 공간을 추가해야합니다. 따라서 오히려 비용이 많이 듭니다 `${s} ` .
Arnauld

7

Japt , 26 24 19 17 바이트

¸®ë4 ®c u5Ãn2 dÃq

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

@Shaggy 덕분에 2 바이트 절약 및 2 바이트 절약

설명

input: "FizzBuzzBuzzFizzBuzzFizzFizzFizz FizzBuzzBuzzFizzBuzzFizzFizzBuzz FizzFizzBuzzFizzFizzFizzFizzBuzz"

¸®                // ["FizzBuzzBuzzFizzBuzzFizzFizzFizz","FizzBuzzBuzzFizzBuzzFizzFizzBuzz","FizzFizzBuzzFizzFizzFizzFizzBuzz"]
  ë4              // ["FBBFBFFF","FBBFBFFB","FFBFFFFB"]
     ®c           // [[70,66,66,70,66,70,70,70],[70,66,66,70,66,70,70,66],[70,70,66,70,70,70,70,66]]
        u5Ã       // ["01101000","01101001","00100001"]
           n2     // [104,105,33]
              d   // ["h","i","!"]
               Ãq // "hi!"

1
2를 })로 바꿀 수 있습니다 Ã. 그것보다 분명히 더 많은 것을 구할 수는 있지만 전화로 작동시킬 수는 없습니다.
Shaggy

1
Japt를 이용해 주셔서 감사합니다! 당신은 대체하여 몇 바이트를 저장할 수 있습니다 ò4...q n2ë4...n2( ë4같은 일로서 않습니다 ò4, 이상하게도, 그것을 문서화하지 않는 것, 첫 번째 항목을 반환 제외)
ETHproductions

1
@ETHproductions Japt를 제작 해 주셔서 감사합니다!
powelles

6

루비, 65 63 60 바이트

->s{s.split.map{|x|x.gsub(/..../){$&.ord%5}.to_i(2).chr}*''}

이것은 익명의 proc이며 입력을 받아 출력을 문자열로 제공합니다.

->s{
s.split            # split on whitespace
.map{|x|           # for each word as x,
  x.gsub(/..../){  # replace each sequence of four characters with
    $&.ord%5       # the ASCII value of the first character, mod 5
                   # F is 70, B is 66, so this yields 0 for Fizz and 1 for Buzz
  }.to_i(2)        # interpret as a binary number
  .chr             # the character with this ASCII value
}*''               # join on empty string
}

6

자바 스크립트 (ES6), 95 88 85 81 바이트

s=>s.replace(/..zz/g,m=>m<"F"|0).replace(/\d+ ?/g,m=>String.fromCharCode("0b"+m))

시도 해봐

f=
s=>s.replace(/..zz/g,m=>m<"F"|0).replace(/\d+ ?/g,m=>String.fromCharCode("0b"+m))
oninput=_=>o.innerText=f(i.value)
o.innerText=f(i.value="FizzBuzzBuzzFizzBuzzFizzFizzFizz FizzBuzzBuzzFizzBuzzFizzFizzBuzz FizzFizzBuzzFizzFizzFizzFizzBuzz")
*{font-family:sans-serif}
<input id=i><p id=o>


I believe + is shorter than parseInt
Kritixi Lithos

2
I think +(m[0]<"F") could be shortened to m<"F"|0
ETHproductions

5

Perl 5, 33 Bytes

print(pack'B*',<>=~y/FB -z/01/dr)

Replaces 'F' and 'B' in the input with 0 and 1 respectively, and deletes the other characters. It then uses perl's pack function to turn this bit string into ASCII characters.


Wow this is golfed down to about half the size of my Perl 5 attempt. Kudos.
David Conrad

1
I believe you could make this considerably shorter using the -p0 command line option (which would save you <>=~r for input, and allow you to use $_= rather than print()). Depending on how you want to handle newlines, you might not even need the 0. (Even if you want to avoid command line option penalties, say is shorter than print.)

@Chris Not mine, faubiguy's. But thanks. ;)
David Conrad

@DavidConrad My bad haha.
Chris

1
You definitely don't need the 0 either. Just use the -p flag and $_=pack'B*',y/FB -z/01/dr for your program lowers your score to 26 bytes.
Chris

5

Python 2, 90 83 82 81 bytes

-1 byte thanks to totallyhuman
-1 byte thanks to Martmists
-1 byte thanks to Jonathan Frech

lambda x:''.join(chr(int(`[+(l<'D')for l in b[::4]]`[1::3],2))for b in x.split())

Try it online!



you can save a byte by turning *1 for into *1for
Martmists

Since you use *1 to convert from boolean to integer, you can save a byte by using a +: (l<'D')*1for can be +(l<'D')for.
Jonathan Frech

3

Whitespace, 123 bytes

Visible representation:

SSNNSSNSNSSSNSNSTNTSTTTSSSTSSSSSNTSSTSNSNTSSNSSSTSSTTSNTSSTNTSTNSSSTNTSSSNSSTNSSNSNSSNSTNTSTNTSTNTSTSSSNSNNNSSSNSNTTNSSNSNN

Unobfuscated program:

    push  0
loop:
    dup
    push  0
    dup
    ichr
    get
    push  32
    sub
    dup
    jz    space
    push  38
    sub
    jz    fizz
    push  1
    add
fizz:
    push  0
    dup
    dup
    ichr
    ichr
    ichr
    add
    jmp   loop
space:
    swap
    pchr
    jmp   loop

There's nothing particularly odd about the implementation, the only real golfing is in some strange reuse of temporaries as well as not caring about the unbounded stack growth to skim down some more bytes.


3

Octave, 59 57 53 bytes

@(s)['',bi2de(flip(reshape(s(65<s&s<71)<70,8,[]))')']

This doesn't work on TIO, since the communication toolbox is not implemented. It works fine if you copy-paste it to Octave-online. It's not even close to be working code in MATLAB.

Managed to save two bytes by transposing the matrix after flipping it, instead of the other way around.

Explanation:

@(s)             % Anonymous function that takes a string as input
    ['',<code>]  % Implicitly convert the result of <code> to its ASCII-characters

Let's start in the middle of <code>:

s(65<s&s<71)      % Takes the elements of the input string that are between 66 and 70 (B and F)
                  % This gives a string FBBFFBBFBBBFFFBF...
s(65<s&s<71)<70   % Converts the resulting string into true and false, where F becomes false.
                  % Transformation: FBBFFB -> [0, 1, 1, 0, 0, 1]

Let's call the resulting boolean (binary) vector for t.

reshape(t,8,[])       % Convert the list of 1 and 0 into a matrix with 8 rows, one for each bit
flip(reshape(t,8,[])) % Flip the matrix vertically, since bi2de reads the bits from the wrong end
flip(reshape(t,8,[]))' % Transpose it, so that we have 8 columns, and one row per character
bi2de(.....)'          % Convert the result decimal values and transpose it so that it's horizontal

3

Perl 5, 28 bytes+4 bytes for flags=32 bytes

Run with the flags -040pE

$_=chr oct"0b".y/FB -z/01/dr

-040 sets the record separator to a space so that perl sees each group of FizzBuzzes as a separate line, then loops over those lines, changing F to 0, B to 1, deleting everything else, then converting to binary and from there to ascii.




2

Brain-Flak, 107 bytes

{(((((()()()()){}){}){})({}[{}])()())((){[()](<{}>)}{}<>)<>{(<{}{}{}{}>)<>({}({}){})<>}{}}<>{({}<>)<>}<>

Try it online!

+3 bytes for the -c flag.

Explanation

{                                        For each character in input:
 (((((()()()()){}){}){})({}[{}])()())    Push 32-n and 66-n
 ((){[()](<{}>)}{}<>)<>                  If character is B, push 1 on second stack.  Otherwise, push 0
 {                                       If character is not space:
  (<{}{}{}{}>)                           Burn 3 additional characters
  <>({}({}){})<>                         Multiply current byte by 2 and add previously pushed bit
 }                                       (otherwise, the pushed 0 becomes the new current byte)
 {}                                      Remove character from input
}
<>{({}<>)<>}<>                           Reverse stack for output

2

q/kdb+, 41 40 37 33 bytes

Solution:

{10h$0b sv'66=vs[" ";x][;4*(!)8]}

Example:

q){10h$0b sv'66=vs[" ";x][;4*(!)8]}"FizzBuzzBuzzFizzBuzzFizzFizzFizz FizzBuzzBuzzFizzBuzzFizzFizzBuzz FizzFizzBuzzFizzFizzFizzFizzBuzz"
"hi!"

Explanation:

Split the input string on " " to give distinct lists of FizzBuzz..., index into each of these lists at the first character (ie 0 4 8 ... 28). Return boolean list determined by whether each character is "B" (ASCII 66). Convert these lists to base 10, and then cast result to string.

{10h$0b sv'66=vs[" ";x][;4*til 8]} / ungolfed solution
{                                } / lambda function with x as implicit input
              vs[" ";x]            / split (vs) input (x) on space (" ")
                           til 8   / til 8, the range 0..7 inclusive
                         4*        / vectorised multiplication, 0 1 2 3 => 0 4 8 12
                       [;       ]  / index the 2nd level at these indices (0, 4, 8 ... 28)
           66=                     / 66 is ASCII B, 66="FBBFBFFF" -> 01101000b
     0b sv'                        / join (sv) each row back with 0b (converts from binary)
 10h$                              / cast to ASCII (0x686921 -> "hi!")

1

Haskell, 72 bytes

(>>= \w->toEnum(foldl1((+).(2*))[mod(fromEnum c)5|c<-w,c<'a']):"").words

Try it online!

How it works

            words      -- split input string into words at spaces
(>>=      )            -- map the function to each word and flatten the resulting
                       -- list of strings into a single string
   \w->                -- for each word w
       [  |c<-w,c<'a'] -- take chars c that are less than 'a' (i.e. B and F)
     mod(fromEnum c)5  -- take ascii value of c modulus 5, i.e. convert to bit value
    foldl1((+).(2*))   -- convert list of bit to int
  toEnum(   ):""       -- convert ascii to char.  :"" forces toEnum to be of type String
                       -- now we have a list of single char strings, e.g. ["h","i","!"]        

1

JavaScript ES6 - 98 bytes

too many bytes, but at least readable

Defined as function it is 98 bytes

let s=>s.replace(/(F)|(B)|./g,(c,F,B)=>B?1:F?0:'').replace(/.{8}/g,v=>String.fromCharCode('0b'+v))

test:

"FizzBuzzBuzzFizzBuzzFizzFizzFizz FizzBuzzBuzzFizzBuzzFizzFizzBuzz FizzFizzBuzzFizzFizzFizzFizzBuzz"
.replace(/(F)|(B)|./g,(c,F,B)=>F?0:B?1:'').replace(/.{8}/g,v=>String.fromCharCode('0b'+v))

Explanation:

/(F)|(B)|./

Matches the F and B letters and anything else as Groups

(c,F,B)=>F?0:B?1:''

is a Function that captures the groups , returns a 0 for F and 1 for B , or ''

c is the character matched
F and B are now Parameters!
the 3rd . group is ommitted as parameter

F and B are undefined when the 3rd group is matched
B is undefined when group F is matched

The resulting 0100.. etc string

is cut in slices of 8 bytes

.replace(/.{8}/g,v=>String.fromCharCode('0b'+v))

and processed as 0b binary string


2
Welcome to PPCG! The objective of this challenge is to provide a program or function translating arbitrary FizzBuzz strings. I don' know much JavaScript, but a valid function submission might be s=>s.replace( .... Also please do include a byte count in the Header of your answer.
Laikoni

I cleaned up some of your code formatting for you. Also, you don't need the let, anonymous functions are acceptable.
Shaggy

1

shortC, 35 bytes

i;AW*@&3?*@&9||(i+=i+*s%5):Pi),*s++

Conversions in this program:

  • A - int main(int argc, char **argv){
  • W - while(
  • @ - argv
  • P - putchar(
  • Auto-inserted );}

Heavily based off of Doorknob's answer.


1

APL (Dyalog Classic), 17 bytes

{82DR'B'=⍵∩'BF'}

Explanation

           ⍵∩'BF'    cut, removes all but 'BF' from 
       'B'=          equals 'B' turns it into binary stream   
 82DR              converts into character stream

Try it online!



0

Google Sheets, 94 bytes

=ArrayFormula(JOIN("",CHAR(BIN2DEC(SPLIT(SUBSTITUTE(SUBSTITUTE(A1,"Fizz",0),"Buzz",1)," ")))))

I'm not familiar with FizzBuzz binary but it seems that they're delineated by spaces so this formula relies on that. The logic is pretty simple:

  • Replace Fizz with 0 and Buzz with 1
  • Split the result into an array using a space as a delimiter
  • Convert each element from binary to decimal
  • Replace each element with its ASCII equivalent
  • Join each element without a delimiter

0

Java 8, 117 115 bytes

s->{for(String x:s.split(" "))System.out.print((char)Long.parseLong(x.replace("Fizz","0").replace("Buzz","1"),2));}

I doubt you can do a lot of the fancy regex replacements in Java like most other answers, mainly because you can't do anything with the captured capture-groups in Java-regexes.. (I.e. "$1".charAt(...) or "$1".replace(...) aren't possible for example.)

Explanation:

Try it here.

s->{                          // Method with String parameter and no return-type
  for(String x:s.split(" "))  //  Loop over the input split by spaces:
    System.out.print(         //   Print:
     (char)                   //    Each character
     Long.parseLong(          //    after we've converted each binary-String to a long
      x.replace("Fizz","0").replace("Buzz","1")
                              //    after we've replaced the Fizz/Buzz to 0/1
     ,2));
}                             // End of method

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