Fizz Buzz to Text


29

前書き

フィズバズのトレンドはどこから来たのか私は特に知りません。ミームか何かかもしれませんが、やや人気があります。

チャレンジ

今日の仕事は、Fizz Buzzをそれぞれバイナリ(0、1)に変換し、そのバイナリをテキストに変換することです。かなり標準的なもの。

それはどのように機能しますか?

FizzBu​​zzBuzzFizzBu​​zzFizzFizzFizz FizzBu​​zzBuzzFizzBu​​zzFizzFizzBu​​zzは01101000 01101001に変換され、その後「hi」に変換されます

制約

  • 入力は、バイナリの観点ではフィズバズです(以下の例を参照)。
  • 出力はテキストでなければなりません。
  • FizzBu​​zz入力が正しいと仮定できます。
  • これは、最短バイトが勝ちます。

入力

FizzBu​​zzBuzzFizzBu​​zzFizzFizzFizzFizzFizzBu​​zzBuzzFizzBu​​zzFizzFizzBu​​zz FizzFizzBu​​zzFizzFizzFizzFizzBu​​zz

出力

"こんにちは!"


15
ミーム?これは初等(小学校)の学校ゲームです
ベータディケイ

2
入力にスペースを含めることはできませんか?
-HyperNeutrino

2
しかし、そのスペースを取ることはできませんか?そのスペースを入力する必要がなければ、3バイト節約できます。
ハイパーニュートリノ


8
Joelが参照している「もう1つのブログ」である@dmckeeは、Stackoverflowのもう1人の創始者である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++あり、カンマ演算子は2番目の引数の値のみを返します。したがって、終了する前に、これは文字列*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つの最下位ビットのいずれかを持っていない唯一の文字であるが、我々は、ビット単位のANDできると文字0b11の文字がそれ以外のスペースやNULとゼロでない場合には、ゼロを取得します。

深く掘り下げると、最初の「if」ブランチで、次のいずれかのキャラクターができましたFBizuFsとBsのアキュムレータのみを更新することを選択したため、sを除外する方法が必要でしたizu。便利なことにFB両方とも2番目、3番目、または7番目の最下位ビットのみが設定されており、他のすべての数値には少なくとも1つの他のビットが設定されています。実際、それらはすべて最初または4番目の最下位ビットを持っています。したがって、ビットごとにANDを使用してANDを実行できます0b00001001。これは、9でありFBandが0で、それ以外の場合はゼロではありません。

For があることを確認したら、is およびis であるため、それらのモジュラス5を取得することによりB0およびにマッピングできます。次にスニペット1F70B66

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を使用した素敵なトリック。
コンピュトロニウム

これは本当にすごいです。Cは正しかった!
グスタボマシエル

13
物事を正しく行うことについて言えば、これは私の控えめな意見では、コードとゴルフの答えがどのように行われるべきかということです。あなたは、他のより実用的な状況で役立つかもしれない言語について実際に人々に何かを教える完全で、よく書かれた説明を伴う、賢明で洞察力のあるソリューションを投稿します。
コーディグレイ

3
@CodyGrayまさにこれ。私が頻繁に訪れるSEのトップにCode Golfが載っていない理由の1つは、多くの答えが「コードはここにある」だけだからです。それは言語に精通している人にとってはクールですが、それは私にとってはノイズのように見えます。私はそれが明らかになったので、ここのような説明を見たい方法私はほとんどの人が、コード自体よりも多く、より面白いと思うだろう。ちょうど私の2セント...
クリスクレフィス

非常に良いビットハックですが、MSB(左)からLSB(右)までビットをカウントしますか?IMOのみ正気8ビットバイトのビットカウントする方法(または128ビットSIMDベクトルを、または何でも)さLSB =からは7ビットがMSBにビット0
ピーターコルド

10

ゼリー、9バイト

Ḳm€4O%5ḄỌ

オンラインでお試しください!


賢く、平らにする必要はありませんでした。いいね
ハイパーニュートリノ

@HyperNeutrinoあなたのコメントに注意してください、私は少し違うアルゴリズムを使って、重複を避けています(技術的には好きではありませんが)。
エリックアウトゴルファー

@downvoter:ドライブバイダウン投票の前にこれをテストしましたか?
エリックアウトゴルファー


9

Pythonの3169の 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

少し前にこれと似たようなことをしましたが、それはただコピーアンドペーストの問題で、それをFizzBu​​zzに変更しました:P
Martmists

1
ああ、それは説明します。:Pしかし、あなたはアウトゴルフされました; _;
ハイパーニュートリノ


1
おっと、それは再びやった、85で、この時間をバイトlambda機能
氏Xcoder

8

JavaScript(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} ` です。
アーナルド

7

Japt26 24 19 17バイト

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

オンラインでお試しください!

@Shaggyのおかげで2バイト節約、&のおかげで2バイト節約 @ ETHproductionsの節約

説明

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 })をに置き換えることができÃます。確かにそれ以上のものを保存する必要がありますが、私はそれを自分の携帯電話でうまく機能させることはできません。
シャギー

1
Japtをご利用いただきありがとうございます!で置き換えることò4...q n2で数バイト節約できますë4...n2(最初の項目のみを返すë4ことをò4除き、と同じことを行います;奇妙なことに、文書化されていないようです)
-ETHproductions

1
@ETHproductions Japtを作成してくれてありがとう!
パウエルズ

6

Ruby、65 63 60バイト

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

これは、入力を受け取り、文字列として出力を提供する匿名プロシージャです。

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

JavaScript(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>


私は信じている+よりも短くなっているparseInt
KritixiのLithos

2
+(m[0]<"F")短縮できると思うm<"F"|0
-ETHproductions

5

Perl 5、33バイト

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

入力の「F」と「B」をそれぞれ0と1に置き換え、他の文字を削除します。次に、perlのpack関数を使用して、このビット文字列をASCII文字に変換します。


うわー、これは私のPerl 5の試みの約半分のサイズにまで削減されます。称賛。
デビッドコンラッド

1
-p0コマンドラインオプションを使用すると、これをかなり短くすることができると思います(これにより<>=~r、入力が不要になり、を使用せ$_=ずに使用できるようになりますprint())。改行の処理方法によっては、が必要ない場合もあります0。(コマンドラインオプションのペナルティを回避したい場合でもsayprint。より短くなります。)

@Chris俺じゃない、faubiguy's。しかし、ありがとう。;)
デビッドコンラッド

@DavidConrad私の悪い笑。
クリス

1
必ず0も必要ありません。-pフラグを使用するだけ$_=pack'B*',y/FB -z/01/drで、プログラムのスコアが26バイトに下がります。
クリス

5

パイソン290の 83 82 81バイト

完全に人間のおかげで-1バイトマートミストの
おかげで-1バイトジョナサンフレッチの
おかげで-1バイト

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

オンラインでお試しください!



あなたは回してバイトを保存することができます*1 for*1for
Martmists

*1ブール値から整数への変換に使用するため、+:を使用してバイトを保存(l<'D')*1forできます+(l<'D')for
ジョナサンフレッチ

3

空白、123バイト

目に見える表現:

SSNNSSNSNSSSNSNSTNTSTTTSSSTSSSSSNTSSTSNSNTSSNSSSTSSTTSNTSSTNTSTNSSSTNTSSSNSSTNSSNSNSSNSTNTSTNTSTNTSTSSSNSNNNSSSNSNTTNSSNSNN

難読化されていないプログラム:

    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

実装については特に奇妙なことはありません。唯一の本当のゴルフは、一時的なものを奇妙に再利用することであり、無制限のスタックの成長を気にせずにさらにバイトを減らすことです。


3

オクターブ59 57 53バイト

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

通信ツールボックスが実装されていないため、これはTIOでは機能しません。コピーしてOctave-onlineに貼り付けると正常に動作します。MATLABで動作するコードに近いことすらありません。

他の方法ではなく、マトリックスを反転した後に転置することにより、2バイトを節約することができました。

説明:

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

の途中から始めましょう<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]

の結果のブール(バイナリ)ベクトルを呼び出しましょう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バイト+フラグの場合4バイト= 32バイト

フラグで実行 -040pE

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

-040 perlがFizzBu​​zzesの各グループを個別の行と見なし、Fを0に、Bを1に、他のすべてを削除してからバイナリに変換し、そこからasciiに変換するように、レコードセパレーターをスペースに設定します。




2

Brain-Flak、107バイト

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

オンラインでお試しください!

+3バイト -cフラグ。

説明

{                                        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バイト

溶液:

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

例:

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

説明:

入力文字列を分割し" "て、の個別のリストをFizzBuzz...作成し、これらの各リストの最初の文字(つまり0 4 8 ... 28)にインデックスを付けます。各文字が"B"(ASCII 66)かどうかによって決定されるブールリストを返します。これらのリストを基数10に変換し、結果を文字列にキャストします。

{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バイト

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

オンラインでお試しください!

使い方

            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バイト

バイトが多すぎるが、少なくとも読みやすい

関数として定義されている98バイトです

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

テスト:

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

説明:

/(F)|(B)|./

グループとしてFおよびBの文字とその他のものに一致します。

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

はグループをキャプチャする関数で、Fの場合は0、Bの場合は1を返します

cは
Fに一致する文字で、Bはパラメーターになりました!
3番目グループはパラメーターとして省略されます

FとBはundefined3番目のグループが一致したとき
BはundefinedグループFが一致したとき

結果の0100 .. etc文字列

8バイトのスライスにカットされます

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

0b バイナリ文字列として処理されます


2
PPCGへようこそ!この課題の目的は、任意のFizzBu​​zz文字列を翻訳するプログラムまたは機能を提供することです。JavaScriptはあまり知りませんが、有効な関数サブミットはかもしれませんs=>s.replace( ...。また、回答のヘッダーにバイトカウントを含めてください。
ライコニ

コードの書式設定の一部を整理しました。また、を必要としませんがlet、匿名関数は受け入れられます。
シャギー

1

shortC、35バイト

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

このプログラムでの変換:

  • A - int main(int argc, char **argv){
  • W - while(
  • @ - argv
  • P - putchar(
  • 自動挿入 );}

Doorknobの回答に大きく基づいています。




0

Googleスプレッドシート、94バイト

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

私はFizzBu​​zzバイナリに精通していませんが、スペースで区切られているようなので、この式はそれに依存しています。ロジックは非常に簡単です。

  • 交換するFizz0してBuzz1
  • スペースを区切り文字として使用して、結果を配列に分割します
  • 各要素を2進数から10進数に変換します
  • 各要素を対応するASCIIに置き換えます
  • 区切り文字なしで各要素を結合します

0

Java 8、117 115バイト

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

主にJava正規表現でキャプチャされたキャプチャグループで何もできないため、他のほとんどの答えのようにJavaで多くの派手な正規表現の置換を行うことはできないと思います。(たとえば、"$1".charAt(...)または"$1".replace(...)できない)

説明:

ここで試してみてください。

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.