開発環境
- 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 コメント:
コメントを投稿