ソニーのソフトウェアスペシャリスト認定コンテスト『人生の時計』

広告

2/8追記:ライセンスについて

※回答はオープンソースソフトウェアとして公開してください。
その際、そのソフトウェアをOSDに準拠したライセンス(GPLライセンスやBSDライセンスなど)であることを明示して公開してください。

とあるので、ここのコードは修正BSDライセンスとして扱って下さい。普段は常識的な範囲でご自由にライセンスにしておくのだけど、OSSの世界ではそれは困るらしい。

ソニーのソフトウェアスペシャリスト認定コンテスト『人生の時計』

前回のエントリに続いて

1) 人生の時計
あなたの一生を24時間にたとえると今日は何時何分何秒ですか?ただしあなたはあなたの誕生日(a年b月c日)の0時ちょうどに生まれてn歳まで生きる(n歳のときは生きていてn+1歳にはなれない)とし、bとcは一般的な月日の範囲とします。

  1. 1990<=a<=2000,n=80のとき、今日は何時何分何秒ですか?
  2. 1900<=a<=2000,n=200のとき、今日は何時何分何秒ですか?

これは前回の「実数の階乗」と違ってライブラリを使うなとは書いていないので、Rubyで書いてみる。

人生の時計

# encoding: utf-8
require 'rubygems'
require 'active_support/all'

def 何時何分何秒( a, b, c, n )
	生まれた日 = Time.local( a, b, c, 0, 0, 0 )
	天に召される日 = 生まれた日 + n.years - 1.day
	今日 = Time.now
	
	人生時計 = 24 * 60 * 60 * (今日.to_i - 生まれた日.to_i) / (天に召される日.to_i - 生まれた日.to_i)
	秒 = 人生時計.divmod(60)
	分 = 秒[0].divmod(60)
	時 = 分[0].divmod(24)
	
	return "#{時[1]}時#{分[1]}分#{秒[1]}秒"
end


月 = Date.today.month
日 = Date.today.day


puts "i) 1990<=a<=2000,n=80のとき、今日は何時何分何秒ですか?"
for i in 1990..2000 do
	puts "#{i}年生まれにとって今日は#{何時何分何秒( i, 月, 日, 80 )}"
end



puts "ii) 1900<=a<=2000,n=200のとき、今日は何時何分何秒ですか?"
for i in 1900..2000 do
	puts "#{i}年生まれにとって今日は#{何時何分何秒( i, 月, 日, 200 )}"
end

せっかくRubyなので変数名は無駄に日本語にしてみた。

ここではRuby on Railsのactive_supportを使っている。active_supportを使うとFixnumクラスが拡張されて

  • + 1.day
  • + 3.weeks
  • - 7.years
  • 4.hours.from_now
  • 35.minutes.until

などの表記が可能になる。とても便利。

この問題は単に全部の時間を秒とか日で求めて比を計算し、24時間に合わせればいいだけなのだけれど、C言語を使うとUNIX時間が1900年1月1日からの秒単位(だったかな)だったり、1970年からだったり、色々面倒臭いことになる。なぜUNIX時間に変換するかというと、閏年の計算が面倒臭いなと思ったから。

たぶん日付の計算は

に載っていたと思う。Ruby on Railsは

あたりが定番。アジャイル本は英語版がPDFで買えるので買っていたが、最近日本語訳も出た。日本語版も電子書籍で買えるようだ。いや、それどころかRuby本までPDFで買えるじゃないか。知らなかった。

Ohmsha

出版社名は怪しげな宗教みたいだけど、こういう風に電子書籍に前向きなところは応援したい。

実行結果

i) 1990<=a<=2000,n=80のとき、今日は何時何分何秒ですか?
1990年生まれにとって今日は6時36分2秒
1991年生まれにとって今日は6時18分2秒
1992年生まれにとって今日は6時0分3秒
1993年生まれにとって今日は5時42分1秒
1994年生まれにとって今日は5時24分1秒
1995年生まれにとって今日は5時6分2秒
1996年生まれにとって今日は4時48分3秒
1997年生まれにとって今日は4時30分1秒
1998年生まれにとって今日は4時12分1秒
1999年生まれにとって今日は3時54分2秒
2000年生まれにとって今日は3時36分3秒
ii) 1900<=a<=2000,n=200のとき、今日は何時何分何秒ですか?
1900年生まれにとって今日は13時26分25秒
1901年生まれにとって今日は13時19分13秒
1902年生まれにとって今日は13時12分1秒
1903年生まれにとって今日は13時4分50秒
1904年生まれにとって今日は12時57分38秒
1905年生まれにとって今日は12時50分25秒
1906年生まれにとって今日は12時43分13秒
1907年生まれにとって今日は12時36分2秒
1908年生まれにとって今日は12時28分50秒
1909年生まれにとって今日は12時21分37秒
1910年生まれにとって今日は12時14分25秒
1911年生まれにとって今日は12時7分14秒
1912年生まれにとって今日は12時0分2秒
1913年生まれにとって今日は11時52分49秒
1914年生まれにとって今日は11時45分37秒
1915年生まれにとって今日は11時38分25秒
1916年生まれにとって今日は11時31分14秒
1917年生まれにとって今日は11時24分1秒
1918年生まれにとって今日は11時16分49秒
1919年生まれにとって今日は11時9分37秒
1920年生まれにとって今日は11時2分26秒
1921年生まれにとって今日は10時55分13秒
1922年生まれにとって今日は10時48分1秒
1923年生まれにとって今日は10時40分49秒
1924年生まれにとって今日は10時33分38秒
1925年生まれにとって今日は10時26分25秒
1926年生まれにとって今日は10時19分13秒
1927年生まれにとって今日は10時12分1秒
1928年生まれにとって今日は10時4分50秒
1929年生まれにとって今日は9時57分37秒
1930年生まれにとって今日は9時50分25秒
1931年生まれにとって今日は9時43分13秒
1932年生まれにとって今日は9時36分2秒
1933年生まれにとって今日は9時28分49秒
1934年生まれにとって今日は9時21分37秒
1935年生まれにとって今日は9時14分25秒
1936年生まれにとって今日は9時7分14秒
1937年生まれにとって今日は9時0分1秒
1938年生まれにとって今日は8時52分49秒
1939年生まれにとって今日は8時45分37秒
1940年生まれにとって今日は8時38分25秒
1941年生まれにとって今日は8時31分13秒
1942年生まれにとって今日は8時24分1秒
1943年生まれにとって今日は8時16分49秒
1944年生まれにとって今日は8時9分37秒
1945年生まれにとって今日は8時2分25秒
1946年生まれにとって今日は7時55分13秒
1947年生まれにとって今日は7時48分1秒
1948年生まれにとって今日は7時40分49秒
1949年生まれにとって今日は7時33分36秒
1950年生まれにとって今日は7時26分25秒
1951年生まれにとって今日は7時19分13秒
1952年生まれにとって今日は7時12分1秒
1953年生まれにとって今日は7時4分48秒
1954年生まれにとって今日は6時57分37秒
1955年生まれにとって今日は6時50分25秒
1956年生まれにとって今日は6時43分13秒
1957年生まれにとって今日は6時36分0秒
1958年生まれにとって今日は6時28分49秒
1959年生まれにとって今日は6時21分37秒
1960年生まれにとって今日は6時14分25秒
1961年生まれにとって今日は6時7分12秒
1962年生まれにとって今日は6時0分1秒
1963年生まれにとって今日は5時52分49秒
1964年生まれにとって今日は5時45分37秒
1965年生まれにとって今日は5時38分24秒
1966年生まれにとって今日は5時31分13秒
1967年生まれにとって今日は5時24分1秒
1968年生まれにとって今日は5時16分49秒
1969年生まれにとって今日は5時9分36秒
1970年生まれにとって今日は5時2分25秒
1971年生まれにとって今日は4時55分13秒
1972年生まれにとって今日は4時48分1秒
1973年生まれにとって今日は4時40分48秒
1974年生まれにとって今日は4時33分36秒
1975年生まれにとって今日は4時26分25秒
1976年生まれにとって今日は4時19分13秒
1977年生まれにとって今日は4時12分0秒
1978年生まれにとって今日は4時4分48秒
1979年生まれにとって今日は3時57分37秒
1980年生まれにとって今日は3時50分25秒
1981年生まれにとって今日は3時43分12秒
1982年生まれにとって今日は3時36分0秒
1983年生まれにとって今日は3時28分49秒
1984年生まれにとって今日は3時21分37秒
1985年生まれにとって今日は3時14分24秒
1986年生まれにとって今日は3時7分12秒
1987年生まれにとって今日は3時0分1秒
1988年生まれにとって今日は2時52分49秒
1989年生まれにとって今日は2時45分36秒
1990年生まれにとって今日は2時38分24秒
1991年生まれにとって今日は2時31分13秒
1992年生まれにとって今日は2時24分1秒
1993年生まれにとって今日は2時16分48秒
1994年生まれにとって今日は2時9分36秒
1995年生まれにとって今日は2時2分25秒
1996年生まれにとって今日は1時55分13秒
1997年生まれにとって今日は1時48分0秒
1998年生まれにとって今日は1時40分48秒
1999年生まれにとって今日は1時33分36秒
2000年生まれにとって今日は1時26分25秒

ところで年齢はいつ加算されるのか

普通の感覚だと年齢は誕生日に加算される。だから、ここでは「n歳まで生きる(n歳のときは生きていてn+1歳にはなれない)」を

天に召される日 = 生まれた日 + n.years - 1.day

と表現したけど、年齢の計算に関する法律というのがあって、それによると誕生日の前日に1歳年を取ることになっている。4月1日生まれの人は3月31日に年齢が増えるため1学年上のクラスに入る。また2月29日生まれの人は2月28日に年齢が増えるため、誕生日を迎えた数が少なくてもちゃんと年は取る。もしこっちに従うのであれば、生きられる最後の日は誕生日の2日前となる。