Language detail: JavaScript
Coverage: 75.13%
|
number of '+' ratings |
contribution for coverage |
Unsolved challenges
- 年賀はがきの当せん番号 (Nested Flatten)
- 箱詰めパズルの判定 (Nested Flatten)
- 関数やメソッドのソースの平均行数 (Nested Flatten)
- コレクションの実装 (Nested Flatten)
- 化学反応式の完成 (Nested Flatten)
codes
居眠り床屋問題
(Nested
Flatten)
JavaScriptで。マルチスレッドライブラリのConcurrent.Threadを使用しました。
床屋と客の2スレッド構成です。スレッドIDに相当するものはない(と思う)ので、自分で付けました。
寝ていますフラグがないと、床屋が起きているときに notify が飛んで、床屋の機嫌を損ねて(=エラー終了)しまいます。
<実行例>
[床屋] 床屋、眠る
[ 客 ] 来店 1
[床屋] 床屋、目覚める
[床屋] 散髪開始 1
[ 客 ] 来店 2
[ 客 ] 来店 3
[床屋] 散髪完了 1
[床屋] 散髪開始 2
[床屋] 散髪完了 2
[床屋] 散髪開始 3
[ 客 ] 来店 4
[ 客 ] 来店 5
[ 客 ] 来店 6
[ 客 ] 満席で立ち去る 6
[床屋] 散髪完了 3
[床屋] 散髪開始 4
[ 客 ] 来店 7
[ 客 ] 来店 8
[ 客 ] 満席で立ち去る 8
[床屋] 散髪完了 4
[床屋] 散髪開始 5
[床屋] 散髪完了 5
[床屋] 散髪開始 7
[床屋] 散髪完了 7
[床屋] 床屋、眠る
[ 客 ] 来店 9
[床屋] 床屋、目覚める
[床屋] 散髪開始 9
[ 客 ] 来店 10
[ 客 ] 来店 11
[ 客 ] 来店 12
[ 客 ] 満席で立ち去る 12
[床屋] 散髪完了 9
[床屋] 散髪開始 10
[ 客 ] 来店 13
[ 客 ] 来店 14
[ 客 ] 満席で立ち去る 14
[ 客 ] 来店 15
[ 客 ] 満席で立ち去る 15
[床屋] 散髪完了 10
[床屋] 散髪開始 11
[ 客 ] 来店 16
[床屋] 散髪完了 11
[床屋] 散髪開始 13
[床屋] 散髪完了 13
[床屋] 散髪開始 16
[床屋] 散髪完了 16
[床屋] 床屋、眠る
床屋と客の2スレッド構成です。スレッドIDに相当するものはない(と思う)ので、自分で付けました。
寝ていますフラグがないと、床屋が起きているときに notify が飛んで、床屋の機嫌を損ねて(=エラー終了)しまいます。
<実行例>
[床屋] 床屋、眠る
[ 客 ] 来店 1
[床屋] 床屋、目覚める
[床屋] 散髪開始 1
[ 客 ] 来店 2
[ 客 ] 来店 3
[床屋] 散髪完了 1
[床屋] 散髪開始 2
[床屋] 散髪完了 2
[床屋] 散髪開始 3
[ 客 ] 来店 4
[ 客 ] 来店 5
[ 客 ] 来店 6
[ 客 ] 満席で立ち去る 6
[床屋] 散髪完了 3
[床屋] 散髪開始 4
[ 客 ] 来店 7
[ 客 ] 来店 8
[ 客 ] 満席で立ち去る 8
[床屋] 散髪完了 4
[床屋] 散髪開始 5
[床屋] 散髪完了 5
[床屋] 散髪開始 7
[床屋] 散髪完了 7
[床屋] 床屋、眠る
[ 客 ] 来店 9
[床屋] 床屋、目覚める
[床屋] 散髪開始 9
[ 客 ] 来店 10
[ 客 ] 来店 11
[ 客 ] 来店 12
[ 客 ] 満席で立ち去る 12
[床屋] 散髪完了 9
[床屋] 散髪開始 10
[ 客 ] 来店 13
[ 客 ] 来店 14
[ 客 ] 満席で立ち去る 14
[ 客 ] 来店 15
[ 客 ] 満席で立ち去る 15
[床屋] 散髪完了 10
[床屋] 散髪開始 11
[ 客 ] 来店 16
[床屋] 散髪完了 11
[床屋] 散髪開始 13
[床屋] 散髪完了 13
[床屋] 散髪開始 16
[床屋] 散髪完了 16
[床屋] 床屋、眠る
see: JavaScriptへのマルチスレッド・プログラミングの導入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | <html>
<head>
<script type="text/javascript" src="Concurrent.Thread-full-20090713.js"></script>
<script type="text/javascript">
var queue = []; //客行列
var barber; //床屋スレッド
var customer; //客スレッド
var barber_is_sleeping = false; //寝ていますフラグ
//床屋スレッド本体
var barber_func = function() {
while (true) {
while (queue.length > 0) {
var cust = queue[0];
log(barber, "散髪開始 " + cust.toString());
Concurrent.Thread.sleep(Math.random()*300+100);
log(barber, "散髪完了 " + cust.toString());
queue.shift();
}
log(barber, "床屋、眠る");
try {
barber_is_sleeping = true;
stop();
} catch ( ex ) {
log(barber, "床屋、目覚める");
barber_is_sleeping = false;
}
}
};
//客スレッド本体
var customer_func = function() {
var count = 0;
while (count < 16) {
count++;
if (count != 9) {
Concurrent.Thread.sleep(Math.floor(Math.random()*200));
} else {
Concurrent.Thread.sleep(1200);
}
log(customer, "来店 " + count.toString());
if (queue.length >= 3) {
log(customer, "満席で立ち去る " + count.toString());
} else {
queue.push(count);
if (barber_is_sleeping) {
barber.notify("wake!");
}
}
yield();
}
};
//ログ出力
function log(t, s) {
var o = document.getElementById('result');
o.innerHTML += '[' + t.ID + '] ' + s + "<br>";
}
function init() {
barber = Concurrent.Thread.create(barber_func);
barber.ID = "床屋";
customer = Concurrent.Thread.create(customer_func);
customer.ID = " 客 ";
}
</script>
</head>
<body onload="init();">
<div id="result"></div>
</body>
</html>
|
バイナリクロック
(Nested
Flatten)
1 | javascript:alert(function(t){return t>0?arguments.callee(t/60|0)+'\n'+('00000'+(t%2560).toString(2)).slice(-6).replace(/1/g,'■').replace(/0/g,'□'):''}(((new Date().getTime()/1000|0)+32400)%2586400))
|
Hello, world!
(Nested
Flatten)
まだWindows Script Hostを使ったものが出ていないようなので。
1 | WScript.Echo('Hello, world!');
|
Twitterへの投稿
(Nested
Flatten)
Windows Script Hostで動きます。初めはVBScriptを使っていましたが、URLエンコードのためにJavaScirptへ移行しました。ところで、JavaScriptは使い慣れていないので、encodeURIComponentとencodeURIの違いが分かりませんでした。間違っていたらごめんなさい。
1 2 3 4 5 6 7 8 9 10 11 12 | function twitte(id, password, message)
{
var req = new ActiveXObject("MSXML2.XMLHTTP");
var url = "http://twitter.com/statuses/update.xml?status=" + encodeURIComponent(message);
req.open("POST", url, false, id, password);
req.send();
return req;
}
r = twitte("なまえ", "パスワード", "へろー");
WScript.Echo(r.responseText);
WScript.Echo(r.status);
|
いちばん長いしりとり
(Nested
Flatten)
総当り法を取ると重くて動かないので、残集団の中で最大数を締める文字で終わるような単語を選択するようにしてみました。
しりとり開始の単語をランダムで選ぶ形式ですが、350前後までつながるのを確認。
選択対照の単語リストはテキストエリアに貼り付けて使用します。
リストの文字区切りはtab,改行,半角スペースで指定。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | <html>
<head>
<meta http-equiv="content-type" content="text/html;charset=shift_jis">
<script type="text/javascript"><!-- //
ls0={};
ls0.wordmap=null;
ls0.counter=null;
ls0.getWordList = function(){
var str = document.getElementById("ls0_ta").value;
str = str.replace(/(\t|\r|\n)/g, " ");
str = str.replace(/ +/g, " ");
str = str.replace(/ +$/g, "");
return str.split(" ");
};
ls0.lastChar = function(word){ return word.charAt(word.length-1); };
ls0.chainSort = function(a,b){
if(!a || !b){ return (!a) ? ( (!b) ? 0 : 1 ) : -1; }
var a0 = ls0.lastChar(a);
var b0 = ls0.lastChar(b);
if(!ls0.counter[a0] || !ls0.counter[b0]){
return (!ls0.counter[a0]) ? ((!ls0.counter[b0])?0:1) : -1;
}
return ls0.counter[b0]-ls0.counter[a0];
};
ls0.execute = function(){
var result=document.getElementById("ls0_result");
result.innerHTML="";
ls0.counter=[];
ls0.wordmap=[];
var indexes=[];
var arr = ls0.getWordList();
for(var i = 0; i < arr.length; i++){
var c = arr[i].charAt(0);
if(!ls0.counter[c]){
ls0.counter[c]=0;
ls0.wordmap[c]=[];
indexes.push(c);
}
ls0.counter[c]++;
ls0.wordmap[c].push(arr[i]);
}
for(var i=0;i<indexes.length; i++){
var c = indexes[i];
ls0.wordmap[c] = ls0.wordmap[c].sort(ls0.chainSort);
}
var pos = Math.floor(Math.random()*arr.length);
var word = arr[pos];
arr=null;
var longest = ls0.getLongest(word);
for(var i = 0; i < longest.length; i++){
var div = document.createElement("div");
div.innerHTML=i+":"+longest[i];
result.appendChild(div);
}
};
ls0.getLongest = function(word){
var longest=[];
var c0 = word.charAt(0);
var cz = ls0.lastChar(word);
ls0.counter[c0]--;
for(var i = 0;i < ls0.wordmap[c0].length;i++){
if(!ls0.wordmap[c0][i]){ continue; }
if(ls0.wordmap[c0][i]!=word){ continue; }
ls0.wordmap[c0][i]=null;
break;
}
//
if(ls0.counter[cz]&&ls0.counter[cz]>0){
ls0.wordmap[cz]=ls0.wordmap[cz].sort(ls0.chainSort);
for(var i = 0; i < ls0.wordmap[cz].length; i++){
if(!ls0.wordmap[cz][i]) continue;
longest = ls0.getLongest(ls0.wordmap[cz][i]);
break;
}
}
longest.unshift(word);
return longest;
};
// --></script>
</head>
<body>
<div>
<input type="button"
onclick="javascript:ls0.execute()"
value="start" />
</div>
<div>
<textarea id="ls0_ta" cols="50" rows="10"></textarea>
</div>
<div id="ls0_result"></div>
</body>
</html>
|
バイナリクロック
(Nested
Flatten)
誤差が出ないように修正。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="ja">
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<meta http-equiv="content-script-type" content="text/javascript">
<meta http-equiv="content-style-type" content="text/css">
<title>Binary Clock</title>
<style type="text/css">
#clock span{
display: block;
}
</style>
<script type="text/javascript">
var $ = function(id){ return document.getElementById(id); };
var getBinary = function(num){
var bNum = '';
while(num >= 2){
var mod = num % 2;
num = (num - mod) / 2;
bNum = mod + '' + bNum;
}
bNum = num + '' + bNum;
return bNum;
};
var getBinaryClockStr = function(num, length){
var result = '';
var bNum = getBinary(num);
while((bNum + '').length < length){
bNum = '0' + bNum;
}
for(var i=0; i<(bNum+'').length; i++){
result += bNum.substr(i,1) == '1' ? '■' : '□';
}
return result;
};
var fixTime = function(miliSec){
return miliSec < 501 ? miliSec : -(1000-miliSec);
};
window.onload = function(){
var g = new Date();
var setTime = function(){
var d = new Date();
g = new Date(g.getTime()+1000);
$('hour').innerHTML = getBinaryClockStr(g.getHours(),5);
$('minute').innerHTML = getBinaryClockStr(g.getMinutes(),6);
$('second').innerHTML = getBinaryClockStr(g.getSeconds(),6);
setTimeout(setTime, 1000-fixTime(d%1000));
}
setTime();
};
</script>
</head>
<body>
<p id="clock"><span id="hour"></span><span id="minute"></span><span id="second"></span></p>
</body>
</html>
|
ラングトンのアリの描画
(Nested
Flatten)
出題者によるデモが初期読み込み時に重かったので、改編してみました。
おまけにアリ自体も最大5匹まで増量可能だったり。
ちなみにOperaだとCSSのエラーで動かないっぽいのが難点ですorz
see: サンプル
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 | <html>
<head>
<meta http-equiv="content-type" content="text/html;charset=shift_jis">
<title>Langton's Ant</title>
<script type="text/javascript"><!-- //
langton={};
langton.Direction=function(x,y){ this.x=(x)?x:0; this.y=(y)?y:0; };
langton.Direction.prototype={
x : 0,
y : 0,
equals : function(test){
return (this.x==test.x)&&(this.y==test.y);
},
change : function(dif){
var val=langton.Direction.next(this,dif);
this.x=val.x;
this.y=val.y;
return this;
}
};
langton.Direction.NORTH=new langton.Direction(0,-1);
langton.Direction.SOUTH=new langton.Direction(0,1);
langton.Direction.EAST=new langton.Direction(1,0);
langton.Direction.WEST=new langton.Direction(-1,0);
langton.Direction.CYCLE=[
langton.Direction.NORTH,
langton.Direction.EAST ,
langton.Direction.SOUTH,
langton.Direction.WEST
];
langton.Direction.FORWORD=0;
langton.Direction.RIGHT=1;
langton.Direction.BACKWORD=2;
langton.Direction.LEFT=3;
langton.Direction.next=function(current,change){
var i = 0;
for( ; i < langton.Direction.CYCLE.length; i++){
if(current.equals(langton.Direction.CYCLE[i])){ break; }
}
i+=change;
i%=langton.Direction.CYCLE.length;
return langton.Direction.CYCLE[i];
};
langton.Ant=function(){};
langton.Ant.prototype={
x : -1,
y : -1,
direction : null,
color : null,
go : function(lr){
this.direction=this.direction.change(lr);
this.x+=this.direction.x;
this.y+=this.direction.y;
if(this.x==langton.Canvas.rowsize){ this.x=0; }
if(this.x<0){ this.x=langton.Canvas.rowsize-1; }
if(this.y==langton.Canvas.rowsize){ this.y=0; }
if(this.y<0){ this.y=langton.Canvas.rowsize-1; }
return this;
},
eat : function(cell,isblack){
var color = (isblack)?this.color:langton.Canvas.BLACK;
cell.style.backgroundColor=color;
},
action : function(cells){
var index = this.y*langton.Canvas.rowsize + this.x;
if(!cells[index]){
cells[index]=langton.Canvas.prepareCell();
cells[index].style.position="absolute";
cells[index].style.top=(this.x*3)+"px";
cells[index].style.left=(this.y*3)+"px";
}
var isblack=(cells[index].style.backgroundColor==langton.Canvas.BLACK);
this.eat(cells[index],isblack);
var choice = (isblack) ? langton.Direction.RIGHT
: langton.Direction.LEFT;
this.go(choice);
return this;
}
};
langton.Canvas={};
langton.Canvas.body=null;
langton.Canvas.counter=null;
langton.Canvas.rowsize=100;
langton.Canvas.cells=[];
langton.Canvas.clear=function(){
if(langton.Canvas.counter){
langton.Canvas.counter.value=0;
langton.Canvas.counter=null;
}
if(langton.Canvas.body){
langton.Canvas.body.innerHTML="";
langton.Canvas.body=null;
}
langton.Canvas.ants=[];
langton.Canvas.cells=[];
};
langton.Canvas.ants=[];
langton.Canvas.BLACK="black";
langton.Canvas.WHITE="white";
langton.Canvas.BLUE="blue";
langton.Canvas.RED="red";
langton.Canvas.YELLOW="yellow";
langton.Canvas.GREEN="green";
langton.Canvas.COLORS=[
langton.Canvas.WHITE,
langton.Canvas.BLUE,
langton.Canvas.RED,
langton.Canvas.YELLOW,
langton.Canvas.GREEN
];
langton.Canvas.prepareCell=function(){
var div = document.createElement("div");
langton.Canvas.body.appendChild(div);
div.style.width="3px";
div.style.height="3px";
div.style.backgroundColor=langton.Canvas.BLACK;
return div;
};
langton.Canvas.addAnt=function(){
if(langton.Canvas.ants.length < langton.Canvas.COLORS.length){
var ant =new langton.Ant();
ant.x=Math.floor(Math.random()*langton.Canvas.rowsize);
ant.y=Math.floor(Math.random()*langton.Canvas.rowsize);
ant.color=langton.Canvas.COLORS[langton.Canvas.ants.length];
var dirid = Math.floor(Math.random()*langton.Direction.CYCLE.length);
var dir = langton.Direction.CYCLE[dirid];
ant.direction=new langton.Direction(dir.x,dir.y);
langton.Canvas.ants.push(ant);
};
};
langton.Action=function(){
if(!langton.Canvas.body){
langton.Canvas.body=document.getElementById("canvas");
}
if(langton.Canvas.ants.length==0){
langton.Canvas.addAnt();
}
for(var i = 0; i < langton.Canvas.ants.length; i++){
langton.Canvas.ants[i].action(langton.Canvas.cells);
}
if(!langton.Canvas.counter){
langton.Canvas.counter=document.getElementById("counter");
}
var value = parseInt(langton.Canvas.counter.value,10)+1;
langton.Canvas.counter.value=value;
};
/* -------------------------------------------------------------------------------- */
langton.timer=0;
langton.isTimerOn=false;
langton.startTimer=function(){
langton.isTimerOn=true;
document.getElementById("run").disabled=true;
document.getElementById("clear").disabled=true;
langton.timer = setInterval(langton.executeTimer, 1);
};
langton.stopTimer=function(){
langton.isTimerOn=false;
};
langton.executeTimer=function(){
if(langton.isTimerOn) langton.Action();
else{
clearInterval(langton.timer);
document.getElementById("run").disabled=false;
document.getElementById("clear").disabled=false;
return 0;
}
};
function test(){
langton.Action();
}
// --></script>
<style type="text/css">
#canvas{
border: 1px solid #999;
width: 300px;
height: 300px;
background-color: black;
}
</style>
</head>
<body>
<p>
<input type="button"
value="run"
onclick="langton.startTimer();"
id="run" />
<input type="button"
value="add"
onclick="langton.Canvas.addAnt();" />
<input type="button"
value="stop"
onclick="langton.stopTimer();" />
<input type="button"
value="clear"
onclick="langton.Canvas.clear()"
id="clear" />
<input type="text" id="counter" disabled value=0 />
</p>
<div id="canvas" style="position:relative"></div>
</body>
</html>
|
アリの動作をどう書くかという話じゃなく、余談にはなりますが、参考ページのブログエントリに書かれていたビットマップ表現と効率について。
DOMのあるノード直下に非常に多数のノードを作る(兄弟ノードが多すぎる)・それらのノードにアクセスするというのは、速度低下の原因になりがちです。どのくらいの数からどこに影響が出るかは実装によるでしょうが、ノード総数が少々多くなろうとも入れ子・小分けにすることで改善できる場合があります。
添付コードのように変更を加えた場合、Pen4 2.53GHzにおいて時間を計測すると次のようになりました(単位:ms ― 遅いCPUだから差が顕著になっているのであって、今時のCPUではこれほどの改善は見込めないかもしれませんが)。
Firefox 3.5.1:
キャンバス作成(ノード作成)が34,551から1,021へと大幅に改善、アリの行進(ノードアクセス)でも330,770から216,934に改善
Opera 10b1:
キャンバス作成は328から344にと若干遅くなるが、もともとあまり時間が掛かっていない。アリの行進の方は1,188,625から415,312に改善
一方で、テーブル要素にしてしまう方法も試してみましたが、手元の環境ではdiv要素で小分けとほとんど変わりませんでした。セルの色表現を、要素のクラス書き換え・クラスごとにCSSで色指定する方法も試してみたが、こちらでもほとんど変化なし。
DOMのあるノード直下に非常に多数のノードを作る(兄弟ノードが多すぎる)・それらのノードにアクセスするというのは、速度低下の原因になりがちです。どのくらいの数からどこに影響が出るかは実装によるでしょうが、ノード総数が少々多くなろうとも入れ子・小分けにすることで改善できる場合があります。
添付コードのように変更を加えた場合、Pen4 2.53GHzにおいて時間を計測すると次のようになりました(単位:ms ― 遅いCPUだから差が顕著になっているのであって、今時のCPUではこれほどの改善は見込めないかもしれませんが)。
Firefox 3.5.1:
キャンバス作成(ノード作成)が34,551から1,021へと大幅に改善、アリの行進(ノードアクセス)でも330,770から216,934に改善
Opera 10b1:
キャンバス作成は328から344にと若干遅くなるが、もともとあまり時間が掛かっていない。アリの行進の方は1,188,625から415,312に改善
一方で、テーブル要素にしてしまう方法も試してみましたが、手元の環境ではdiv要素で小分けとほとんど変わりませんでした。セルの色表現を、要素のクラス書き換え・クラスごとにCSSで色指定する方法も試してみたが、こちらでもほとんど変化なし。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | <style type="text/css">
#canvas{
border: 1px solid #999;
width: 300px;
height: 300px;
}
/* 子divへのCSS指定を、孫divへの指定にするだけ */
#canvas div div{
width: 3px;
height: 3px;
float: left;
}
</style>
// スクリプト部の変更点はwindow.onloadのコールバックのみ
window.onload = function(){
// キャンバス作成部 セルを表すdivを入れ子に
var canvas = document.getElementById('canvas');
var k = 0;
for(var i=0; i< WORLD_SIZE; i++){
var row = document.createElement('div');
canvas.appendChild(row);
for(var j=0; j< WORLD_SIZE; j++){
var cell = document.createElement('div');
row.appendChild(cell);
earth[k] = new Cell(cell);
k++;
}
}
// 以下変更なし
lang_ant = new Ant();//蟻の誕生
lang_ant.world = earth;//地球に降り立つ
lang_ant.ageDisplay = document.getElementById('step');
document.getElementById('run').disabled = false;
}
|
自分のマシンは CPUが Pentium 4 (2.66GHz)、メモリが 512MBとリ ソースが貧弱なためか、うまく動作してくれませんでした。 なので、 #9331を参考に table要素を利用したものへと書き直して みました。 念のため、以下のブラウザーで動作を確認してあります。 Firefox 2.0.0.6 Internet Explorer 6.0.29 Google Chrome 1.0.154.48 Opera 9.23 Safari 3.1.2 Firefox, Google Chrome, Safariは CPUをほとんど食わないのです が、 Internet Explorerと Operaはともに CPU使用率が高く、動作 も遅かったです。(実装の違いですかね? )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | <html>
<head>
<style type="text/css">
.C_0 { background-color : #ffffff; height : 3px; width : 3px; }
.C_1 { background-color : #000000; height : 3px; width : 3px; }
</style>
<script type="text/javascript">
Function.prototype.repeat =
function (t, o) {
var _ = this;
return setInterval(function () { _.apply(o); }, t);
};
var $ = function (i) { return document.getElementById(i); };
var USER_AGENT = navigator.userAgent.toLowerCase();
var CLASS_NAME = (USER_AGENT.indexOf('msie') > -1) ? 'className' : 'class';
var Colony =
function (w, h) {
this.w = w;
this.h = h;
this.generate =
function () {
var i, j;
document.write('<table border="0" cellpadding="0" cellspacing="0">');
for (j = 0; j < this.h; j++) {
document.write('<tr>');
for (i = 0; i < this.w; i++) document.write('<td id="' + i + '_' + j + '" class="C_0"></td>');
document.write('</tr>');
}
document.write('</table>');
};
};
var Ant =
function (x, y, w, h) {
this.x = x;
this.y = y;
this.dx = -1;
this.dy = 0;
this.w = w;
this.h = h;
this.id = 0;
this.move =
function () {
var C = $(this.x + '_' + this.y);
var c;
var t;
if (this.x < 0 || this.x >= this.w || this.y < 0 || this.y >= this.h) {
alert('DEAD END ...');
clearTimeout(this.id);
return;
}
if (c = ((C.getAttribute(CLASS_NAME)).split('_')[1] ^ 1)) { // 反転
t = this.dx;
this.dx = this.dy;
this.dy = -t;
} else {
t = this.dx;
this.dx = -this.dy;
this.dy = t;
}
C.setAttribute(CLASS_NAME, 'C_' + c);
this.x += this.dx;
this.y += this.dy;
if (!this.id) this.id = this.move.repeat(10, this);
};
};
</script>
</head>
<body>
<script type="text/javascript">
var W = 100, H = 100;
new Colony(W, H).generate();
new Ant(50, 50, W, H).move();
</script>
</body>
</html>
|
キッチンタイマー
(Nested
Flatten)
JavaScriptで。
タイマーが鳴るまでの時間はブラウザーのアドレスバーから以下の
ように指定します。
e.g.
file:///(パス文字列)/240.html?(秒数)
指定した時間が経過した後に鳴る音は、ダイアログがポップアップ
する時に鳴るもので勘弁してください。
Firefox 2.0.0.6, Google Chrome 1.0.154.48, Opera 9.23で動作
を確認しました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | <html>
<body>
<script type="text/javascript">
Function.prototype.repeat =
function (t, o) {
var _ = this;
return setInterval(function () { _.apply(o); }, t);
};
var Timer =
function (t) {
this.id = 0;
this.time = t;
this.tick = function () {
if (!this.id) this.id = this.tick.repeat(1000, this);
document.body.innerHTML = this.time + ' second(s) remaining.';
if (this.time-- == 0) {
alert('!');
clearTimeout(this.id);
}
};
};
window.onload =
function () {
var t = parseInt(location.search.substring(1));
if (!isNaN(t)) new Timer(t).tick();
};
</script>
</body>
</html>
|
バイナリクロック
(Nested
Flatten)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="ja">
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<meta http-equiv="content-script-type" content="text/javascript">
<meta http-equiv="content-style-type" content="text/css">
<title>Binary Clock</title>
<style type="text/css">
#clock span{
display: block;
}
</style>
<script type="text/javascript">
var $ = function(id){ return document.getElementById(id); };
var getBinary = function(num){
var bNum = '';
while(num >= 2){
var mod = num % 2;
num = (num - mod) / 2;
bNum = mod + '' + bNum;
}
bNum = num + '' + bNum;
return bNum;
};
var getBinaryClockStr = function(num, length){
var result = '';
var bNum = getBinary(num);
while((bNum + '').length < length){
bNum = '0' + bNum;
}
for(var i=0; i<(bNum+'').length; i++){
result += bNum.substr(i,1) == '1' ? '■' : '□';
}
return result;
};
window.onload = function(){
var setTime = function(){
var d = new Date();
$('hour').innerHTML = getBinaryClockStr(d.getHours(),5);
$('minute').innerHTML = getBinaryClockStr(d.getMinutes(),6);
$('second').innerHTML = getBinaryClockStr(d.getSeconds(),6);
}
setInterval(setTime, 1000);
};
</script>
</head>
<body>
<p id="clock"><span id="hour"></span><span id="minute"></span><span id="second"></span></p>
</body>
</html>
|
リングノードベンチマーク
(Nested
Flatten)
Pen4 2.53Ghzのにおいて1000ノード1000周をやったとき、Firefox 3.5で1400-1700ms、Operaで600msちょいでした。
蛇足ですが、コメントアウト部はノード網羅の確認用。alertで表示できる文字数には限りがあるし、Firefoxでは最大10000文字で切り捨てるようなので、それにあわせてm,nを減らす必要があります。
see: memo: リングノードベンチマーク
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | var send;
var Node = function () {
var id = 0;
var relayDest, relayMsg;
send = function (msg) {
relayDest = this;
relayMsg = msg;
while (relayDest.receive(relayMsg));
return relayMsg;
}
return function () {
this.id = id++;
this.dest = this;
this.receive = function (msg) {
if (typeof this.count == "number") {
if (this.count == 0) return false;
// msg += "\n" + this.count + ": ";
this.count--;
}
// msg += this.id + " ";
relayDest = this.dest;
relayMsg = msg;
return true;
};
};
}();
Node.prototype.send = send;
var n = 1000, m = 1000;
var ring = [];
ring[0] = new Node();
for (var i = 1; i < n; i++) {
ring[i] = new Node();
ring[i - 1].dest = ring[i];
}
ring[n - 1].dest = ring[0];
ring[0].count = m;
var t = new Date();
var lastMsg = ring[0].send("read me in turn.");
t = new Date() - t;
alert("elapsed time:\n" + t + "[ms]\n\nmessage:\n" + lastMsg);
|
ラングトンのアリの描画
(Nested
Flatten)
ラングトンのアリを描画してください。ラングトンのアリは、以下のような動きをする、セル・オートマトンです。(Wikipediaより引用)
- 黒いマスにアリがいた場合、90°右に方向転換し、そのマスの色を反転させ、1マス前進する。
- 白いマスにアリがいた場合、90°左に方向転換し、そのマスの色を反転させ、1マス前進する。
詳しくはWikipedia等で調べるか、参考ページに拙作のデモがありますのでご覧下さい。
- 黒いマスにアリがいた場合、90°右に方向転換し、そのマスの色を反転させ、1マス前進する。
- 白いマスにアリがいた場合、90°左に方向転換し、そのマスの色を反転させ、1マス前進する。
詳しくはWikipedia等で調べるか、参考ページに拙作のデモがありますのでご覧下さい。
see: JavaScriptでラングトンの蟻
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="ja">
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<meta http-equiv="content-script-type" content="text/javascript">
<meta http-equiv="content-style-type" content="text/css">
<title>ラングトンの蟻</title>
<style type="text/css">
#canvas{
border: 1px solid #999;
width: 300px;
height: 300px;
}
#canvas div{
width: 3px;
height: 3px;
float: left;
}
</style>
<script>
var earth = [];
var WORLD_SIZE = 100;
var lang_ant;
function Ant(){}
Ant.prototype = {
age : 0,
ageDisplay : undefined,
id : undefined,
speed: 200,
direction: [0,-1],//向き。x軸 y軸。最初は上に動く
position: [60,40],//初期位置
world: [],
start: function(){
var self = this;
this.id = setInterval(function(){self.move()}, 1000/this.speed);
},
move: function(){
this.ageDisplay.innerHTML = ++this.age;
this.moveNextCell();
var cell = this.getCellInfo();
var color = cell.getAndToggleColor();
this.setNextDirection(color);
},
moveNextCell: function(){
this.position[0] += this.direction[0];
this.position[1] += this.direction[1];
if(this.position[0] < 0 || this.position[1] < 0 ||
this.position[0] >= WORLD_SIZE || this.position[1] >= WORLD_SIZE){
clearInterval(this.id);
this.die();
}
},
getCellInfo: function(){
var idx = this.position[0] + this.position[1] * WORLD_SIZE;
return this.world[idx];
},
setNextDirection: function(bool){//colorがfalse(白)なら右へ、true(黒)なら左へ転回
if(bool){//黒
var tmp = this.direction[0];
this.direction[0] = this.direction[1];
this.direction[1] = -tmp;
}
else{//白
var tmp = this.direction[0];
this.direction[0] = -this.direction[1];
this.direction[1] = tmp;
}
},
die: function(){
alert('Langton\'s ant is dead.');
throw true;
}
};
function Cell(elm){
this.elm = elm;
}
Cell.prototype = {
elm: undefined,
color: false, //colorは2値なのでbooleanで表す
colorList: ['#FFF','#000'],
getAndToggleColor: function(){
this.color = !this.color;
var i = this.color ? 1 : 0;
this.elm.style.backgroundColor = this.colorList[i];
return !this.color;
}
}
window.onload = function(){
var canvas = document.getElementById('canvas');
var div = '<div></div>';
var inner_canvas = "";
for(var i=0; i< WORLD_SIZE*WORLD_SIZE; i++){
inner_canvas += div;
}
canvas.innerHTML = inner_canvas;
var cells = canvas.childNodes;
for(var i=0; i<cells.length; i++){//世界の誕生
earth[i] = new Cell(cells[i]);
}
lang_ant = new Ant();//蟻の誕生
lang_ant.world = earth;//地球に降り立つ
lang_ant.ageDisplay = document.getElementById('step');
document.getElementById('run').disabled = false;
}
</script>
</head>
<body>
<p><input type="button" value="run" onclick="lang_ant.start();this.disabled=true;" id="run" disabled="disabled"> <span id="step"></span>
<input type="button" value="stop & refresh" onclick="location.reload();"></p>
<div id="canvas"></div>
|
バイナリクロック
(Nested
Flatten)
強引な1linerで
1 | javascript:{String.prototype.pad=function(l,c){var v=this; while(v.length<l){v=c+v;}return v;};d=new Date();alert((d.getHours().toString(2).pad(6,' ')+"\n"+d.getMinutes().toString(2).pad(6,'0')+"\n"+d.getSeconds().toString(2).pad(6,'0')).replace(/0/g,'□').replace(/1/g,'■'))};
|
環境変数の取得
(Nested
Flatten)
WSHのJScriptです。WSHでは、WScript.Shellオブジェクトから取得可能です。
1 2 3 4 5 6 7 | sh = new ActiveXObject('WScript.Shell');
env = sh.Environment;
stdIn = WScript.StdIn;
stdOut = WScript.StdOut;
stdOut.WriteLine('キー名を指定してください');
key = stdIn.ReadLine();
stdOut.WriteLine('%' + key + '% == ' + env(key));
|
LL Golf Hole 1 - tinyurl.comを使ってURLを短縮する
(Nested
Flatten)
参考までに、同じものをJavaScriptで投稿しておきます。WSHで実行するように作っているので、これを試すには拡張子jsを付けて保存したファイルを直接実行してください。Windowsでない方にはごめんなさい。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | function GetTinyUrlString(url)
{
var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
xmlhttp.open("GET", "http://tinyurl.com/api-create.php?url=" + url);
xmlhttp.send();
var result = xmlhttp.responseText;
if (result.toLowerCase() == "error")
{
throw "Tinyurl returns error";
}
return result;
}
WScript.Echo(GetTinyUrlString("http://ll.jus.or.jp/2008/info/xgihyo"))
|
IPv4アドレスのマスクの変換
(Nested
Flatten)
「ipaddr2mask」でアドレス→数値変換。 「mask2ipaddr」で数値→アドレス変換。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | function format(num, dec1, dec2, minlen){
var num1 = new Number(parseInt(num, dec1)).toString(dec2);;
while(num1.length < minlen) num1 = "0" + num1;
return num1;
}
function ipaddr2mask(ipaddr){
var ad = ipaddr.split(".");
var str = "";
for(var i = 0; i < ad.length; i++){
str += format(ad[i],10,2,8);
}
for(var i = str.length-1; i > 0 ; i--){
if(str.charAt(i)!=0){return i+1;}
}
return 0;
}
function mask2ipaddr(mask){
var m1 = format(mask,10,10,1);
var str = "";
while(str.length < 32){ str+= (str.length < m1) ? "1" : "0"; }
var ipaddr = "";
for(var i = 0; i < 4; i++){
if(i > 0){ ipaddr+="."; }
ipaddr+=format(str.substr(i*8, 8),2,10,1);
}
return ipaddr;
}
|
ストレンジアトラクタの描画
(Nested
Flatten)
JavaScriptで Clifford Attractorsを描画してみました。パラメーターを変更することで、 いろいろな形を描画することができます。 Firefox 2.0.0.6, Google Chrome 1.0.154.48, Opera 9.23で動作を確認しました。
see: Clifford Attractors
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | <html>
<head>
<script type="text/javascript">
var $ = function (i) { return document.getElementById(i); };
Function.prototype.repeat =
function (t, o) {
var _ = this;
return setInterval(function () { _.apply(o); }, t);
};
// アトラクター
var Attractor =
function (a, b, c, d) {
var _ = $('canvas');
this.a = a; // パラメーター
this.b = b;
this.c = c;
this.d = d;
this.h = 300; // 高さ
this.w = 300; // 横幅
this.ox = this.w / 2; // 原点
this.oy = this.h / 2;
this.s = (this.w > this.h) ? this.h / 4 : this.w / 4;
this.x = 0; // X座標
this.y = 0; // Y座標
_.setAttribute('height', this.h); _.setAttribute('width', this.w);
this.C = _.getContext('2d'); // 描画コンテキスト
}
Attractor.prototype.draw =
function () {
var x = Math.sin(this.a * this.y) + this.c * Math.cos(this.a * this.x);
var y = Math.sin(this.b * this.x) + this.d * Math.cos(this.b * this.y);
this.C.fillRect(this.ox + x * this.s, this.oy - y * this.s, 1, 1);
this.x = x; this.y = y;
}
window.onload =
function () {
var A = new Attractor(-1.4, 1.6, 1.0, 0.7);
A.draw.repeat(1, A);
};
</script>
</head>
<body>
<canvas id="canvas"></canvas>
</body>
</html>
|
16進数から10進数の変換
(Nested
Flatten)
next >>
初投稿です。
数値文字列として変換してみました。
変換後の最大値はおそらくNumber.MAX_VALUEになるかと。
# とりあえず4-500桁ぐらいまでは動作検証しました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | /* --------------------------------------------------------------------------- */
String.prototype.toCharArray=function(){
var arr = new Array(this.length);
for(var i = 0; i < this.length; i++){ arr[i] = this.charAt(i); };
return arr;
};
/* --------------------------------------------------------------------------- */
function add(strnum1, strnum2){
var arr1 = strnum1.toCharArray().reverse();
var arr2 = strnum2.toCharArray().reverse();
var max = (arr1.length > arr2.length ? arr1.length : arr2.length) - 1;
var strsum = "";
for(var i = 0, up = 0; i <= max; i++){
var c1 = i < arr1.length ? parseInt(arr1[i],10) : 0;
var c2 = i < arr2.length ? parseInt(arr2[i],10) : 0;
c1 += up;
c1 += c2;
up = Math.floor(c1/10);
c1 %= 10;
strsum = c1 + strsum;
if(i == max) strsum = up+strsum;
}
return strsum;
};
/* --------------------------------------------------------------------------- */
function sum(arr){
var strsum = "";
for(var i = 0; i < arr.length; i++){
strsum = add(strsum, arr[i]);
}
return strsum.replace(/^0*/,"");
};
/* --------------------------------------------------------------------------- */
function multiple(a, b){
var arr_a = a.toCharArray().reverse();
var arr_b = b.toCharArray().reverse();
var arr_c = new Array(arr_b.length);
var max = arr_a.length-1;
for(var i = 0, zeropad=""; i < arr_b.length; i++,zeropad+="0"){
var str_c = "";
for(var j = 0, up=0; j<arr_a.length; j++){
var c = (parseInt(arr_a[j], 10) * parseInt(arr_b[i],10));
c+=up;
up = Math.floor(c/10);
c %= 10;
str_c = c+str_c;
if(j==max && up>0) str_c=up+str_c;
}
str_c+=zeropad;
arr_c[i] = str_c;
}
return sum(arr_c);
};
/* --------------------------------------------------------------------------- */
function hex2decimal(hexstr){
var template = "0123456789ABCDEF";
var arr = hexstr.toUpperCase().substring(2).toCharArray().reverse();
for(var i = 0, hex="1"; i < arr.length; i++, hex=multiple(hex,"16")){
var numc = "" + template.indexOf(arr[i]);
var mult = multiple(numc, hex);
arr[i] = mult;
}
var decstr=sum(arr);
if(decstr.length==0) desctr="0";
return decstr;
};
|






匿名
#10336()
[
JavaScript
]
Rating0/0=0.00
2次元配列をつくる →1文字ずつ埋める →つなげる →(゚Д゚)ウマー
Rating0/0=0.00-0+
[ reply ]