다음 공휴일

호주인들은 공휴일과 술을 좋아합니다. 어제 1 월 26 일은 공휴일 인 호주의 날이었습니다. 나는 어제 직장에 가지 않아서 기뻤고, 다음에 공휴일을 맞이하는 것을 알고 싶어했습니다! 불행히도, 나는 술을 너무 많이 마셨고, 나 자신을 위해 그것을 해결할 수 없습니다.

날짜를 호주 날짜 / 시간 표기법 (dd / mm)으로 입력하고 다음 공휴일까지 일수를 출력 하는 프로그램을 작성하십시오 . 저는 퀸즈랜드 (QLD) 거주자이므로 퀸즈 랜더에 영향을주는 공휴일 에만 관심이 있습니다 .

25/03 | 성 금요일
26/03 | 부활절 토요일
28/03 | 부활절 월요일
25/04 | 안작 데이
02/05 | 노동절
03/10 | 여왕의 생일
25/12 | 크리스마스
26/12 | 박싱 데이
27/12 | 크리스마스 휴일

사이트에서 다음을 참고하십시오.

크리스마스 휴일

새해, 크리스마스 또는 박싱 데이가 주말에 추가 될 경우 추가 공휴일이 추가됩니다.

크리스마스는 일요일에 있기 때문에 공휴일 이 추가로 있습니다. 크리스마스는 여전히 공휴일입니다.

저는 오전 사람이므로 현재 날짜를 하루로 포함해야합니다 (다음 공휴일에 대한 프로그램을 확인할 가능성이 가장 높기 때문에). 즉, 공휴일 날짜를 입력하면 출력은 0; 공휴일 전날을 입력하면 출력은입니다 1.

나는 연말까지 지금 (27/01) 사이의 날짜에만 관심이 있습니다 . 당신이 계산해야 할 마지막 날짜는 31/12이며 출력은 1(설날)입니다.

표준 허점 은 금지되어 있습니다.

입력

  • 입력은 항상 5 자 (4 자, 하이픈 -또는 슬래시로 구분됨)입니다./
  • 입력 날짜는 27/01에서 31/12 사이입니다.

산출

  • 입력 날짜를 포함하여 호주 퀸즐랜드 공휴일까지의 일수 : 0및 사이 153(최대 간격) 여야합니다.
  • 새로운 줄이나 오류가 없습니다

01-05 = 1
02-05 = 0
03-05 = 153
25/12 = 0
26-12 = 0
27/12 = 0
30/12 = 2
31-12 = 1

잘만되면 이것이 분명하고 빠진 것이 없습니다. 그러나 이것은 두 번째 질문이므로 피드백을 보내 주시면 최대한 빨리 문제를 해결하기 위해 최선을 다하겠습니다.



답변

피스 , 98 84 62 67 바이트

최신 정보: 일 수 계산을 위해 12 개월 모두의 일 수 목록을 단축하여 14 바이트를 절약했습니다. 시도하고 다른 목록을 압축하는 좋은 방법을 찾지 못했습니다!

업데이트 2 : 날짜-숫자 목록을 base256 문자열로 엔드 코딩하여 22 바이트를 더 절약했습니다.

J30KhJ=Yc:z"\W"dd=N+s<[KtJKJKJKKJKJK)tseYshY-hfgTNCMc"UVXt{ĕŨũŪů"1N

온라인으로 사용해보십시오!

내 파이썬 답변과 같은 알고리즘. 그리고 하루 중 어느 날도 붙잡을 수 없었으므로 직접해야했습니다. 연중 계산과 휴일의 날에 대한 두 목록을 작성하는 데는 많은 비용이 듭니다 … 다시 살펴보고 더 적은 바이트로 생성하려고 시도하십시오.


답변

155 또는 118 바이트의 Visual Basic for Applications

버전 1-로케일 독립적, 155 바이트

Function h(d)
For i=0To 9
h=Array(0,1,3,31,38,192,275,276,277,282)(i)+42454-DateSerial(16,Val(Right(d,2)),Val(Left(d,2)))
If h>=0Goto 9
Next
9 End Function

버전 2-로케일 종속, 118 바이트

Function h(d)
For i=0To 9
h=Array(0,1,3,31,38,192,275,276,277,282)(i)+42454-CDate(d)
If h>=0Goto 9
Next
9 End Function

바이트 수는 줄 바꿈 문자를 포함하여 최종 .BAS 파일을위한 것입니다. 표준 VBA 편집기 외부에서 편집 (추가 키워드와 일부 키워드의 자세한 형태가 적용됨)-모든 Office 응용 프로그램에서 가져 오기 및 실행 (예 : ? h("10/08")직접 창에서 또는 Excel에서 직접 셀 수식에서 직접 테스트 )

(편집 됨) 처음에는 DateSerial함수를 로캘 안전 (버전 1)으로 만드는 데 사용 하기로 선택했습니다 . 브라질에 거주하고 있으므로 시스템이 날짜와 같이 “dd / mm / yy”형식을 사용하도록 구성되어 있기 때문에 (호주처럼) CDate대신 (버전 2)를 사용하여 더 작은 버전을 작성할 수 있습니다.CDate시스템 로캘 정보를 사용하여 텍스트를 날짜로 변환합니다. 또한이 버전에서 코드는 2016 년 동안 만 실행될 것이라고 가정했습니다 (연도가 생략 된 경우 (-6 바이트) CDate는 시스템 시계에 따라 현재 연도를 가정합니다).

세 번째 줄의 42454는 VBA에서 2016 년 1 월 1 일의 숫자 표현 인 42450의 합계이고 첫 번째 휴일의 날짜 인 84입니다. 이 배열에는 일부 공휴일이 없어 지므로 각 공휴일 (2017 년 1 월 1 일 포함)에 대해 -84로 오프셋 된 연도가 포함되어 있습니다. 에 2016 대신 16 사용DateSerial 2 바이트가 더 걸립니다.

반복 내에서 동일한 배열을 9 번 만드는 것은 “나쁜”코드이지만 작동하고 3 바이트를 더 저장합니다 (하나는 배열 이름 및 하나는 루프 외부 등호, 다른 하나는 루프 내부의 배열 참조).

두 번째 및 네 번째 행에서 0과 다음 키워드 사이의 “missing”공백은 모듈을 가져올 때 VBE에 의해 자동으로 다시 도입되므로 필요하지 않습니다. 오래된 사용하지만, 바이트 싼이 If <...> Goto <linenumber>(루프에서 휴식을 모두 If <...> Then Exit ForIf <...> Then Exit Function 더 많은 문자를 사용).

또한 VBA의 함수 이름이 로컬 변수로 작동하고 실행이 끝나면 함수에 의해 값이 자동으로 반환된다는 사실을 이용했습니다.


답변

자바 스크립트 (ES6) 131 128 바이트

d=>[56,57,59,87,94,248,331,332,333,338].map(n=>r=r||(q=1454e9+n*864e5-new Date(d[3]+d[4]+`/${d[0]+d[1]}/16`))>=0&&q/864e5,r=0)|r

설명

JavaScript 내장 Date생성자를 사용하여 에포크 이후 입력 문자열을 여러 밀리 초로 변환 한 다음 각 공휴일의 밀리 초 수와 비교합니다.

이는 공휴일을 참조 날짜 이후의 일 수로 배열에 저장하여 수행합니다. 2016-01-29에포크 이후 밀리 초가이 날짜에 가장 짧게 압축 될 수 있기 때문에 참조 날짜로 선택했습니다 . 결과가 반올림되므로 오늘과 다음 작품 사이의 밀리 초 수는 중간에 숫자를 유지하면 일광 절약 효과를 피할 수 있습니다 (OP 시간대에는 일광 절약 시간이 없지만). 이 날의 숫자는 1453986000000반올림 1454000000000(2 시간 더함)으로 쓸 수 있음을 의미합니다 1454e9.

d=>
  [56,57,59,87,94,248,331,332,333,338]             // list of day offsets from 01/29
  .map(n=>                                         // for each public holiday offset n
    r=r||                                          // if r is already set, do nothing
      (q=                                          // q = approximate difference in ms
        1454e9+n*864e5                             // time of public holiday
        -new Date(d[3]+d[4]+`/${d[0]+d[1]}/16`)    // time of input date
      )
      >=0&&                                        // if q >= 0
        q/864e5,                                   // r = q in days
    r=0                                            // r = result
  )
  |r                                               // floor and return r

테스트

이 솔루션은 사용자 시간대에 따라 다릅니다. 이것은 OP (및 내) 시간대 (GMT +1000)에서 작동합니다. 당신이 추가, 다른 시간대에서 테스트하려면 numberOfHoursDifferentFromGMT1000 * 60 * 60 * 1000날짜 수를 기준으로 해야 작동합니다. (예 : GMT +0430은 -5.5 * 60 * 60 * 1000 + 1454e9+n*864e5)

var solution = d=>[56,57,59,87,94,248,331,332,333,338].map(n=>r=r||(q=1454e9+n*864e5-new Date(d[3]+d[4]+`/${d[0]+d[1]}/16`))>=0&&q/864e5,r=0)|r
<input type="text" id="input" value="03/05" />
<button onclick="result.textContent=solution(input.value)">Go</button>
<pre id="result"></pre>

답변

T-SQL, 210 , 206 , 194 바이트

(첫 번째 게시물은 여기에 좋기를 바랍니다.하지만 좋을 것입니다 🙂

입력 들어가는 @i모두,를 충족시켜 /-세퍼레이터로. 저는 호주에 있으므로 날짜 형식은 @Tas와 같습니다.

DECLARE @i CHAR(5)='23-09';DECLARE @c INT=DATEPART(dy,CAST(REPLACE(@i,'-','/')+'/2016' AS DATE))-1;SELECT MIN(b)-@c FROM(VALUES(84),(85),(87),(115),(122),(276),(359),(360),(361))a(b)WHERE b>=@c;

3 바이트 varcharchar절약하고 공백을 제거하는 업데이트 🙂

업데이트 2@c 는 선택하지 않고 선언 하고 할당합니다.


답변

T-SQL, 296 바이트

테이블 값 함수로 생성

create function d(@ char(5))returns table return select min(o)o from(select datediff(day,cast('2016'+right(@,2)+left(@,2)as date),cast(right('2016'+right('0'+cast(d as varchar(4)),4),8)as datetime)+1)o from(values(324),(325),(327),(424),(501),(1002),(1224),(1225),(1226),(1231))d(d))d where 0<=o

다음과 같은 방식으로 사용

SELECT *
FROM (
    VALUES
        ('01/05') --= 1
        ,('02/05') --= 0
        ,('03/05') --= 153
        ,('25/12') --= 0
        ,('26/12') --= 0
        ,('27/12') --= 0
        ,('30/12') --= 2
        ,('31/12') --= 1
    )testData(i)
    CROSS APPLY (
        SELECT * FROM d(t)
    ) out

i     o
----- -----------
01/05 1
02/05 0
03/05 153
25/12 0
26/12 0
27/12 0
30/12 2
31/12 1

(8 row(s) affected)

간단한 설명

create function d(@ char(5)) returns table  -- function definition
return
select min(o)o -- minimum set value
from(
    select datediff( -- date difference
        day, -- day units
        cast('2016'+right(@,2)+left(@,2)as date), -- convert input parameter to date
        cast(right('2016'+right('0'+cast(d as varchar(4)),4),8)as datetime)+1 -- convert int values into datetimes and add a day
        )o
    from(
        values(324),(325),(327),(424),(501),(1002),(1224),(1225),(1226),(1231) -- integers representing the day before public holidays
        )d(d)
    )d
where 0<=o -- only for values >= 0

답변

자바 스크립트 (ES6), 134 바이트

x=>[0,1,3,31,38,192,275,276,277,282].find(z=>z>=(q=x[0]+x[1]- -[...'20212122121'].slice(0,x[3]+x[4]-1).reduce((a,b)=>+b+a+29,0)-85))-q

user81655는 여전히 3 바이트로 이길 수는 있지만 여기서 아무 것도 짜낼 수있는 곳은 없습니다. Date를 사용하는 대신 지나간 일 수를 계산 한 다음 휴일 오프셋 배열과 비교하여 작동합니다.


답변

파이썬 2 204 185 165 166 바이트

업데이트 : 혼자서 하루를 계산하여 ~ 20 바이트까지 내 렸습니다. 더 이상 긴 수입이 필요 없습니다 🙂

업데이트 2 : 367 일로 새해를 다룰 수 있고 다른 작은 조정을 통해 20 년을 더 줄입니다.

def f(d):d=[d[:2],d[3:]];y=sum([31,29,31,30,31,30,31,31,30,31,30,31][:int(d[1])-1])+int(d[0]);return filter(lambda n:n>=y,[85,86,88,116,123,277,360,361,362,367])[0]-y

온라인으로 사용해보십시오!

언 골프 드 :

def f(d):
    l=[85,86,88,116,123,277,360,361,362,367]
    d=[d[:2],d[3:]]
    y=sum([31,29,31,30,31,30,31,31,30,31,30,31][:int(d[1])-1])+int(d[0])
    f=filter(lambda n:n>=y,l)
    return f[0]-y

휴일의 일 수를 목록에 저장하고 주어진 날짜 이전의 휴일을 필터링하고 필터링 된 목록의 첫 번째 요소를 빼고 일을 빼서 작동합니다. 입력에서 계산되었습니다.