다음 공휴일


18

호주인들은 공휴일과 술을 좋아합니다. 어제 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

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


@insertusernamehere 좋은 제안에 감사드립니다! 질문에 날짜를 추가했습니다
Tas

@Tas 그 날짜가 맞습니까? 예제의 내용은 따옴표와 일치하지 않으며 둘 다 웹 사이트와 일치하지 않습니다.
Adam Martin

@AdamMartin 지적 해 주셔서 감사합니다. 12 월 날짜를 잘못 입력했습니다. 이 예의 날짜는 공휴일에만 국한되지 않은 날짜입니다. 입력 할 수있는 날짜와 출력 결과의 예일뿐입니다. 인용 된 사람이 해야한다 (희망 않음) 웹 사이트에서 사람을 일치합니다.
Tas

퀸즐랜드에서 10 월에 여왕의 생일을 축하합니까? 너무 이상하지만 링크에서 올바른 것 같습니다.
레벨 리버 St

와, 너희들 6 월부터 9 월까지 휴일이 없니? 거칠다.
Joe Z.

답변:


2

피스 , 98 84 62 67 바이트

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

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

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

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

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


하이픈으로 분리 된 입력을 좋아하지 않는 것 같지만 그렇지 않으면 훌륭합니다
Tas

@Tas 힌트를 주셔서 감사합니다, 그 부분을 완전히 읽었습니다 ... 5 바이트를 더 소비했습니다. 가능한 모든 입력 변형을 포함하기를 원하기 때문에 테스트 케이스에 하이픈을 추가해야 할 수도 있습니다.
Denker

5

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의 함수 이름이 로컬 변수로 작동하고 실행이 끝나면 함수에 의해 값이 자동으로 반환된다는 사실을 이용했습니다.


PPCG에 오신 것을 환영합니다! 여기서 우리는 인터프리터에 의해 프로그래밍 언어를 정의하므로 특정 로케일이 필요합니다.
lirtosiast

감사! 더 작은 로케일 종속 버전을 추가하도록 편집되었습니다.
04 초에 dnep

4

자바 스크립트 (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)


날짜를 하이픈으로 구분하면 항상 0이됩니다. 나는 OP가 테스트 케이스를 조정하도록 요청했습니다.
Denker

@ DenkerAffe 오, 그는 우리가 분리기를 자유롭게 선택할 수 있다고 생각했습니다. 덧붙여서, 그것을 구분 기호로 만들면 3 바이트가 절약되었으므로 감사합니다!
user81655

1
규칙 separated with a hyphen - or slash /이 약간 모호한 것 같습니다 . 나를 위해 그것은 우리가 둘 다를 처리해야 함을 의미하지만, 나는 분명히 당신 편을 볼 수 있습니다. OP가 이것을 명확히해야한다고 생각합니다.
Denker

3

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 는 선택하지 않고 선언 하고 할당합니다.


2

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

2

자바 스크립트 (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

파이썬 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

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


1

PHP, 116 바이트

매우 직접적인 접근 방식. 휴일의 연중 날짜를 저장하고 과거에있는 한 계속 표시됩니다. 마지막으로 요청 된 요일을 뺍니다.

for($x=[366,361,360,359,276,122,115,87,85,84];($a=date(z,strtotime($argv[1].'-2016')))>$t=array_pop($x););echo$t-$a;

모든 테스트 사례를 통과하십시오. 명령 행에서 실행하고 다음과 같이 하이픈을 사용하여 입력을 승인합니다.

$ php holidays.php "12-05"

1

루비 1.9.3, 155 153 바이트

성탄절 휴가 후, 우리는 우리의 특별한 날 366이 필요합니다! @DenkerAffe와 비슷한 경우입니다.

require'date'
c=(Date.strptime(ARGV[0],'%d/%m')-Date.parse('01/01')).to_i
print [84,85,87,115,122,276,359,360,361,366].map{|i|(i-c)}.select{|i|i>=0}.min

용법:

$ ruby i_want_to_break_free.rb "03/05"

Ruby에 대해서는 잘 모르지만 1 줄과 3 줄에서 공백을 제거하여 3 바이트를 절약 할 수 있다고 생각합니다. 또한 코드에서 분명하지 않기 때문에 사용중인 입력 방법을 지정해야합니다. 함수를 정의하여 일부 바이트를 절약 할 수 있으므로 입력을 인수로 사용하고 리턴 값을 출력으로 사용할 수 있습니다.
Denker

@DenkerAffe 감사합니다! 2 바이트를 절약했지만 함수가 숫자를 늘릴 것이라고 생각합니다. 사용법 예제로 답변을 업데이트했습니다.
Tarod

0

05AB1E , 45 바이트

•9JRt€ª´Q®Ië•368вDI„-/S¡`•Σ₁t•ºS₂+s<£O+©@Ïн®-

더 이상 2016 년이 아닐 수도 있지만, 무엇이든 ..;) 여전히 292 월 의 윤년을 위해 2016 년이라고 가정합니다 .

온라인으로 시도 하거나 모든 테스트 사례를 확인하십시오 .

설명:

9JRt€ª´Q®Ië•  # Push compressed integer 10549819042671399072072399
  368в         # Converted to base-368 as list: [85,86,88,116,123,277,360,361,362,367]
      D        # Duplicate this list
I              # Take the input
 „-/S¡         # Split it on ["-","/"]
      `        # Push both integer separated to the stack
•Σ₁t          # Push compressed integer 5354545
     º         # Mirror it without overlap: 53545455454535
      S        # Converted to a list of digits: [5,3,5,4,5,4,5,5,4,5,4,5,3,5]
       ₂+      # Add 26 to each: [31,29,31,30,31,30,31,31,30,31,30,31,29,31]
         s     # Swap to get the month-integer
          <    # Decrease it by 1
           £   # Only leave the first month-1 values from the integer-list
            O  # Sum that sublist
             + # And add it to the day-integer (so we now have the N'th day of the year)
©              # Save this in the register (without popping)
 @             # Do a >= check with each integer in the first (duplicated) list we created
  Ï            # Only leave the truthy values from the list
   н           # Then pop this sublist and only leave its first value
    ®-         # And subtract the integer we saved in the register (N'th day of the year)
               # (after which the result is output implicitly)

내이 05AB1E 팁을 참조하십시오 (섹션에서는 어떻게 큰 정수를 압축하는 데 어떻게?압축 정수 목록에 어떻게? ) 이유를 이해하는 •9JRt€ª´Q®Ië•것입니다 10549819042671399072072399; •9JRt€ª´Q®Ië•368в이다[85,86,88,116,123,277,360,361,362,367] ; 하고 •Σ₁t•있다 5354545.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.