Rubyのプログラムで今月「日曜日」が何回あるのか教えてください。(「今月」はプログラム実行時のシステム時間でかまいません)
前回(http://www.hatena.ne.jp/1128425886)同様、以下の要領でお願いします。
◎この質問は、プログラムの書き方がわからないのではなく「こんな書き方もできる」の募集です。
◎面白いプログラム、とても短いプログラム、トリッキーなもや勉強になるものは喜ばしいです。
◎このプログラムが役立つ場面は想像できません :-P
◎Rubyがダメな人はRuby以外でも可
http://www.hatena.ne.jp/1128425886
人力検索はてな - 最近ちょっとした作業にRubyを使っています。 仕事で英数字から成るランダムな文字列を生成する必要があって、とりあえず英数字一覧の文字列を用意しようと思ったところ、..
4回です。
・・・質問の仕方が悪かったでしょうか?
答えが必要なのではなくて、プログラムを募集しています。
それに、今月の日曜は5回だと思いますが・・・
http://www.ruby-lang.org/ja/man/index.cgi?cmd=view;name=Time
Rubyリファレンスマニュアル - Time
あいかわらず全然面白くない例ですみません。
t = Time.now.localtime
yd = Time.local(t.year, 12, 31).yday
if yd == 365 and t.mon == 2 then # Uruu ja nai toshi 2-gatsu
answer = 4
else
t2 = Time.local(t.year, t.mon, 1)
if yd == 366 and t.mon == 2 then # Uruu doshi 2-gatsu
if t2.wday == 0 then answer = 5
else answer = 4
end
else if [4,6,9,11].include?(t.mon) then # Shou no tsuki
if t2.wday == 0 or t2.wday == 6 then answer = 5
else answer = 4
end
else # Dai no tsuki
if [0,6,5].include?(t2.wday) then answer = 5
else answer = 4
end
end
end
end
p t,answer
まず閏年でないときの2月は必ずどの曜日も4回なので先に除外。
閏年の2月は1日が日曜日のときだけ日曜日が5回。
残りの小の月(4,6,9,11)の場合は1日が土曜か日曜の場合のみ5回日曜がある。
大の月の場合は1日が金・土・日の場合だけ5回日曜がある。
なんかwdayの処理あたりがださいか。
けっこう長くなりましたね。
・・・ちょっと私も自分で書いてみよう・・
書いてみました>http://d.hatena.ne.jp/nisyu/20051012/1129126889
アプローチがだいぶ違いますネ。面白いです。
面白そうなのでpythonで書いてみました。
from datetime import date
import calendar
today = date.today()
answer = 0
for i in calendar.monthcalendar(today.year, today.month):
if i[6]: answer += 1
print answer
pythonのcalendar.monthcalendarは、1週間ごとの日付の配列を1ヶ月分返します。例えば、今月なら、
[[0, 0, 0, 0, 0, 1, 2], [3, 4, 5, 6, 7, 8, 9], [10, 11, 12, 13, 14, 15, 16], [17, 18, 19, 20, 21, 22, 23], [24, 25, 26, 27, 28, 29, 30], [31, 0, 0, 0, 0, 0, 0]]
こんな感じ。forで1週間ごと取り出して、6番めの値が0以外なら、日曜が存在するので1加算する、といった方法で求めています。
コレはシンプルですね。すごいです!
http://www.ruby-lang.org/ja/man/index.cgi?cmd=view;name=Date
Rubyリファレンスマニュアル - Date
require ”date”
d = Date.today
d -= d.day - 1;
p((d...(d>>1)).find_all {|i| i.wday.zero?}.size)
# => 5
http://d.hatena.ne.jp/nisyu/20051012/1129126889
と同じことですが、Dateオブジェクトを多用してみました。もっとうまく書けそうな気がします。
ほんとですね!「d -= d.day - 1;」とか「.find_allのsizeで調べる」とか全く思いつきませんでした。スゴイ。ありがとうございます。
http://www.ruby-lang.org/ja/man/?cmd=view;name=Date
Rubyリファレンスマニュアル - Date
そか、Dateライブラリとか使えばよかったか。あと、数えたほうが簡単ですね。
ということでこんな感じ。
require ’date’
d = Date.new(Date.today.year, Date.today.mon, 1)
ans = 0
d.upto((d >> 1) - 1){|dd| if dd.wday == 0 then ans = ans+1 end }
p ans
その月の1日と最後の日までをなめて日曜ならansをカウントアップ
直感的になにをやっているかがわかりやすいプログラムになってますね。気持ちいいです。
ありがとうございます。
Ask.jp
#今月一日の曜日と、今月が何日まであるかで決まってしまうので最初に配列を作ってしまいます……。
require ’date’
sundays = Array.new
sundays[28] = [4,4,4,4,4,4,4]
sundays[29] = [5,4,4,4,4,4,4]
sundays[30] = [5,4,4,4,4,4,5]
sundays[31] = [5,4,4,4,4,5,5]
d = Date.today
y = d.year
m = d.mon
#一日の曜日
first = Date.new(y, m, 1).wday
#次の月の一日の前の日=今月の最後の日=今月の日数
#12月なら次の年の1月ということで
last = (Date.new(y + (m == 12 ? 1 : 0), (m == 12 ? 1 : m + 1), 1) - 1).day
p sundays[last][first]
__END__
無駄なサイズの配列を作っているので、
sundays[0] = [4,4,4,4,4,4,4]
sundays[1] = [5,4,4,4,4,4,4]
sundays[2] = [5,4,4,4,4,4,5]
sundays[3] = [5,4,4,4,4,5,5]
:
:
p sundays[last-28][first]
が正当でしょうけど。
これも面白いですね
sshi.Continual
歴週を使ってみました。少しトリッキーですが、ちゃんと動作すると思います。コメントを外すとコマンドラインから任意の年と月が指定できます。
require ’date’
first_day = Date.new(Date.today.year,Date.today.mon)
#first_day = Date.new(ARGV.shift.to_i,ARGV.shift.to_i) if ARGV.size == 2
p (53 + (first_day >> 1).cweek - first_day.cweek) % 53
今までに無いやり方ですね、暦週というのもあるのかぁ。
とりあえずそれなりに縮めてみました。
require ’date’
d=Date.today
d-=d.day-1
p ((d>>1)-d+d.cwday-1).to_i/7
今月の日数を7で割るのが基本的なアイデアです。月の最初の曜日に応じて適当に補正しています。
URLはおまけのshバージョンです。
日数+曜日/7 が今のところ短さでは最良ですね
http://d.hatena.ne.jp/secondlife/20051013/1129193192
川o・-・)<2nd life - はてな Rubyのプログラムで今月「日曜日」が何回あるのか教えてください。
URLはダミーです。
require ’open-uri’
puts open(’http://d.hatena.ne.jp/sample/’).read.scan(%r{<tr>¥r?¥n.+?class=”calendar-day”>(¥d+)</td>}).size
こんなんどうでしょう。
すでにある資産(web上のカレンダー)を活用します。
うわー!面白いです。こういうの待ってました(ぉぃ)無駄なことをシンプルにやってる感じがしてGOODです!
http://search.cpan.org/dist/Calendar-Simple/
Dave Cross / Calendar-Simple - search.cpan.org
Ruby を書けないので、Perl で回答します。以下をコマンドラインから実行するような感じでどうでしょうか。上記 URL で示した Perl モジュールを用いています。
$ perl -MCalendar::Simple -e ’print scalar grep { $_->[0] } calendar;’
カレンダーモジュールから日曜日の在る行を数えているという感じでしょうか?
ありがとうございます
Linux commands
シェルスクリプトではどうでしょうか?
----
bash-3.00$ cal | cut -b 1-2 | grep -c [0-9]
5
(1) calでカレンダーを表示します。
----
bash-3.00$ cal
October 2005
Su Mo Tu We Th Fr Sa
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
(2) cutで1~2バイトめを切り出します。
----
bash-3.00$ cal | cut -b 1-2
Su
2
9
16
23
30
(3) 最後にgrepで数値をふくむ行の数を求めます。
----
bash-3.00$ cal | cut -b 1-2 | grep -c [0-9]
5
Cygwin Information and Installation
Windows2000/Cygwinで試してみました。現在、一般的なUNIXシステム上でなら、上のコマンドは可能なのではないでしょうか。
先にダイアリーの方で拝見しました。
面白いです!ありがとうございました
http://www.ruby-lang.org/ja/man/index.cgi?cmd=view;name=Date;em=...
Rubyリファレンスマニュアル - Date
今度はRubyで。
def countSundays(m,y)
require’date’;d=Date.new(y,m);(d.cwday+((d>>1)-1).day-1)/7
end
上の方も「今月一日の曜日と、今月が何日まであるかで決まってしまう」と言われていますが、同じ考え方です。
(1) Date#cwdayメソッドで月初の曜日を算出
(2) その値に今月の日数-1を加算
(3) (2)を7で割って商(整数)を算出
Date#cwdayメソッドの返す値の仕様(1-7,日曜=7)から、(2)の値を7で割り切れる整数の数=日曜日の回数だと考えます。
http://www.benri.com/calendar/2004.html
2004�N�J�����_�[�i�j���t���j
http://www.benri.com/calendar/2005.html
2005�N�J�����_�[�i�j���t���j
試してみてください。
irb(main):025:0> for i in 1..12; print ”2005/#{i}=”,countSundays(i,2005),”¥n” ;end
2005/1=5
2005/2=4
2005/3=4
2005/4=4
2005/5=5
2005/6=4
2005/7=5
2005/8=4
2005/9=4
2005/10=5
2005/11=4
2005/12=4
=> 1..12
irb(main):026:0>
いろいろと勉強になります。ありがとうございます。
http://search.cpan.org/dist/Date-Simple-Month/
Yasuhiro Horiuchi / Date-Simple-Month - search.cpan.org
私もPerlです。
というか、antipopさんのと使ってるモジュールが違うだけでほとんど変わらないっすね。。。
$ perl -MDate::Simple::Month -e ’print scalar grep { $_->day_of_week == 0 } Date::Simple::Month->new->dates’
しかもこっちのほうが冗長だし^^;
まあ、ストレートに日曜日を数えるってことで。
ありがとうございます!
さて、だいぶ出切ったようですので、ここでおわります。
ありがとうございました。
コメントはありません