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