0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【JavaScriptで数字禁止縛りCode Golfをする人必見!!!】JavaScriptで数字禁止縛りCode Golfをする際のお役立ち情報まとめ

0
Posted at

はじめに

よくこんなニッチなところにたどり着きましたね(困惑)

どうも、Sei2423です。(初めての自己紹介)

JavaScriptで数字禁止FizzBuzzをしているコードが ↓ これ ↓ くらいしか見つからなかったのでまとめようと思い立ちました。



Javascript 97 chars - no numbers at all

Numbers ? Who needs number when you have Javascript !

a=b=!![]+![],a--,c=b+b;while(++a)e=!(a%(c+c+b)),alert(!(a%(c+b))?e?"FizzBuzz":"Fizz":e?"Buzz":a);

どうやら1~100ではなくずっと続きそうですね

そもそもcodegolfとしてやってる人見かけたことないけど今回書いたコードは多分FizzBuzz in JavaScript without using digitsでは最短になっていると思われる

数字縛り

突然ですが質問です。

Q. 数字禁止縛りというものを知っていますか?

A. その名の通り、コード内に0~9が含まれていてはいけないという縛りです

英語圏でno numbersとかno digits challengeとかdigits restrictedとかwithout using numbersとか書かれてる奴ですね

情報一覧

わざわざこんなのを見に来る人に普通のショートコードテクニック等は必要ないという前提で始めます!


一般的なテクニックを知りたい方へ ↓


JSFUCKの情報が知りたい方へ ↓

あとは-~とかが分かっていれば多分大丈夫!!

数字禁止の特徴

  • JSFUCKと違って英語が使える
  • ""{}が使える
  • 算術演算子かbit演算子が使える
  • evalを使わないのでいいので安全性が担保される!!!!(絶対にそこではない)

真偽値とか

・ True, False

!"";  // true
![];  // false  {}も可

JSFUCKとは違い""が使えるためtruefalseがそれぞれ1文字短く表せる。

Truthy Falsy

[];   // Truthy  {}も可
"";   // Falsy

実はwhile(true)while([])に代替可能である。

・ undefined

"".a;  // undefined  []も可

数字編

・ 0, 1, -1

+"";   // 0   []も可
+!"";  // 1
-~"";  // 1   [], {}も可
~"";   // -1  [], {}も可

-11より短いため次のような場面では-1を反転する方が有効な場面がある。

・ 99, 100, 101

~(~""+"e"+-~!"");  // 99
-(~""+"e"+-~!"");  // 100
-~""+"e"+-~!"";    // '1e2'

-~-(~""+"e"+-~!"");  // 101
+!""+"e"+-~!""|!"";  // 101
-~(+!""+"e"+-~!"");  // 101

100では上で言った通り、+(-!""...)ではなく-(~""...)となっている

条件編

定数編

次の式のexprの式を変えることで条件を変えるものとします。

function expr(i) {
    return /* 式 */;
}

for(let i = []; expr(++i);) {  // i = 1 ~ n;
    console.log(`\u001b[35m${i}\u001b[0m: ${expr(i)}`);  //i: expr(i)
}

・ 99, 100, 101

~-~-~-(i>>-~i);  // (0|1) ~ 99
~-~-~-(i>>i);    // (0|1) ~ 100
~-~-~-(i>>~-i);  // (0|1) ~ 101

実践

じゃあ、ここからは上の知識を使ったり使わなかったりしながらいろいろな問題を解いてみましょう

私より短いコードを書けた場合はコメントまでご連絡ください。IDと一緒に追記として記載いたします。

FizzBuzz

for(f=~(i=''),b=--f+--f;i++<b*b*~b;console.log(i%b?x||i:x+'Buzz'))x=i%f?'':'Fizz'

81byte

解説

まず、有名なJavaScriptのFizzBuzz最短コードを用意します

for(i=0;++i<101;console.log(i%5?x||i:x+'Buzz'))x=i%3?'':'Fizz'

多分これで大体わかります()

ということで私のコードを展開して見て見ましょう

for(
    f=~(i=''), ...
    b=--f+--f; ...

    i++<b*b*~b;  ...

    console.log(i%b?x||i:x+'Buzz')

)x=i%f?'':'Fizz'

i=''の式としての値は代入結果になるので''
''は数値化すると0なのでfの値~''-1

i = ''   // ''
f = ~''  // -1

がんばってf=-3, b=-5に調整
--f1つ目は-2--f2つ目は-3
b-2 + -3-5

b = --f + --f  // b = -5, f = -3

左辺はi
右辺は-5 * -5 * ~-5 = 25 * 4 = 100
~-~-~-(i>>i)より短かったためこちらを採用
++i<101i++<100は大体同義

i++ < b * b * ~b;  // i < 100

あとは元のコードと一緒です

あとがき

実は数字縛りって言う縛りの欠陥なのですが、

そもそもコードにおいて1, 0, -1か100以外の数字を使うことがそれほどなく あってもforかカウンターとかの初期値がほとんどで、
それなのに短縮が難しくなるのは大きい数字を作るときくらいしかなく、

そうなると

「FizzBuzzくらいしかやることがない」


という事でした。
まあまた何かがあったら追記します

終わり!!!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?