開発環境
- OS X Lion - Apple(OS)
- BBEdit - Bare Bones Software, Inc.(Text Editor)
- Script言語:Ruby
『初めてのプログラミング 第2版』(Chris Pine 著、長尾 高弘 訳、オライリー・ジャパン、2010年、ISBN978-4-87311-469-9)の 12章(新しいクラスのオブジェクト), 12.6(練習問題の続き)roman_to_integer 'mcmxcix'! を解いてみる。
その他参考書籍
- 『プログラミング言語 Ruby』David Flanagan, まつもと ゆきひろ 著 、卜部 昌平 監訳、長尾 高弘 訳、オライリー・ジャパン、2009年、ISBN978-4-87311-394-4)
- Rubyクックブック ―エキスパートのための応用レシピ集
roman_to_integer 'mcmxcix'!
コード(BBEdit)
sample.rb
#!/usr/bin/env ruby1.9
# -*- coding: utf-8 -*-
def roman_to_integer roman
num = 0
r_i = {
'M' => 1000,
'D' => 500,
'C' => 100,
'L' => 50,
'X' => 10,
'V' => 5,
'I' => 1}
pre = 0
(roman.length-1).downto(0) do |i|
n = r_i[roman[i].upcase]
return "有効なローマ数字になっていません!" unless n
if n >= pre
num += n
pre = n
else
num -= n
end
end
num
end
def roman_numeral 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
roman
end
puts roman_to_integer 'mcmxcix'
(1..1000).each do |num|
if num != roman_to_integer(roman_numeral num)
puts "間違え有り"
end
end
入出力結果(Terminal)
$ ./sample.rb 1999 $
ちなみにJavaScriptの場合。
コード(BBEdit)
function roman_to_integer(roman){
var num = 0;
var r_i = {
'M':1000,
'D':500,
'C':100,
'L':50,
'X':10,
'V':5,
'I':1}
var pre = 0;
for(var i = roman.length - 1; i >= 0; i--){
var n = r_i[roman[i].toUpperCase()];
if(!n) throw "有効なローマ数字になっていません!";
if(n >= pre){
num += n;
pre = n;
} else {
num -= n;
}
}
return num;
}
var roman = $('#t0').val();
$('#pre0').text(roman_to_integer(roman));
pythonの場合。
sample.py
コード(BBEdit)
#!/usr/bin/env python3.3
# -*- coding: utf-8 -*-
class Error(Exception):pass
def roman_to_integer(roman):
num = 0
r_i = r_i = {
'M':1000,
'D':500,
'C':100,
'L':50,
'X':10,
'V':5,
'I':1}
pre = 0
for i in range(len(roman) - 1, -1, -1):
if not roman[i].upper() in r_i.keys():
# 何となく例外を発生させるようにしてみた
raise Error("有効なローマ数字になっていない!")
n = r_i[roman[i].upper()]
if n >= pre:
num += n
pre = n
else:
num -= n
return num
def roman_numeral(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)
return roman
try:
print(roman_to_integer('mcmxcix'))
for num in range(1, 1001):pass
except Error as err:
print(err)
入出力結果(Terminal)
$ ./sample.py 1999 $
perlの場合。
sample.pl
コード(BBEdit)
#!/usr/bin/env perl
use strict;
use warnings;
use utf8;
use 5.016;
binmode STDIN, ":utf8";
binmode STDOUT, ":utf8";
use POSIX; # 浮動小数点数の切り捨てのためfloor関数を使いたいのでPOSIXモジュールを使用
sub roman_to_integer{
my $roman = shift;
my @a = split "", $roman;
my $num = 0;
my %r_i = (
'M' => 1000,
'D' => 500,
'C' => 100,
'L' => 50,
'X' => 10,
'V' => 5,
'I' => 1);
my $pre = 0;
for(reverse(0..(@a - 1))){
my $n = $r_i{uc $a[$_]};
return "有効なローマ数字になっていない!" unless $n;
if($n >= $pre){
$num += $n;
$pre = $n;
} else {
$num -= $n;
}
}
$num;
}
sub roman_numeral{
my $n = shift;
my $roman = "";
my $t = floor($n / 1000);
$n %= 1000;
my $h = floor($n / 100);
$n %= 100;
my $ten = floor($n / 10);
$n %= 10;
my $o = $n;
$roman .= 'M' x $t;
given($h){
when(9){ $roman .= 'CM';}
when(4){ $roman .= 'CD';}
default{
$roman .= 'D' x floor($h / 5);
$roman .= 'C' x ($h % 5);
}
}
given($ten){
when(9){ $roman .= 'XC';}
when(4){ $roman .= 'XL';}
default{
$roman .= 'L' x floor($ten / 5);
$roman .= 'X' x ($ten % 5);
}
}
given($o){
when(9){ $roman .= 'IX';}
when(4){ $roman .= 'IV';}
default{
$roman .= 'V' x floor($o / 5);
$roman .= 'I' x ($o % 5);
}
}
$roman;
}
print roman_to_integer('mcmxcix') . "\n";
for(1..1000){
if($_ != roman_to_integer(roman_numeral $_)){
print "間違え有り\n";
}
}
入出力結果(Terminal)
$ ./sample.pl 1999 $
0 コメント:
コメントを投稿