一部の方々にご好評(?)頂いたので第二回です。


Rubyのプログラムで今月「日曜日」が何回あるのか教えてください。(「今月」はプログラム実行時のシステム時間でかまいません)

前回(http://www.hatena.ne.jp/1128425886)同様、以下の要領でお願いします。
◎この質問は、プログラムの書き方がわからないのではなく「こんな書き方もできる」の募集です。
◎面白いプログラム、とても短いプログラム、トリッキーなもや勉強になるものは喜ばしいです。
◎このプログラムが役立つ場面は想像できません :-P
◎Rubyがダメな人はRuby以外でも可

回答の条件
  • URL必須
  • 1人2回まで
  • 登録:2005/10/12 21:29:41
  • 終了:--

回答(13件)

id:papa1214 No.1

papa1214回答回数2ベストアンサー獲得回数02005/10/12 22:11:36

ポイント15pt

http://www.hatena.ne.jp/1128425886

人力検索はてな - 最近ちょっとした作業にRubyを使っています。 仕事で英数字から成るランダムな文字列を生成する必要があって、とりあえず英数字一覧の文字列を用意しようと思ったところ、..

4回です。

id:nisyu

・・・質問の仕方が悪かったでしょうか?

答えが必要なのではなくて、プログラムを募集しています。

それに、今月の日曜は5回だと思いますが・・・

2005/10/12 23:10:00
id:Kumappus No.2

くまっぷす回答回数3784ベストアンサー獲得回数1852005/10/12 22:25:37

ポイント15pt

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の処理あたりがださいか。

id:nisyu

けっこう長くなりましたね。

・・・ちょっと私も自分で書いてみよう・・

書いてみました>http://d.hatena.ne.jp/nisyu/20051012/1129126889

アプローチがだいぶ違いますネ。面白いです。

2005/10/12 23:27:10
id:t-wata No.3

t-wata回答回数82ベストアンサー獲得回数132005/10/13 00:07:44

ポイント15pt

面白そうなので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加算する、といった方法で求めています。

id:nisyu

コレはシンプルですね。すごいです!

2005/10/13 00:14:10
id:iwadon No.4

いわどん回答回数60ベストアンサー獲得回数132005/10/13 01:18:48

ポイント15pt

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オブジェクトを多用してみました。もっとうまく書けそうな気がします。

id:nisyu

ほんとですね!「d -= d.day - 1;」とか「.find_allのsizeで調べる」とか全く思いつきませんでした。スゴイ。ありがとうございます。

2005/10/13 05:15:18
id:Kumappus No.5

くまっぷす回答回数3784ベストアンサー獲得回数1852005/10/13 01:20:28

ポイント15pt

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をカウントアップ

id:nisyu

直感的になにをやっているかがわかりやすいプログラムになってますね。気持ちいいです。

ありがとうございます。

2005/10/13 05:17:29
id:quintia No.6

quintia回答回数562ベストアンサー獲得回数712005/10/13 08:48:07

ポイント15pt

#今月一日の曜日と、今月が何日まであるかで決まってしまうので最初に配列を作ってしまいます……。


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]


が正当でしょうけど。

id:nisyu

これも面白いですね

2005/10/13 13:02:07
id:sshi No.7

s回答回数14ベストアンサー獲得回数12005/10/13 22:37:59

ポイント15pt

歴週を使ってみました。少しトリッキーですが、ちゃんと動作すると思います。コメントを外すとコマンドラインから任意の年と月が指定できます。


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

id:nisyu

今までに無いやり方ですね、暦週というのもあるのかぁ。

2005/10/14 06:02:35
id:shinichiro_h No.8

shinichiro_h回答回数6ベストアンサー獲得回数02005/10/13 22:56:45

ポイント15pt

とりあえずそれなりに縮めてみました。


require ’date’

d=Date.today

d-=d.day-1

p ((d>>1)-d+d.cwday-1).to_i/7


今月の日数を7で割るのが基本的なアイデアです。月の最初の曜日に応じて適当に補正しています。


URLはおまけのshバージョンです。

id:nisyu

日数+曜日/7 が今のところ短さでは最良ですね

2005/10/14 06:04:58
id:secondlife No.9

セコン回答回数6ベストアンサー獲得回数12005/10/13 23:17:37

ポイント40pt

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上のカレンダー)を活用します。

id:nisyu

うわー!面白いです。こういうの待ってました(ぉぃ)無駄なことをシンプルにやってる感じがしてGOODです!

2005/10/14 06:10:16
id:antipop No.10

Kentaro KURIBAYASHI回答回数16ベストアンサー獲得回数22005/10/13 23:42:36

ポイント15pt

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;’

id:nisyu

カレンダーモジュールから日曜日の在る行を数えているという感じでしょうか?

ありがとうございます

2005/10/14 06:12:49
id:kkkkkkkk No.11

kkkkkkkk回答回数19ベストアンサー獲得回数02005/10/14 02:03:28

ポイント15pt

シェルスクリプトではどうでしょうか?

----

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


http://www.cygwin.com/

Cygwin Information and Installation

Windows2000/Cygwinで試してみました。現在、一般的なUNIXシステム上でなら、上のコマンドは可能なのではないでしょうか。

id:nisyu

先にダイアリーの方で拝見しました。

面白いです!ありがとうございました

2005/10/14 06:14:07
id:kkkkkkkk No.12

kkkkkkkk回答回数19ベストアンサー獲得回数02005/10/14 05:47:01

ポイント15pt

今度は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>

id:nisyu

いろいろと勉強になります。ありがとうございます。

2005/10/14 11:08:57
id:hi-rocks No.13

よしだっぺ回答回数2ベストアンサー獲得回数02005/10/14 11:38:19

ポイント15pt

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’


しかもこっちのほうが冗長だし^^;

まあ、ストレートに日曜日を数えるってことで。

id:nisyu

ありがとうございます!

さて、だいぶ出切ったようですので、ここでおわります。

ありがとうございました。

2005/10/14 20:48:12

コメントはまだありません

この質問への反応(ブックマークコメント)

トラックバック

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません