A Day in the Life

2006-08-28

気づいたら会社に一人きり

寂しい><

ユビキタス

間違える!よな!

JavaScript 配列のランダム化

そういやノゾキング作の ruby の spidermonkey binding 使うと簡単に書けるじゃん!と思った。素直に spidermonke インタプリタを使ったほうg(ry

Fisher-Yates の方は綺麗にランダムな結果だなー。あと Fisher-Yates のほうが全然速い。

結果

shuffle
[[825, 790, 747, 576, 622, 874, 1041, 1382, 1964, 1179],
 [500, 566, 712, 1147, 903, 702, 910, 1280, 2032, 1248],
 [1601, 1555, 1024, 898, 1127, 1344, 1080, 520, 543, 308],
 [1140, 1175, 1392, 779, 867, 933, 1168, 1614, 608, 324],
 [837, 767, 1076, 1739, 999, 781, 916, 1056, 1199, 630],
 [833, 788, 953, 1352, 1599, 746, 896, 1016, 1175, 642],
 [1586, 1609, 1184, 1255, 1451, 1845, 280, 308, 343, 139],
 [1247, 1314, 1102, 1039, 1162, 1414, 1977, 309, 294, 142],
 [1100, 1091, 1412, 779, 858, 925, 1180, 1712, 633, 310],
 [331, 345, 398, 436, 412, 436, 552, 803, 1209, 5078]]
shuffleFisherYates
[[974, 990, 1005, 962, 988, 1008, 1036, 1040, 1000, 997],
 [1009, 1016, 979, 1006, 979, 1005, 980, 992, 1035, 999],
 [986, 977, 954, 1026, 1039, 985, 1000, 995, 996, 1042],
 [988, 1000, 1031, 975, 1017, 999, 981, 1018, 1016, 975],
 [1049, 1001, 986, 1052, 954, 947, 980, 1015, 982, 1034],
 [956, 898, 1071, 1061, 1016, 999, 1017, 962, 989, 1031],
 [1036, 991, 984, 969, 996, 1020, 972, 1016, 998, 1018],
 [975, 1015, 951, 1015, 1039, 1034, 1001, 973, 1041, 956],
 [1021, 1038, 1024, 941, 990, 996, 1022, 998, 975, 995],
 [1006, 1074, 1015, 993, 982, 1007, 1011, 991, 968, 953]]

コード

require './spidermonkey'
require 'pp'

cs = SpiderMonkey::Context.new
cs.eval <<-EOF;
Array.prototype.shuffle = function() {
  return this.concat().sort(function(){ return Math.random() - 0.5 });
};

Array.prototype.shuffleFisherYates = function() {
  var list = this.concat();
  var i = list.length;

  while (--i) {
    var j = Math.floor(Math.random() * (i + 1));
    if (i == j) continue;
    var k = list[i];
    list[i] = list[j];
    list[j] = k;
  }

  return list;
};
var a = new Array(0,1,2,3,4,5,6,7,8,9);
EOF

def shuffle_result(cs, func)
  (1..10000).inject([]) do |result,|
    cs.evalget("a.#{func}()").to_a.each_with_index do |val, i|
      result[val] ||= []
      result[val][i] ||= 0
      result[val][i] += 1
    end
    result
  end
end
puts 'shuffle'
pp shuffle_result(cs, 'shuffle')

puts 'shuffleFisherYates'
pp shuffle_result(cs, 'shuffleFisherYates')

Ruby の配列~二次元配列をはてなの table 記法に

ときたま使うので。

class Array
  def to_hatena_table
    if self.first.kind_of?(Array)
      self.map {|a| a.to_hatena_table }.join("\n")
    else
      "|#{self.join('|')}|"
    end
  end
end
puts ary.to_hatena_table
|181|94|62|59|67|57|44|32|51|353|
|217|149|77|101|50|62|65|81|145|53|
|160|158|71|80|116|182|24|43|51|115|
|132|141|171|67|59|78|128|191|13|20|
|102|106|91|228|59|56|59|51|222|26|
|58|82|81|112|347|50|54|63|74|79|
|33|40|51|65|118|293|62|83|100|155|
|48|89|155|66|79|86|402|24|23|28|
|45|100|178|34|56|70|88|333|45|51|
|24|41|63|188|49|66|74|99|276|120|

みたいなー。

Math.random の間違った考察

http://subtech.g.hatena.ne.jp/secondlife/20060827/1156679433

まず一つめは Array.prototype.sort は破壊的だったということを忘れていたこと。二つめは Array.prototype.sort に関数を渡した場合、

sort メソッドは、指定された Array オブジェクト内の要素を並べ替えます。このメソッドを実行しても、新しい Array オブジェクトは作成されません。

引数 sortFunction に指定する場合は、次の戻り値を返すような関数を指定する必要があります。

  • 1 つ目の引数が 2 つ目の引数よりも小さい場合は、負の値を返す関数。
  • 2 つの引数が等しい場合は 0 を返す関数。
  • 1 つ目の引数が 2 つ目の引数よりも大きい場合は、正の値を返す関数。

という仕様だということ。

つまりこうしなくちゃダメだった。

var a = new Array(0,1,2,3,4,5,6,7,8,9);
for(var i = 0; i < 1000; i++) console.log(a.concat().sort(function(){ return Math.random() - 0.5 }));

とする必要があった。というわけで1000回ループまわして統計を取ったらばっちりランダムに!ならねええええ。なんなんだ…

-

0

1

2

3

4

5

6

7

8

9

0

181

94

62

59

67

57

44

32

51

353

1

217

149

77

101

50

62

65

81

145

53

2

160

158

71

80

116

182

24

43

51

115

3

132

141

171

67

59

78

128

191

13

20

4

102

106

91

228

59

56

59

51

222

26

5

58

82

81

112

347

50

54

63

74

79

6

33

40

51

65

118

293

62

83

100

155

7

48

89

155

66

79

86

402

24

23

28

8

45

100

178

34

56

70

88

333

45

51

9

24

41

63

188

49

66

74

99

276

120

出社

そういえばどうしてアレ系のイベントって T-shirt を配布したがるんだろう。当日ぐらいしか普通の人は着れないし、また当日着てるのもスタッフ+αぐらいだ。家の寝間着つーのもちょっとなぁ。T-shirtいらないから1000円安くして欲しい!という人の方が多そう、特に学生はお金無いし…。

そんなぽっくんはアレT-shirt 着まくり今日もLLRing のだお><。自転車通勤(電車じゃ恥ずかしすぎる)でアレな会社じゃないと無理だわぁ…。mixi, hatena, るびカ, YAPC, LL Ring, LL night が最近のアレTヴァリエーション。

記事の一覧 >