2013年2月6日水曜日

開発環境

『初めてのプログラミング 第2版』(Chris Pine 著、長尾 高弘 訳、オライリー・ジャパン、2010年、ISBN978-4-87311-469-9)の 13章(新しいクラスの作成と既存のクラスの変更), 13.1(練習問題)組み込みクラスの拡張 を解いてみる。

その他参考書籍

組み込みクラスの拡張

コード(BBEdit)

sample.rb

#!/usr/bin/env ruby1.9
#-*- coding: utf-8 -*-

class Array
  def shuffle
    some_array = self
    a = some_array[0, some_array.length]
    result = []
    while a.length > 0
      i = rand (a.length - 1)
      result.push a.slice!(i)
    end
    result
  end
end

$facs = {0 => 1, 1 => 1}
class Integer
  def factorial
    n = self
    return $facs[n] if $facs[n]
    $facs[n] = n * (n-1).factorial
  end
  def to_roman
    n = self
    roman = 'M' * (n / 1000)
    n = n % 1000
    h = n / 100
    n = n % 100
    t = n / 10
    o = n % 10
    if h != 9 and h != 4
      roman += 'D' * (h / 5)
      roman += 'C' * (h % 5)
    elsif h != 9
      roman += 'CD'
    else
      roman += 'CM'
    end
    if t != 9 and h != 4
      roman += 'L' * (h / 5)
      roman += 'X' * (h % 5)
    elsif t != 9
      roman += 'XL'
    else
      roman += 'XC'
    end
    if o != 9 and o != 4
      roman += 'V' * (o / 5)
      roman += 'I' * (o % 5)
    elsif o != 9
      roman += 'IV'
    else
      roman += 'IX'
    end
    roman
  end
end

a = [1,2,3,4,5] + %w[A B C D E a b c d e]
shuffled = a.shuffle
puts "シャッフル前: #{a.join(" ")}"
puts "シャッフル後: #{shuffled.join(" ")}"

(1..10).each do |n|
  puts "#{n}! = #{n.factorial}"
end

n = 1999
puts "#{n}: #{n.to_roman}"

入出力結果(Terminal)

$ ./sample.rb
シャッフル前: 1 2 3 4 5 A B C D E a b c d e
シャッフル後: 4 3 D a 1 b C d 5 E c B A 2 e
1! = 1
2! = 2
3! = 6
4! = 24
5! = 120
6! = 720
7! = 5040
8! = 40320
9! = 362880
10! = 3628800
1999: MCMXCIX
$

ちなみにJavaScriptの場合。

コード(BBEdit)

// 本当はJavaScriptでは組み込みのオブジェクトを拡張しない方がいい
Array.prototype.shuffle = function() {
    var a = this.slice(),
        result = [],
        i;
    while ( a.length > 0 ) {
        i = Math.floor(Math.random() * a.length);
        result.push( a.splice(i, 1)[0] );
    }
    return result;
};
var facs = {0:1, 1:1};
Number.prototype.factorial = function() {
    var n = this;
    if (n < 0){
        throw {
            type: "Factorial失敗",
            message: "自然数にしか使えない"
        };
    }
    if (facs[n]) {
        return facs[n];
    }
    return facs[n] = n * (n-1).factorial();
};
Number.prototype.toRoman = function(){
    var n = this,
        roman = new Array(Math.floor(n / 1000) + 1).join('M'),
        n = Math.floor(n % 1000),
        h = Math.floor(n / 100),
        n = Math.floor(n % 100),
        t = Math.floor( n / 10),
        o = Math.floor(n % 10);
    if(h !== 9 && h !== 4){
        roman += new Array(Math.floor(h / 5) + 1).join('D');
        roman += new Array(Math.floor(h % 5) + 1).join('C');
    } else if(h !== 9){
        roman += 'CD';
    } else {
        roman += 'CM';
    }
    if(t !== 9 && t !== 4){
        roman += new Array(Math.floor(t / 5) + 1).join('L');
        roman += new Array(Math.floor(t % 5) + 1).join('X');
    } else if (t !== 9){
        roman += 'XL';
    } else {
        roman += 'XC';
    }
    if( o !== 9 && o !== 4){
        roman += new Array(Math.floor( o / 5) + 1).join('V');
        roman += new Array( Math.floor(o % 5) + 1).join('I');
    } else if ( o !== 9 ){
        roman += 'IV';
    } else {
        roman += 'IX';
    }
    return roman;
};
var a = [1,2,3,4,5,'A','B','C','D','E','a','b','c','d','e'],
    shuffled = a.shuffle(),
    result = "シャッフル前: " + a.join(" ") + "\n" +
        "シャッフル後: " + shuffled.join(" ") + "\n",
    n = 1999,
    i;
for (i = 0, max = 10; i <= max; i += 1) {
    result += i + "! = " + i.factorial() + "\n";
}
result += n + ": " + n.toRoman();
$('#pre0').text(result);




pythonの場合。

sample.py

コード(BBEdit)

#!/usr/bin/env python3.3
#-*- coding: utf-8 -*-

class MyList(list):
    def shuffle(self):
        import random
        l = self[:]
        result = []
        while len(l) > 0:
            i = random.randint(0, len(l) - 1)
            result.append( l.pop(i) )
        return result

class MyInt(int):
    facs = {0:1, 1:1}
    def factorial(self):
        n = self
        if n in MyInt.facs.keys():
            return MyInt.facs[n]
        MyInt.facs[n] = n * MyInt(n - 1).factorial()
        return MyInt.facs[n]
    def toRoman(self):
        n = self
        roman = 'M' * (n // 1000)
        n %= 1000
        h = n // 100
        n %= 100
        t = n // 10
        o = n % 10
        if h != 9 and h != 4:
            roman += 'D' * (h // 5)
            roman += 'C' * (h % 5)
        elif h != 9:
            roman += 'CD'
        else:
            roman += 'CM'
        if t != 9 and h != 4:
            roman += 'L' * (t // 5)
            roman += 'X' * (t % 5)
        elif t != 9:
            roman += 'XL'
        else:
            roman += 'XC'
        if o != 9 and o != 4:
            roman += 'V' * (o // 5)
            roman += 'I' * (o % 5)
        elif o != 9:
            roman += 'IV'
        else:
            roman += 'IX'
        return roman
    
l = MyList([1,2,3,4,5,'A','B','C','D','E','a','b','c','d','e'])
shuffled = l.shuffle()
for x, y in [("シャッフル前", l), ("シャッフル後", shuffled)]:
    print("{0}: {1}".format(x, y))

for x in range(11):
    n = MyInt(x)
    print("{0}! = {1}".format(n, n.factorial()))

print(MyInt(1999).toRoman())

入出力結果(Terminal)

$ ./sample.py
シャッフル前: [1, 2, 3, 4, 5, 'A', 'B', 'C', 'D', 'E', 'a', 'b', 'c', 'd', 'e']
シャッフル後: ['A', 'a', 3, 'E', 'B', 'd', 'e', 5, 'C', 'D', 2, 4, 'c', 1, 'b']
0! = 1
1! = 1
2! = 2
3! = 6
4! = 24
5! = 120
6! = 720
7! = 5040
8! = 40320
9! = 362880
10! = 3628800
MCMXCIX
$

0 コメント:

コメントを投稿