다음 2 월 29 일의 요일


14

날짜를 가져 와서 그 날짜 다음 2 월 29 일의 요일을 반환하는 함수를 작성하십시오.

  • 입력은 ISO 확장 형식 인 YYYY-MM-DD의 문자열입니다 (예 : 2010 년 5 월 27 일은 "2010-05-27"임).

  • 출력은 요일의 이름 인 문자열입니다 (예 : "월요일"). 대문자는 중요하지 않지만 영어로 전체 이름을 지정하십시오.

  • 주어진 날짜 2 월 29 일 인 경우, 다음의 요일을 반환 다음 2 월 29 일.

  • Proleptic Gregorian Calendar의 계산을 사용하십시오 (그래서 전체 길이에 대해 Gregorian 윤년 계산을 사용합니다). Julian Calendar 또는 Julian에서 Gregorian으로 전환 할 때 걱정하지 마십시오. 그레고리 안을 모든 것으로 가정하십시오.

  • 이 기능은 최소한 "0001-01-01"- "2100-01-01"범위에서 작동해야합니다.

  • 선택한 언어가 제공하는 표준 라이브러리를 자유롭게 사용하십시오. 그러나 솔루션의 일부로 해당 코드를 포함시키지 않으려면 타사 라이브러리를 사용하지 마십시오.

  • 가장 짧은 코드 (가장 적은 문자)가 이깁니다.

예 :

  • func("0001-01-01") -> "Sunday"
  • func("1899-12-03") -> "Monday"
  • func("1970-01-01") -> "Tuesday"
  • func("1999-07-06") -> "Tuesday"
  • func("2003-05-22") -> "Sunday"
  • func("2011-02-17") -> "Wednesday"
  • func("2100-01-01") -> "Friday"

(아니요, 당신은 함수의 이름을 지정할 필요가 없습니다 func)

힌트 :

  • 400으로 나눌 수없는 00으로 끝나는 연도는 윤년이 아닙니다.
  • 0001 년 1 월 1 일은 월요일입니다.

답변:


7

윈도우 PowerShell, 65

매우 간단합니다.

filter f{for($d=date $_;($d+='1').day*$d.month-58){}$d.dayofweek}

평소와 같이 완료 될 때까지 오랫동안 기다릴 경우 2 바이트를 줄일 수 있습니다.

filter f{for($d=date $_;($d+=9).day*$d.month-58){}$d.dayofweek}

테스트:

> '0001-01-01','1899-12-03','1970-01-01','1999-07-06','2003-05-22','2011-02-17','2100-01-01'|f
Sunday
Monday
Tuesday
Tuesday
Sunday
Wednesday
Friday

역사:

  • 2011-02-18 00:06 (65) 첫 번째 시도.

이것이 작동하려면 어떤 경로가 필요합니까? 내 길에 GnuWin 날짜가있어서 깨고 있습니다.
— 피터 테일러

@Peter :와 충돌 할 수 있습니다 date. PATH에서 GNUWin32를 제거하면 작동합니다. 또는로 변경 date하십시오 Get-Date(이러한 종류의 폴백 동작은 명령을 찾을 수없는 경우에만 작동합니다. 확인하고 사용하십시오 gcm date). 어쨌든 GNUWin32와 같은이 스크립트의 특정 문제는 표준 Windows 설치의 일부가 아니라고 생각하지 않습니다.
— Joey

내가 요청한 이유는 이미 사용을 시도 get-date하고 Method invocation failed because [System.Management.Automation.PSObject] doesn't contain a method named 'op_Addition'.PS2 또는 .Net 4 등이 필요합니까?
— 피터 테일러

@Peter : PowerShell v2를 사용해 보았습니다. PowerShell이 ​​2.0 런타임에 연결되어 있기 때문에 .NET 4는 작동하지 않습니다. 어쨌든 PSObject는 돌아 오는 Get-Date것이 아니라 a 에서 가져와야 합니다 System.DateTime.
— Joey

매우 이상합니다. DateTime에 정의되어 있지 않다는 $d=Get-Date "0400-01-01"; $d++오류 메시지를 표시합니다 ++. 동일은 교체 ++로 +=1하거나 +="1"또는 +='1'PSObject에 대한 오류 메시지를 제공합니다. 그리고 그냥 +"1"작동합니다.
— 피터 테일러

5

루비 1.9, 85 자

f=->a{require"date";d=Date.parse(a,0,0)+1;d+=1until d.day*d.month==58;d.strftime"%A"}

간단한 솔루션. 로 함수를 호출하십시오 f[args].

  • 편집 : ( 0001-01-0187- > 97) 테스트 케이스를 수정했습니다 .
  • 편집 2 : (97-> 91) Date.parse를 사용하면 달력 재구성 날짜도 지정할 수 있습니다.
  • 편집 3 : (91-> 87) 함수 대신 람다를 사용하십시오. 고마워 Dogbert !
  • 편집 4 : (87-> 85) 불필요한 공백을 제거하십시오. 다시 감사합니다, Dogbert !

4
"0001-01-01"의 테스트 케이스를 실패합니다. 루비의 날짜는 너무 강력해서 줄리안 날짜를 고려합니다.
— steenslag

@Ventero def *는 무엇을합니까? 전에 본 적이 없습니다.
— steenslag

@ steenslag : 고마워, 그 테스트 케이스를 수정했습니다. def*그냥 함수를 정의합니다 *. 그렇게 def하면 함수 이름과 사이에 공백이 필요하지 않습니다 .
— Ventero

1
람다를 대신 정의 할 수 없습니까? a =-> {...}
— Wile E. Coyote

1
또한 strftime 이후에는 공간이 필요하지 않습니다.
— Wile E. Coyote

3

T-SQL 166 185 자

CREATE PROCEDURE f29 (@d DATETIME) AS
DECLARE @i int
SET @i=YEAR(DATEADD(M,-2,@d)+3)
SET @i=@i+(4-@i%4)
IF @i%100=0 AND @i%400<>0 SET @i=@i+4
SELECT DATENAME(W,CAST(@i AS CHAR)+'-2-29')

나는 이미 T-SQL 날짜 함수를 망쳐 놓았으므로 왜 안되는지 알아 냈습니다 ...

원래 솔루션이 잘못되었습니다 ...

그 전략을 작동시키기 위해 실제로 해야 할 일은 다음과 같습니다 .

CREATE PROCEDURE f29 (@d DATE) AS
DECLARE @i int
SET @i = YEAR(@d)
BEGIN TRY 
SET @i=YEAR(DATEADD(D, 3, DATEADD(M,-2,@d)))
END TRY
BEGIN CATCH
END CATCH
SET @i=@i+(4-@i%4)
IF @i%100=0 AND @i%400<>0 SET @i=@i+4
SELECT DATENAME(W,CAST(@i AS CHAR)+'-2-29')

내가 뭔가 짧은 만드는 포기 올바른 데이터 형식 사용하는 경우에도 나는 0001-01-01 후 2 개월 뺀 오버 플로우를 만들 점을 감안 하고 이 질문에 대한 유효한. O_o. 트릭시 질문.
— mootinator

이러한 T-SQL 솔루션을보고 싶습니다. :)
— Steve

3

C #, 176

Func<String,String>f=(d)=>{DateTime n;for(n=DateTime.Parse(d).AddDays(307);!(DateTime.IsLeapYear(n.Year));n=n.AddYears(1)){}return new DateTime(n.Year,2,29).ToString("dddd");};

일반적인 함수 정의를 사용하여 8 바이트를 절약 할 수 있습니다.string f(string d){...}
— Joey

.ToString("dddd")그러나 영어가 아닌 현재 로케일로 날짜를 인쇄합니다.
— Joey

165 자 => 문자열 f (문자열 d) {var n = DateTime.Parse (d) .AddDays (307); while (! (DateTime.IsLeapYear (n.Year))) n = n.AddYears (1); 반품 (new DateTime (n.Year, 2,29)). DayOfWeek.ToString ();}
— Stephan Schinkel

127 자로 추가 개선 :string f(string d){var n=DateTime.Parse(d).AddDays(1);return DateTime.IsLeapYear(n.Year)&&n.DayOfYear==60?n.DayOfWeek+"":f(n+"");}
— Patrik Westerlund

3

배쉬, 96 바이트

고마워 피터 ... 골프 버전, 96 바이트 :

i=1;until [ `date -d"$1 $i days" +%m-%d` = "02-29" ];do((i++));done
date -d "${1} ${i} days" +%A

이전 버전, 229 바이트

#!/bin/bash
from=$1
i=1
while [ "$isFeb" = "" ] || [ "$is29" = "" ]
do
isFeb=`date -d "${from} ${i} days" | grep Feb`
is29=`date -d "${from} ${i} days" +%Y-%m-%d | grep "\-29"`
((i++))
done
((i--))
date -d "${from} ${i} days" +%A

샘플 I / O

:~/aman>./29Feb.sh 0001-01-01
Sunday
:~/aman>./29Feb.sh 1899-12-03
Monday
:~/aman>./29Feb.sh 1970-01-01
Tuesday

디폴트 시간대가 설정되어 있지 않은 경우 TZ를 설정해야 할 수도 있습니다, 내가 배운 cyberciti.biz/faq/... 일부 온라인 IDE에서이 작업을하는 동안
— 아만 ZeeK 베르

1
이거 골프가요? ; p 마지막 줄 앞의 모든 것을 다음과 같이 바꿀 수 있습니다i=0;d=;until [ `date -d"$1 $i days" +%m-%d` = "02-29" ];do((i++));done
— Peter Taylor

:-) 우리가 이미 bash에 대한 나의 원시성을 한 번에 논의했듯이! ... 어떤 이유로, 나는 bash를 많이 좋아하지 않습니다.. 그들은 너무 오류가 발생하기 쉽습니다! .. ur 제안에 감사드립니다 .. 업데이트되었습니다!
— Aman ZeeK Verma

1
Bash가있는 Rawness는 4 글자 변수 이름을 사용하는 데 대한 변명의 여지가 없습니다. : P
— Peter Taylor

네 선생님, 요점이 있습니다.
— Aman ZeeK Verma

2

펄 어떠한 일자 라이브러리 없음 160 159 155

하위 f {($ y, $ m) = 분할 /-/, @ _ ​​[0], 2; $ y ++ if ($ m> '02 -28 '); $ y = ($ y + 3) % 400 >> 2; $ y + = $ y &&! ($ y % 25); @ r = (화, 수, 목, 금, 토, 일, 월); @ r [(5 * $ y-($ y / 25 & 3)) % 7]. "일";}

이 날짜 라이브러리의 진정한 이점은 다른 사람들에게 요일 이름의 길이를 넓히는 것입니다.

반면에, 나는 이것이 로케일에 관계없이 지금까지 유일한 해결책이라고 생각합니다.


2

날짜와 약간의 접착제 (90)

함수:

f(){ while :;do $(date -d$1+1day +'set - %F %A 1%m%d');(($3==10229))&&break;done;echo $2;}

테스트 :

$ for x in 0001-01-01 1899-12-03 1970-01-01 1999-07-06 2003-05-22 2011-02-17 2100-01-01 ; do f $x ; done
Sunday
Monday
Tuesday
Tuesday
Sunday
Wednesday
Friday

1

D : 175 자

S f(S)(S s){auto d=Date.fromISOExtString(s)+days(1);while(d.month!=Month.feb||d.day!=29)d+=days(1);return["Sun","Mon","Tues","Wednes","Thurs","Fri","Sat"][d.dayOfWeek]~"day";}

더 읽기 :

S f(S)(S s)
{
    auto d = Date.fromISOExtString(s) + days(1);

    while(d.month != Month.feb || d.day != 29)
        d += days(1);

    return ["Sun", "Mon", "Tues", "Wednes", "Thurs", "Fri", "Sat"][d.dayOfWeek] ~ "day";
}

D로 작성하는 것은 매우 쉽지만 코드 골프 대회에서이기는 것은 아닙니다. 그럼에도 불구하고 코드 골프 외부에서는 작성하고 이해하기는 쉽지만 간결하지만 작성하고 이해하기는 어렵습니다.


1

자바 8-252 자

골프 :

import java.time.*;
import java.time.format.*;
public class S{public static void main(String[] a){LocalDate d=LocalDate.parse(a[0]).plusDays(1);while(d.getMonthValue()!=2||d.getDayOfMonth()!=29){d=d.plusDays(1);}System.out.println(d.getDayOfWeek());}}

언 골프 드 :

import java.time.*;
import java.time.format.*;
public class S {
    public static void main(String[] a) {
        LocalDate d = LocalDate.parse(a[0]).plusDays(1);

        while(d.getMonthValue()!=2 || d.getDayOfMonth()!=29) {
            d = d.plusDays(1);
        }
        System.out.println(d.getDayOfWeek());
    }
}

다운 보트를 수락하지만 "네크로는 실제"를 설명하고 요점을 설명하는 FAQ에 링크 할 수 있습니까? 나는 이길 것이라고 생각하지 않았지만 자바가 어떻게 할 수 있는지 보는 것이 흥미로울 것이라고 생각했다. Java 8이 주어졌습니다. 저는 코드 골프를 "무게 클래스"를 가지고있는 것으로 간주합니다. 자바가 루비 나 파이썬을 능가하는 경우는 거의 없습니다.
— Michael Easter

OP는 타사 라이브러리를 금지하므로 2011 년에 인기있는 Joda Time 라이브러리를 사용할 수 없으므로 Java 솔루션이 불쾌합니다. 그러나 Java 8 (2014 년 3 월 릴리스)에는 JSR-310 DateTime 라이브러리 ( en.wikipedia.org/wiki/… )가 포함되어 있습니다 . 내 이유는 Java 8이 재미 있고 일부 독자에게는 흥미로울 것이라고 생각했기 때문입니다. (당신이 그 중 하나가 아니라면 괜찮습니다 : 여전히 포스트의 이유가 있습니다.)
— Michael Easter

1

리볼-78

f: func[d][system/locale/days/(until[d: d + 1 d/day * d/month = 58]d/weekday)]

언 골프 드 :

f: func [d] [
    system/locale/days/(
        until [
            d: d + 1
            d/day * d/month = 58
        ]
        d/weekday
    )
]

사용법 예 (Rebol 콘솔) :

>> f 0001-01-01
== "Sunday"

>> f 2100-01-01
== "Friday"

1

PHP, 104 바이트

function f($s){for($y=$s-(substr($s,5)<"02-29");!date(L,$t=strtotime(++$y."-2-1")););return date(l,$t);}

고장

for($y=$s-;                 // "-" casts the string to int; decrement year if ...
    (substr($s,5)<"02-29")  // ... date is before feb 29
    !date(L,                        // loop while incremented $y is no leap year
        $t=strtotime(++$y."-2-1")   // $t=feb 01 in that year (same weekday, but shorter)
    );
);
return date(l,$t);          // return weekday name of that timestamp

date(L): 1윤년, 0기타
date(l): 요일의 전체 텍스트 표현


0

GNU coreutils, 71 바이트

f(){
seq -f "$1 %gday" 2921|date -f- +'%m%d%A'|sed 's/0229//;t;d;:;q'
}

향후 8 년간의 선형 검색 (2096-02-29를 기준으로 최악의 경우). Sed는 2 월 29 일과 일치하는 첫 번째 줄을 찾아 출력합니다.

두 배나 많은 명령에도 불구하고 t;d;:;q숫자가 남아 있는지 확인하기 위해 테스트하는 것보다 짧은 것이 놀랐습니다 /[01]/d;q.

테스트

어려운 코너 사례에 대한 추가 테스트 라인을 추가했습니다.

for i in 0001-01-01.Sunday 1899-12-03.Monday \
    1970-01-01.Tuesday     1999-07-06.Tuesday \
    2003-05-22.Sunday      2011-02-17.Wednesday 2100-01-01.Friday \
    2000-02-28.Tuesday     2000-02-29.Sunday    2000-03-01.Sunday   2096-02-29.Friday
do
    printf "%s => %s (expected %s)\n" ${i%.*} $(f ${i%.*}) ${i#*.}
done
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.