Language detail: JavaScript

Coverage: 75.13%
number of '+' ratings
contribution for coverage

Unsolved challenges

codes

Feed

Used modules

next >>

文字列で+を表示する (Nested Flatten)

2次元配列をつくる →1文字ずつ埋める →つなげる →(゚Д゚)ウマー

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function plusStr (s) {
    var s = String (s) || 'doukaku', l = s.length, r = s.split ('').reverse ().join (''), a = [];
    /*下向きに埋める*/
    a.down = function ([x, y], s) {
        for (var i = 0 ; i < l; i++) {
            if (! a[x + i]) a[x + i] = Array (3 * l + 1).join (' ').split ('');
            this[x + i][y] = s[i];
        }
    };
    [[0, 2 * l], [l, 3 * l], [2 * l, 2 * l]].forEach (function (v) {a.down (v, s)});
    [[1, l], [l + 1, 0], [2 * l + 1, l]].forEach (function (v) {a.down (v, r)});
    /*横向きに埋める*/
    a.right = function ([x, y], s) {
        for (var i = 0 ; i < l; i++){
            this[x][y + i] = s[i];
        }
    };
    [[0, l], [l, 0], [l, 2 * l]].forEach (function (v) {a.right (v, s)});
    [[2 * l, 1], [2 * l, 2 * l + 1], [3 * l, l + 1]].forEach (function (v) {a.right (v, r)});
    /*繋げる*/
    return a.map (function (b) {return b.join ('').replace(/ +$/, '')}).join ("\n");
}
console.log (plusStr ('koukaku'));
居眠り床屋問題 (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
[床屋] 床屋、眠る
 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

  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で色指定する方法も試してみたが、こちらでもほとんど変化なし。
 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を減らす必要があります。

 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等で調べるか、参考ページに拙作のデモがありますのでご覧下さい。
  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 &amp; 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で動作を確認しました。
 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)
初投稿です。 数値文字列として変換してみました。 変換後の最大値はおそらく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;
};
next >>

Index

Feed

Other

Link

Pathtraq

loading...