開発環境
- OS X Lion - Apple(OS)
- BBEdit - Bare Bones Software, Inc.(Text Editor)
- Script言語:Ruby
『初めてのプログラミング 第2版』(Chris Pine 著、長尾 高弘 訳、オライリー・ジャパン、2010年、ISBN978-4-87311-469-9)の 13章(新しいクラスのオブジェクト), 13.1(練習問題)組み込みクラスの拡張 を解いてみる。
その他参考書籍
- 『プログラミング言語 Ruby』David Flanagan, まつもと ゆきひろ 著 、卜部 昌平 監訳、長尾 高弘 訳、オライリー・ジャパン、2009年、ISBN978-4-87311-394-4)
- Rubyクックブック ―エキスパートのための応用レシピ集
組み込みクラスの拡張
コード(BBEdit)
sample.rb
#!/usr/bin/env ruby1.9
# -*- coding: utf-8 -*-
class Array
def shuffle
some_array = self
shuffled_array = []
a = Array.new(some_array)
while a.length > 0
r = rand a.length
shuffled_array.push(a.slice(r))
a = a.slice(0, r) + a.slice(r + 1, a.length)
end
shuffled_array
end
end
class Integer
## メモ化
@@facs = {}
@@romans = {}
def factorial
n = self;
return "0以上の整数を入力してください" unless n >= 0
return @@facs[n] if @@facs[n]
return @@facs[n] = 1 if n == 1
return @@facs[n] = n * (n-1).factorial
end
def to_roman
number =self
return @@romans[number] if @@romans[number]
roman = ""
t = number / 1000
number = number % 1000
h = number / 100
number = number % 100
ten = number / 10
number = number % 10
o = number
roman +='M' * t
if h == 9
roman += 'CM'
elsif h == 4
roman += 'CD'
else
roman += 'D' * (h / 5)
roman += 'C' * (h % 5)
end
if ten == 9
roman += 'XC'
elsif ten == 4
roman += 'XL'
else
roman += 'L' * (ten / 5)
roman += 'X' * (ten % 5)
end
if o == 9
roman += 'IX'
elsif o == 4
roman += 'IV'
else
roman += 'V' * (o / 5)
roman += 'I' * (o % 5)
end
@@romans[self] = roman
end
end
a = [1,2,3,4,5] + %w[A B C D E a b c d e]
shuffled_a = a.shuffle
puts "シャッフル前: #{a.join(" ")}"
puts "シャッフル後: #{shuffled_a.join(" ")}"
n = 10
puts "#{n}! = #{n.factorial}"
n = 1234
puts "#{n}: #{n.to_roman}"
入出力結果(Terminal)
$ ./sample.rb シャッフル前: 1 2 3 4 5 A B C D E a b c d e シャッフル後: c 5 d 1 b A e 2 3 a 4 C B D E 10! = 3628800 1234: MCCXXXIV $
ちなみにJavaScriptの場合。
コード(BBEdit)
<label>配列(カンマ区切り文字列)または整数を入力<br />
<input id="t0" type="text" value="1,2,3,4,5,'A','B','C','D','E','a','b','c','d','e'" />
</label><br />
<input type="button" value="配列をシャッッフル" onclick="clicked1()" /><br />
<input type="button" value="階乗を求める" onclick="clicked2()" /><br />
<input type="button" value="数値をローマ数字に変換" onclick="clicked3()" />
<script>
Array.prototype.shuffle = function(){
var some_array = this;
var shuffled_array = [];
var a = [];
for(var i = 0; i < some_array.length; i++){
a[i] = some_array[i];
}
while(a.length > 0){
var r = Math.floor(Math.random() * a.length);
var o = a.splice(r, 1);
shuffled_array.push(o[0]);
}
return shuffled_array;
};
// メモ化
var facs = {};
Number.prototype.factorial = function(){
var n = this.valueOf();
if(facs[n]) return facs[n];
if( n < 0) return "0以上の整数を指定してください";
if(n === 0 || n === 1) return facs[n] = 1;
return facs[n] = n * (n-1).factorial();
};
String.prototype.repeat = function(n){
var result = "";
for(var i = 0; i < n; i++){
result += this;
}
return result;
};
// メモ化
var romans = {};
Number.prototype.to_roman = function(){
var n = this.valueOf();
if(romans[n]) return romans[n];
var roman = "";
var t = Math.floor(n / 1000);
n %= 1000;
var h = Math.floor(n / 100);
n %= 100;
var ten = Math.floor( n / 10);
n %= 10;
var o = n;
roman += 'M'.repeat(t);
switch(h){
case 9: roman += 'CM'; break;
case 4: roman += 'CD'; break;
default: roman += 'D'.repeat(Math.floor(h / 5));
roman += 'C'.repeat(Math.floor(h % 5));
}
switch(ten){
case 9: roman += 'XC'; break;
case 4: roman += 'CL'; break;
default: roman += 'L'.repeat(Math.floor(ten / 5));
roman += 'X'.repeat(Math.floor(ten % 5));
}
switch(o){
case 9: roman += 'IX'; break;
case 4: roman += 'IV'; break;
default: roman += 'V'.repeat(Math.floor(o / 5));
roman += 'I'.repeat(Math.floor(o % 5));
}
return romans[this.valueOf()] = roman;
};
function clicked1(){
var o = $('#t0').val();
var a = o.split(",");
var shuffled_a = a.shuffle();
$('#pre0').text("シャッフル前: " + a + "\n" +
"シャッフル後: " + shuffled_a);
}
function clicked2(){
var o = parseInt($('#t0').val());
o = new Number(o);
$('#pre0').text( o + "! = " + o.factorial());
}
function clicked3(){
var o = $('#t0').val();
o = new Number(o);
$('#pre0').text(o.to_roman());
}
</script>
pythonの場合。
sample.py
コード(BBEdit)
#!/usr/bin/env python3.3
# -*- coding: utf-8 -*-
class MyList(list):
def __init__(self, data):
list.__init__(self,data)
self.data = data
def __getattr__(self, attrname):
return getattr(self.data, attrname)
def shuffle(self):
l = MyList(self.data[:])
shuffled_list = MyList([])
import random
while len(l) > 0:
r = random.randint(0, len(l) - 1)
shuffled_list.append(l.pop(r))
return MyList(shuffled_list)
class MyInt(int):
facs = {}
romans = {}
def __init__(self, data):
self.data = data
def __getattr__(self, attrname):
return getattr(self.data, attrname)
def factorial(self):
if self.data in MyInt.facs:
return MyInt.facs[self.data]
if self.data < 0:
raise Exception("0以上の整数を指定してください")
if self.data <= 1:
MyInt.facs[self.data] = 1
return 1
MyInt.facs[self.data] = MyInt(self.data) * MyInt(self.data - 1).factorial()
return MyInt.facs[self.data]
def to_roman(self):
number = self.data
if number in MyInt.romans:
return MyInt.romans[number]
roman = ""
t = number // 1000
number %= 1000
h = number // 100
number %= 100
ten = number // 10
number %= 10
o = number
roman += 'M' * t
if h == 9:
roman += 'CM'
elif h == 4:
roman += 'CD'
else:
roman += 'D' * (h // 5)
roman += 'C' * (h % 5)
if ten == 9:
roman += 'XC'
elif ten == 4:
roman += 'XL'
else:
roman += 'L' * (ten // 5)
roman += 'X' * (ten % 5)
if o == 9:
roman += 'IX'
elif o == 4:
roman += 'IV'
else:
roman += 'V' * (o // 5)
roman += 'I' * (o % 5)
MyInt.romans[self.data] = roman
return roman
if __name__ == '__main__':
l = MyList([1,2,3,4,5,'A','B','C','D','a','b','c','d','e'])
shuffled_l = l.shuffle()
print("シャッフル前: {0}".format(l))
print("シャッフル後: {0}".format(shuffled_l))
n = MyInt(10)
print("{0}! = {1}".format(n, n.factorial()))
n = MyInt(1234)
print("{0}: {1}".format(n, n.to_roman()))
入出力結果(Terminal)
$ ./sample.py シャッフル前: [1, 2, 3, 4, 5, 'A', 'B', 'C', 'D', 'a', 'b', 'c', 'd', 'e'] シャッフル後: ['a', 'd', 'A', 'b', 'c', 'C', 'B', 4, 1, 'D', 2, 3, 5, 'e'] 10! = 3628800 1234: MCCXXXIV $
0 コメント:
コメントを投稿