ActionScript3 で素数列挙を short coding
ActionScript3 で素数列挙の short coding にチャレンジしてみる。ネタ元はこれ。
for(a=[],b=[],c=1;c++<1E3;)if(!a[c])for(b.push(d=c);d<1E3;a[d+=c]=1);alert("素数" + b);
— javascripterさん (@javascripter) 1月 29, 2010
元々のコードは JavaScript で「エラトステネスのふるい」を短く書いたもの。JavaScript のコードがあるんだから、ActionScript でも同じぐらいで書けるはずと信じてやってみた。
strict 版
まずは、warning が出ないもの。227文字。
package{import flash.display.*;public class C extends Sprite{public function C(){graphics.beginFill(0);for(var a:Array=[],c:int=1,d:int;c++<1E3;)if(!a[c]){for(d=c;d<1E3;)a[d+=c]=1;graphics.drawRect((c%10)*5,int(c/10)*5,5,5)}}}}
出力はこんな感じ。
10個ごとに素数の数字を黒い点で表している。左上が 0 で、右にいくと 2, 3 が連続して素数として現れて、そのあと、5,7 と続く。2段目からは 11, 13, 17, 19 が現れる。
少し考えたら当たり前だと分かるのだけど下一桁が 0,4,6,9の列は素数が1つも現れないし、2,5の列は一番上にしか素数が登場しない。10以上の素数の下一桁は 1,3,7,9 のいずれかなのだ。こうやって図にしてみると、改めて気づかされて面白い。
で、肝心のソースコードのインデントを復元するとこんな感じ。
package{ import flash.display.*; public class C extends Sprite{ public function C(){ graphics.beginFill(0); // 1から1E3(=1000)までループを回す for(var a:Array=[],c:int=1,d:int;c++<1E3;) // 素数かどうか判定 if(!a[c]){ // 素数のとき: // c*2,c*3,c*4... で a のフラグを立てる for(d=c;d<1E3;) a[d+=c]=1; // 該当する位置に四角を描画する graphics.drawRect((c%10)*5,int(c/10)*5,5,5) } } } }
短くするための工夫は色々してある。思いつく範囲で列挙するだけでも
- コンストラクタでは戻り値
:void
を書かなくても warning は出ない - graphics.endFill() がなくても動くのでやらない
- Math.floor() は int() で代用
- 変数宣言は1箇所にまとめる。しかも for の中でやっちゃうことで、var 文の ; を節約できる
- ; を省略できるところは省略しちゃう
といったあたり。
これより短くできるのか気になる。ルールは
- ライブラリは使用せず、Flash がネイティブに提供する API を利用すること
- 素数の表示方法は問わない
といったあたりか。ただ、TextField 使ったら import flash.text.*;
だけでかなりの文字数になるし、BitmapData は初期化と表示に文字数食われるし、Graphicsを使うのが最短な気がしている。
strict じゃない版
warning が出てもいいならもう少し短くできる。210文字。
package{import flash.display.*;public class C extends Sprite{public function C(){for(var g=graphics,a=[],c=1,d;c++<1E3;)if(!a[c]){for(d=c;d<1E3;)a[d+=c]=1;g.beginFill(0);g.drawRect((c%10)*5,int(c/10)*5,5,5)}}}}
いちおう、整形したソースコードを掲載しておく。
package{ import flash.display.*; public class C extends Sprite{ public function C(){ for(var g=graphics,a=[],c=1,d;c++<1E3;) if(!a[c]){ for(d=c;d<1E3;) a[d+=c]=1; g.beginFill(0); g.drawRect((c%10)*5,int(c/10)*5,5,5) } } } }
型宣言しなくてもいい分だけ短くなった。
また、今までは graphics
と2回入力していたが、g=graphics,
の11文字を追加することで、graphics
(8文字) が g の1文字で済むようになった。graphics は2回登場していたので、16文字が13文字に減ったので3文字の節約だ。ただ、そのせいで beginFill() する位置が変化したが、これでも動いてるので問題はないこととする。
まとめ
これ以上短くできるのかな。挑戦者求む。ソースは wonderfl に投稿してある。
- 作者: Ozy
- 出版社/メーカー: 毎日コミュニケーションズ
- 発売日: 2007-08-09
- メディア: 単行本(ソフトカバー)
- Amazon のレビューを見る