何週間ですか?


13

あなたの仕事は、単一の数字を出力することです。特定の日付範囲が交差するISO週の数。ウィキペディアを引用すると:An average year is exactly 52.1775 weeks longですが、これは平均的なものではありません。

入力は、スペースで区切られた2つのISO日付で構成されます。

0047-12-24 2013-06-01

終了日が開始日より前になることはありません。簡単にするために、外挿されたグレゴリオ暦を使用します。

テストケース:

Format: input -> output
2015-12-31 2016-01-01 -> 1    (both are within week 53 of 2015)
2016-01-03 2016-01-04 -> 2    (the 3rd is within week 53, and the 4th is in week 1)
2015-12-24 2015-12-24 -> 1    (this single day is of course within a single week)

ソリューションはからまでの日付を処理する必要が0001-01-01あり9999-12-31ます。


2
入力は、スペースで区切られた単一の文字列ではなく、文字列の配列にできますか?あるいは、2つの日付を関数の2つの引数にできますか?
ドアノブ


また、週は日曜日または月曜日に始まりますか?2番目のテストケースによると、それは月曜日ですが、念のためです。
ドアノブ

@Doorknob冰ウィキペディアの引用:「日付はISO週番号年YYYY形式で指定され、週番号はwwの形式で文字「W」が前に付けられ、曜日番号は1〜7の数字d ISO 8601
Tensibai

2
ISO標準によると、Weeks start with Monday.
フィリップHaglund

回答:


2

ルビー、89 88 86バイト

->s{a,b=s.split.map{|x|Time.gm *x.split(?-)}
n=1
(a+=86400).wday==1&&n+=1until a==b
n}

非常に原始的な解決策:最初の日付aと2番目の日付を指定してb、increment a、月曜日かどうかを確認し(そうであれば、新しい週に「ロールオーバー」しました)、一度停止しaますb

質問で指定された正確な形式、つまりスペースで区切られた単一の文字列で入力を受け取ります。(入力を解析する方法は派手です。Rubyの「splat」演算子を使用し*ます。この演算子は配列または列挙可能なoutを「展開」するため、にTime.gm *[2013, 06, 01]なりTime.gm 2013, 06, 01ます。)

コメントディスカッションからインポート:

「1年の週」は気にしません。「全体的な週」のみを考慮します。したがって、1年に52週間または53週間があるかどうかに違いはありません。

Wikipediaよると、これが年の境界を正しく処理するかどうかの将来の混乱を避けるために、すべての週は常に月曜日に始まり、日曜日に終わります。

より洗練されたトリックについては、これらはすべて同等です。

until a==b;a+=86400;n+=a.wday==1?1:0;end
[a+=86400,n+=a.wday==1?1:0]until a==b
n+=(a+=86400).wday==1?1:0 until a==b
(a+=86400).wday==1&&n+=1 until a==b
(a+=86400).wday==1&&n+=1until a==b

あなたは1つのcharは交換し保存することができますことはできませんa==ba<b
テンシバイ

1

VBA、125バイト

2つの関数入力を文字列として期待する

Function u(k,j)
f=DateValue(k)
For i=0 To (DateValue(j)-f)
q=DatePart("ww",f+i,2,2)
If q<>j Then u=u+1
j=q
Next
End Function

確かにこれはゴルフできる。これは2つの日付の間で毎日ループし、ISO日付が変わるたびにカウンターを増分します。

DatePart("ww",f+i,2,2)は、最初の2が意味するVBAのISO週番号Monday (complies with ISO standard 8601, section 3.17)です。2番目の2はWeek that has at least four days in the new year (complies with ISO standard 8601, section 3.17)

単一入力付き140バイト

Function g(k)
y=Split(k)
f=DateValue(y(0))
For i=0 To (DateValue(y(1))-f)
q=DatePart("ww",f+i,2,2)
If q<>j Then g=g+1
j=q
Next
End Function

1

R、76バイト

d=as.Date(scan("","raw"));sum(strftime(seq(d[1],d[2],"day")[-1],"%w")==1)+1

@Doorknobとの会話の後、月曜日を数えるのと同じくらい簡単になりました。

seq 日付のベクトル(2つの日付の間の各日)を作成し、strftimeをそれを「週の日数」に変換し、1をカウントして、週を変更した回数を取得し、1を追加します。先週を考慮に入れてください。

ループする別のアプローチ:

R、85バイト

n=1;d=as.Date(scan("","raw"));z=d[1];while(z<d[2]){n=n+(strftime(z<-z+1,"%w")==1)};n

1
2番目のアプローチについては、最初の日付が月曜日に該当しない場合、月曜日の総数に1だけを追加する必要があります。
DavidC

@DavidCarraherありがとう、あなたの答えを読んで、私は範囲の最初の日を削除して、問題を解決できると思いました:)
Tensibai

0

Mathematica 135 79 96 84 74バイト

@Doorknobの提案と一致して、これ

  • 範囲内のすべての日付を生成します

  • (を除く)の月曜日の数(ISOWeekDay== "1")をカウントし、DateRanged

  • 1合計に追加されます。


Count[DateString[#,"ISOWeekDay"]&/@Rest@(DateRange@@StringSplit@#),"1"]+1&

Count[DateString[#,"ISOWeekDay"]&/@Rest@(DateRange@@StringSplit@#),"1"]+1&
/@ {"2015-12-31 2016-01-01", "2016-01-04 2016-01-05","2016-01-03 2016-01-04", 
"2015-12-24 2015-12-24", "1876-12-24 2016-01-01"}

{1、1、2、1、7255}

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.