오늘 밤이나 이번 주말에 다시 연결


20

이것은 첫 번째 코드 골프이므로 너무 광범위하거나 좋은 퍼즐에 대한 정보가 누락 된 경우 알려주십시오!

도전

온타리오 및 전 세계 다른 지역에서는 전력 사용 시간에 따라 킬로와트시 당 비용이 달라지는 TOU (Time-Of-Use ) 요금을 사용하여 전기 요금이 청구됩니다 .

날짜와 시간이 주어지면 내가 피크에 있거나 (빨간색), 중간에 피크 (노란색) 또는 피크가 아닌 (녹색) 기간인지 알고 싶습니다.

입력

입력이 최소 시간 정밀도로 허용 가능한 표준 시간대가없는 ISO 8601 날짜-시간 형식 으로 제공되었다고 가정합니다 YYYY-MM-DDThh[:mm[:ss]](T는 리터럴).

  • 2014-09-01T14
  • 2014-09-01T17 : 30
  • 2014-09-01T17 : 30 : 02

산출

출력은 문자열이어야한다 On, Mid또는 Off.

규칙

  • 최단 코드 승리
  • 이 도전의 목적 상, 법정 공휴일은 무시하십시오
  • 이 게시물에있는 정보를 가정하십시오. 실제 사용 시간 가격 책정 규칙은 온타리오 에너지 부에 의해 미래에 변경 될 수 있습니다.

정보

여름 평일 (5 월 1 일 ~ 10 월 31 일)

여름 주중 사용 시간 시계

  • 피크가 아닌 : 19h00-07h00
  • 미드 피크 : 07h00-11h00 및 17h00-19h00
  • 피크 : 11h00-17h00

겨울 평일 (11 월 1 일 ~ 4 월 30 일)

겨울 평일의 사용 시간 시계

  • 피크가 아닌 : 19h00-07h00
  • 중간 피크 : 11h00-17h00
  • 피크 : 07h00-11h00 및 17h00-19h00

주말

주말에 사용 시간 시계

  • 사용량이 적음 : 하루 종일

겨울 주중에 미드 피크 / 온 피크가 바뀌지 않았습니까?
John Dvorak

3
@JanDvorak, 겨울철 사람들은 아침과 저녁에 조명과 난방을 사용합니다. 여름에는 정오에 에어컨을 사용합니다.
피터 테일러

4
이것은 codegolf.stackexchange.com/q/7008/194의 경계선 복제입니다 (날짜 시간을 구문 분석하고 근무일 인지 여부에 따라 간단한 계산을 수행하십시오). 나는 계절 의존성이 충분히 다르다고 생각하지만 다른 사람들은 동의하지 않을 수 있습니다.
피터 테일러

@PeterTaylor 규칙은 연결된 질문보다 훨씬 간단 해 보입니다. 예를 들어 윤년을 처리 할 필요는 없습니다.
John Dvorak

3
YYYY-MM-DDThh[:mm[:ss]]분을 적용한 경우에만 초를 적용 할 수 있으므로 일반적인 날짜 형식이어야 합니까?
Cruncher

답변:


3

루비 - 147 144 143 141 137 135

x=->s{y,m,d,h=s.scan(/\d+/).map &:to_i
g=Time.new(y,m,d).wday%6<1?0:[0..11,4..9].count{|r|r===h-7}
%W{Off Mid On}[m<5||m>10?(3-g)%3:g]}

문자열을 매개 변수로 사용하고 문자열을 반환하는 함수를 나타냅니다.

다음은 몇 가지 테스트 사례가있는 온라인 데모입니다. http://ideone.com/wyIydw


8

파이썬 2-164

from datetime import*
d,t=input().split('T')
y,m,d=map(int,d.split('-'))
t=int(t[:2])
print'OMOfinfd'[(1+((10<t<17)==(4<m<11)))*(date(y,m,d).weekday()<5<6<t<19)::3]

필요한 경우, 다음은 마지막 행의 논리에 대한 설명입니다.

마지막 줄 'OMOfinfd'은 조건부 평가에 따라 슬라이스를 인쇄합니다 .

  • 먼저 작업을 평가하십시오 1+((10<t<17)==(4<m<11)).

    조건 사이의 XNOR 경우 10<t<17와는 4<m<11이다 False, 이것은로 평가됩니다 1+False => 1+0 => 1. 그렇지 않으면 작업이로 평가됩니다 1+True => 1+1 => 2.

  • 마지막으로, 위 작업의 결과에 요일이 요일인지 여부와 시간이 오전 6시에서 오후 7시 사이인지 곱하십시오.

    이 경우 False하루는 주말이거나 시간은 오후 7시에서 오전 6시 사이이며 결과는입니다 (1|2)*0 => 0. 그렇지 않으면 결과는입니다 (1|2)*1 => 1|2.

의 결과는 0인쇄됩니다 Off, 1인쇄됩니다 Mid2인쇄됩니다 On.


세미콜론을 사용하기 때문에 골프 버전이 실제로 더 길지 않습니까? 아니면 줄 바꿈이 계산됩니까?
Beta Decay

줄 바꿈은 일반적으로 계산됩니다. 메모장 ++ (일반적으로 내 카운트를 얻는 곳)에서 ungolfed 버전은 168에서 4 바이트 더 깁니다.
BeetDemGuise

3
@BeetDemGuise 편집 → EOL 변환 → UNIX / OSX 형식.
Schism

5

C 번호 - 240 개 220 문자

string x(string s){var d=DateTime.Parse((s+":00:00").Substring(0,19));int h=d.Hour,i=(int)d.DayOfWeek,x=d.Month;string o="off",m="mid",f="on";return i==6|i==0?o:x>=5&x<11?h>18|h<7?o:h>10&h<17?f:m:h>18|h<7?o:h>10&h<17?m:f;}

특별한 것은 없습니다. 직접 코딩.

w0lf 덕분에 :)


1
나는 당신이 단축 될 수 있습니다 생각 s.Length==13?s+":00:00":s.Length==16?s+":00":s(s+":00:00").Substring(0,19)
크리스티안 루파 스쿠

5

루비-135

시간 모듈을 남용합니다. 명령 행 인수로 입력합니다.

d=Time.new(*$*[0].scan(/\d+/)[0..3])
o,m,f=%w{On Mid Off}
o,m=m,o if (d.mon-5)%10<6
p d.wday%6<1||(12>h=(d.hour+5)%24)?f:15<h&&h<22?m:o

편집 : 버그를 줄이고 해결하는 데 도움이되는 Time for w0lf에게 감사드립니다.


프로그램이 잘못되었습니다. 입력의 2014-09-01T17:30경우 올바르게 출력 "Mid"되지만 출력의 경우 2014-09-01T17에는 출력 "Off"됩니다.
Cristian Lupascu

3

그루비 - 621 개 534 524 491 문자

Joda-Time을 활용할 때 약간의 추가 골프,하지만 매우 간단

@Grab(group='joda-time',module='joda-time',version='2.3')
f={p,a->org.joda.time.format.DateTimeFormat.forPattern(p).parseDateTime a}
g={p,a->def x=null;try{x=f p,a}catch(Exception e){}}
a=args[0]
d=["",":mm",":mm:ss"].collect{g "yyyy-MM-dd'T'HH$it",a}.find{it}
r="Off"
m="Mid"
j={d,a,b->d.hourOfDay>a&&d.hourOfDay<b}
k={j(it,6,11)||(j(it,16,19))}
if(d.dayOfWeek<6){x=d.monthOfYear;if(x>4&&x<12){if(j(d,10,17))r="On";if(k(d))r=m}else if(x<5||x>10){if(j(d,10,17))r=m;if(k(d))r="On"}}
println r

샘플 실행 :

bash-3.2$ ./run.peak.sh 
groovy Peak.groovy 2014-08-26T19
Off
groovy Peak.groovy 2014-08-26T07:00
Mid
groovy Peak.groovy 2014-08-26T18:00:00
Mid
groovy Peak.groovy 2014-08-26T12:30:30
On
groovy Peak.groovy 2014-11-01T00
Off
groovy Peak.groovy 2014-02-05T11:11:11
Mid
groovy Peak.groovy 2014-01-05T08:08
Off
groovy Peak.groovy 2014-12-18T18:59:59
On
groovy Peak.groovy 2014-08-31T14
Off

언 골프 드 :

@Grab(group='joda-time',module='joda-time',version='2.3')

f = { p,a -> org.joda.time.format.DateTimeFormat.forPattern(p).parseDateTime a}
g = { p,a -> def x=null; try{x=f p,a} catch(Exception e) {} }
a=args[0]

d = ["",":mm",":mm:ss"].collect{g "yyyy-MM-dd'T'HH$it",a}.find{it}
r = "Off"
m = "Mid"

j = {d,a,b -> d.hourOfDay > a && d.hourOfDay < b}
k = { j(it,6,11) || (j(it,16,19)) }

if (d.dayOfWeek<6) {
    x = d.monthOfYear;
    if ( x>4 && x<12 ) {
        if (j(d,10,17)) r="On";
        if (k(d)) r=m
    } else if (x<5||x>10) {
        if (j(d,10,17)) r=m;
        if (k(d)) r="On"
    }
}
println r

2
Java 8부터는 java.time.*Joda Time과 매우 유사하지만 JRE의 일부이기도합니다. 아마도 이것은 코드를 약간 단축시킬 수 있습니다.
ntoskrnl

재 : 자바 8. 우수한 요점
Michael Easter

마지막 세 번째 예제 '2014-01-05T08:08'에서 2014 년 1 월 5 일은 일요일입니다. 따라서'Off'
BeetDemGuise

re : 2014 년 1 월 5 일. 그렇습니다. 현재 코드는 정확하지만 출력 실행이 잘못되었습니다. 해결됩니다.
Michael Easter

시도했다 java.time.*. 비참하게 실패했습니다. 파서가 너무 엄격합니다. 사용 DateParser관대하고, 학대 해킹의 비트, 분 및 초를 건너 뛸 경우에도 관대 충분한 함께 nashorn합니다 (JRE8의도 부분)에서.
Mark Jeronimus

2

R, 243204

b=strptime(scan(,""),"%Y-%m-%dT%H");i=function(x)as.integer(format(b,x));h=i("%H");d=i("%m%d");w=d>1100|d<430;f=ifelse;cat(c("Off","Mid","On")[f(i("%u")%in%5:6|h<7|h>19,1,f(h>11&h<17,f(w,2,3),f(w,3,2)))])

들여 쓰기 및 코멘트 :

b=strptime(scan(,""),"%Y-%m-%dT%H") #Takes stdin and converts into POSIXct
i=function(x)as.integer(format(b,x)) #Format the POSIXct and convert it to integer
h=i("%H")      #Format to hours
d=i("%m%d")    #Format to Month/Day
w=d>1100|d<430 #True if winter time, false if summer
f=ifelse
cat(c("Off","Mid","On")[f(i("%u")%in%5:6|h<7|h>19, #If weekend or night
                          1,                       #Case 1
                          f(h>11&h<17,            #Else if mid-day
                             f(w,3,2),             #Case 2 in winter, case 3 in summer
                             f(w,2,3)))])          #else vice versa

예 :

> b=strptime(scan(,""),"%Y-%m-%dT%H");i=function(x)as.integer(format(b,x));h=i("%H");d=i("%m%d");w=d>1100|d<430;f=ifelse;cat(c("Off","Mid","On")[f(i("%u")%in%5:6|h<7|h>19,1,f(h>11&h<17,f(w,3,2),f(w,2,3)))])
1: 2014-08-26T15
2: 
Read 1 item
On
> b=strptime(scan(,""),"%Y-%m-%dT%H");i=function(x)as.integer(format(b,x));h=i("%H");d=i("%m%d");w=d>1100|d<430;f=ifelse;cat(c("Off","Mid","On")[f(i("%u")%in%5:6|h<7|h>19,1,f(h>11&h<17,f(w,3,2),f(w,2,3)))])
1: 2014-12-10T15
2: 
Read 1 item
Mid
> b=strptime(scan(,""),"%Y-%m-%dT%H");i=function(x)as.integer(format(b,x));h=i("%H");d=i("%m%d");w=d>1100|d<430;f=ifelse;cat(c("Off","Mid","On")[f(i("%u")%in%5:6|h<7|h>19,1,f(h>11&h<17,f(w,3,2),f(w,2,3)))])
1: 2014-08-26T23
2: 
Read 1 item
Off

1

배쉬, 286

이것은 날짜 프로그램을 사용한 간단한 배쉬 답변입니다.

d(){ date -d $1 +%$2; };D=$(echo $1|sed 's/\(T..\)$/\1:00/');H=$(d $D H);M=$(d $D m);if [ $(d $D u) -gt 5 ]||[ $H -lt 7 ]||[ $H -gt 18 ];then echo Off;exit;fi;if [ $M -gt 4 ]&&[ $M -lt 11 ];then I=On;O=Mid;else I=Mid;O=On;fi;if [ $H -gt 10 ]&&[ $H -lt 17 ];then echo $I;else echo $O;fi

1

여기 또 하나 간다!

자바 스크립트, 175 (171)

function f(x){d=new Date(x.slice(0,10));t=x.slice(11,13),m=(x.slice(5,7)+1)%12;return(t<8||t>18||!(d.getUTCDay()%6)?'off':((t<11||t>17)?(m<5?'on':'mid'):(m<5?'mid':'on'))}

미완성 :

function f(x) {
  d = new Date(x.slice(0, 10));
  t = x.slice(11, 13), m = (x.slice(5, 7) + 1) % 12;
  return (t < 8 || t > 18 || !(d.getUTCDay() % 6) ? 'off' : ((t < 11 || t > 17) ? (m < 5 ? 'on' : 'mid') : (m < 5 ? 'mid' : 'on'))
}

ISO8601 날짜 문자열을 Date생성자에 전달할 수있는 인터프리터에서만 작동합니다 .

CoffeeScript, 192 189

놀랍게도, 해당 언어의 삼항 연산자가 없기 때문에 CoffeeScript에서 더 길어졌습니다 (JavaScript에서 볼 수 있듯이 크게 의존했습니다).

f=(x)->d=new Date(x.slice(0,10));t=x.slice(11,13);m=(x.slice(5,7)+1)%12;return'off'if(t<8||t>18||!(d.getUTCDay()%6));if(t<11||t>17)then(if m<5then'on'else'mid')else(if m<5then'mid'else'on')

0

ES6-146

이것은 함수 형태이며 몇 가지 불쾌한 핵을 사용합니다.

let y,m,d,h,c=s=>[y,m,d,h]=s.split(/[T:-]/g).map(i=>+i),new Date(y,m,d).getDay()in{0:1,6:1}||h<20||8>h?'Off':['Mid','On'][(10>h&&h>16)^(m>5||m<8)]

설명 :

// These variables are declared outside of the function scope to save
// characters.
let y, // year
    m, // month
    d, // day
    h, // hour
    c = s => // c for check, called as c(isoString)
      [y, m, d, h] = // Assign to fields
        s.split(/[T:-]/g) // Split at delimiters
         .map(i => +i), // Convert all to numbers
                        // Comma used to keep it as a single statement.
      new Date(y, m, d).getDay() // Create Date to get day of week
        in {0:1, 6:1} // Check if it is good (0 = Sunday, 6 = Saturday). It
                      // is shorter to use an object literal than to
                      // do individual checks.
      ||
      h < 20 || 8 > h ? // h is between 7 and 19 (7pm)
       'Off' : // Return 'Off'
       ['Mid','On'][ // Two other outputs
        (10 > h && h > 16) ^ // Check if it is 11-16 (5pm)
        (m > 5 || m < 8)] // Invert that if the month is in summer/fall. Note
                          // that this returns a number, either 1 or 0. This
                          // is an ugly hack using the bitwise xor operator.

0

파이썬 3-352 자

import datetime as dt
t=input()
i=int
p=print
a='on'
b='mid'
c='off'
m=i(t[5:7])
h=i(t[11:13])
d=dt.date(i(t[0:4]),m,i(t[8:10])).weekday()
if 5==d or 6==d:p(c)
elif h>=19 and h<7:p(c)
elif m<=10 and m>=4:
 if h>=7 and h<11:p(b)
 if h>=11 and h<17:p(a)
 if h>=17 and h<19:p(b)
else:
 if h>=7 and h<11:p(a)
 if h>=11 and h<17:p(b)
 if h>=17 and h<19:p(a)

1
당신은 변경해야합니다 s=['high','mid','off']s=['on','mid','off']뿐만 아니라 2 개 문자 저장이 작업을 수행하지만, 스펙 "의"출력 말한다 -.
Sellyme

0

Java- 426309 /301? (댓글 참조)

String z(String a){
    DateParser b=new DateParser(a);
    boolean c=b.parseEcmaDate();
    Integer[]d=b.getDateFields();
    GregorianCalendar e=new GregorianCalendar(d[0],d[1]-(c?0:1),d[2]);
    e.setTimeZone(new SimpleTimeZone(0,""));
    return(124>>e.get(7)&1)>0&d[3]>6&d[3]<19?
           d[3]>10&d[3]<17^(1008>>e.get(2)&1)>0?"Mid":"On":"Off";
}

출력 예 :

2014-03-02T00   Off
2014-03-02T06   Off
2014-03-02T07   Off
2014-03-02T10   Off
2014-03-02T11   Off
2014-03-02T16   Off
2014-03-02T17   Off
2014-03-02T18   Off
2014-03-02T19   Off
2014-03-02T23   Off
2014-04-02T00   Off
2014-04-02T06   Off
2014-04-02T07   On
2014-04-02T10   On
2014-04-02T11   Mid
2014-04-02T16   Mid
2014-04-02T17   On
2014-04-02T18   On
2014-04-02T19   Off
2014-04-02T23   Off
2014-05-02T00   Off
2014-05-02T06   Off
2014-05-02T07   Mid
2014-05-02T10   Mid
2014-05-02T11   On
2014-05-02T16   On
2014-05-02T17   Mid
2014-05-02T18   Mid
2014-05-02T19   Off
2014-05-02T23   Off

파이썬 제출과 동일한 EXOR 트릭을 사용했습니다. 또한 +때 OR 함수로 OR 함수를 사용 했습니다 weekend OR night.

내 다른 큰 트릭 : 비트 마스크.

예를 들어 숫자가 2에서 6 사이 (월요일에서 금요일)인지 확인하려면 먼저 흥미로운 값이 1 인 비트 패턴을 만듭니다.

  6   2 
0b1111100 = 124

그런 다음 비트 시프트를 사용하여 재미있는 비트를 LSB에 가져 와서 추출하십시오.

(124 >> day_of_week) & 1

마찬가지로 몇 달과 몇 시간 동안 비트 패턴을 만들었습니다.

  9    4
0b1111110000 = 1008

      76          76
0b111110000000000001111111 = 16253055
0b000000011111100000000000 = 129024

불행히도, x>y&x<z대부분의 경우 단순히 짧아서 일부 지역에서는 사용하지 않았습니다.

그리고 마지막으로, 약간의 해커 (매우 구현에 따라 다름) jdk.nashorn.internal.parser.DateParser: parseEcmaDate()날짜를 완전히 파싱하지 않으면 (시간을 읽고 문자열 끝을 칠 때와 같이) false를 반환합니다.

  • 제대로 완료되면 날짜는 Integer[](자동 Java unboxing ftw)에 저장되며 다른 Java 클래스와 마찬가지로 월은 기본 0으로 고정됩니다.
  • false를 반환하면 중간에 중단 되었으며이 수정을 수행하지 않았습니다. 그러나 여전히 구문 분석 된 내용을 배열에 넣었으므로 쉽게 사용할 수 있습니다. 따라서 -(c?0:1).

나는 사용하는 .parse()것도 효과가 있다고 생각 하지만 (8 자 제외) 다른 입력으로 철저히 테스트하지는 않았습니다. parse내부적으로 호출 parseEcmaDate하고 실패하면을 호출합니다 parseLegacyDate. 후자는 배열을 망칠 수 있지만 테스트 한 몇 가지 경우에는 발생하지 않았습니다.
Mark Jeronimus

-1

아무것도 내가 내 자신을 입력하는 것을 막을 수 없으며, 여기에 더 짧은 것이 있습니다.

PHP 5.4+, 194

<?function f($x){$t=substr($x,11,2);$m=(substr($x,5,2)+1)%12;if($t<8||$t>18||(new DateTime(substr($x,0,10)))->format('N')>5)return'off';return($t<11||$t>17)?($m<5?'on':'mid'):($m<5?'mid':'on');}

축소 및 댓글 :

<?
function f($x) {
  $t = substr($x,11,2); // hour
  $m = (substr($x,5,2) + 1) % 12; // month shifted up by 1

  if ($t < 8 || $t > 18 || (new DateTime(substr($x,0,10)))->format('N') > 5)
    return 'off'; // evenings and weekends

  return ($t < 11 || $t > 17)
    ? ($m < 5 ? 'on' : 'mid') // morning and mid-afternoon
    : ($m < 5 ? 'mid' : 'on'); // afternoon
}

또한 date.timezonephp.ini 의 지시어를 설정해야합니다. 그렇지 않으면 예외가 발생합니다.

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