Cắm lại vào tối nay hoặc cuối tuần này


20

Đây là môn đánh gôn đầu tiên của tôi, vì vậy xin vui lòng cho tôi biết nếu nó quá rộng hoặc nếu tôi thiếu bất kỳ thông tin nào cho một câu đố hay!

Thử thách

Ở Ontario và có thể các khu vực khác trên thế giới, điện được lập hóa đơn bằng cách sử dụng giá theo Thời gian sử dụng (TOU) , thay đổi chi phí cho mỗi kilowatt-giờ tùy theo thời điểm bạn sử dụng điện.

Đưa ra một ngày và thời gian, tôi muốn biết liệu tôi đang ở trong khoảng thời gian trên đỉnh (đỏ), giữa cao điểm (vàng) hay ngoài đỉnh (xanh lục).

Đầu vào

Giả sử rằng đầu vào được cung cấp theo định dạng thời gian theo thời gian ISO 8601 không có múi giờ chấp nhận được với độ chính xác tối thiểu của giờ: YYYY-MM-DDThh[:mm[:ss]](T là bằng chữ).

Ví dụ

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

Đầu ra

Kết quả phải là một chuỗi On, Midhoặc Off.

Quy tắc

  • Mã ngắn nhất sẽ thắng
  • Đối với mục đích của thách thức này, bỏ qua các ngày lễ theo luật định
  • Giả sử thông tin tìm thấy trong bài này. Các quy tắc thực tế về giá cả thời gian sử dụng có thể thay đổi trong tương lai của Bộ Năng lượng Ontario.

Thông tin

Các ngày trong tuần (từ 1 tháng 5 đến 31 tháng 10)

Đồng hồ thời gian sử dụng cho các ngày trong tuần

  • Ngoài giờ cao điểm: 19h00 - 07h00
  • Đỉnh cao: 07h00 - 11h00 và 17h00 - 19h00
  • Trên đỉnh: 11h00 - 17h00

Các ngày trong tuần mùa đông (ngày 1 tháng 11 đến ngày 30 tháng 4)

Đồng hồ thời gian sử dụng cho các ngày trong tuần mùa đông

  • Ngoài giờ cao điểm: 19h00 - 07h00
  • Đỉnh cao: 11h00 - 17h00
  • Trên giờ cao điểm: 07h00 - 11h00 và 17h00 - 19h00

Cuối tuần

Đồng hồ thời gian sử dụng vào cuối tuần

  • Ngoài giờ cao điểm: Cả ngày

Bạn có chắc chắn các ngày trong tuần mùa đông không bị tráo đổi giữa cao điểm / cao điểm không?
John Dvorak

3
@JanDvorak, vào mùa đông người ta dùng đèn và sưởi ấm vào buổi sáng và buổi tối; vào mùa hè, họ sử dụng máy lạnh vào giữa trưa.
Peter Taylor

4
Đây là bản sao biên giới của codegolf.stackexchange.com/q/7008/194 (phân tích thời gian và thực hiện một phép tính đơn giản dựa trên việc đó có phải là ngày làm việc hay không). Tôi nghĩ rằng sự phụ thuộc mùa chỉ đủ khác nhau, nhưng những người khác có thể không đồng ý.
Peter Taylor

@PeterTaylor các quy tắc có vẻ đơn giản hơn nhiều so với câu hỏi được liên kết. Điều này không phải xử lý năm nhuận chẳng hạn.
John Dvorak

3
Định dạng ngày chung có nên YYYY-MM-DDThh[:mm[:ss]]vì giây chỉ có thể được áp dụng nếu phút được áp dụng không?
Cruncher

Câu trả lời:


3

Hồng ngọc - 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]}

Điều này đại diện cho một hàm lấy một chuỗi làm tham số và trả về một chuỗi.

Đây là bản demo trực tuyến với một số trường hợp thử nghiệm: http://ideone.com/wyIydw


8

Con trăn 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]

Nếu cần, dưới đây là giải thích về logic trong dòng cuối cùng:

Dòng cuối cùng in một lát 'OMOfinfd'tùy thuộc vào đánh giá các điều kiện của nó.

  • Đầu tiên, đánh giá hoạt động 1+((10<t<17)==(4<m<11)).

    Nếu XNOR giữa các điều kiện 10<t<174<m<11False, điều này sẽ đánh giá 1+False => 1+0 => 1. Nếu không, hoạt động sẽ đánh giá 1+True => 1+1 => 2.

  • Cuối cùng, nhân kết quả của hoạt động trên với liệu ngày đó có phải là một ngày trong tuần hay không và liệu thời gian có trong khoảng từ 6 giờ sáng đến 7 giờ tối hay không.

    Nếu đây là False, một ngày là cuối tuần hoặc thời gian là từ 7 giờ tối đến 6 giờ sáng, và kết quả sẽ là (1|2)*0 => 0. Nếu không thì kết quả sẽ là (1|2)*1 => 1|2.

Một kết quả 0sẽ in Off, 1sẽ in Mid2sẽ in On.


Không phải là phiên bản golf thực sự dài hơn bởi vì bạn sử dụng dấu chấm phẩy? Hoặc là những dòng mới được tính?
Beta Decay

Dòng mới thường được tính. Trong Notepad ++ (nơi tôi thường lấy số đếm của mình), phiên bản không có bản quyền dài hơn 4byte ở 168.
BeetDemGuise

3
@BeetDemGuise Chỉnh sửa → Chuyển đổi EOL → Định dạng UNIX / OSX.
Schism

5

C # - 240 220 ký tự

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;}

Không có gì đặc biệt. Mã hóa thẳng về phía trước.

Cảm ơn w0lf :)


1
Tôi nghĩ bạn có thể rút ngắn s.Length==13?s+":00:00":s.Length==16?s+":00":sxuống(s+":00:00").Substring(0,19)
Cristian Lupascu

5

Hồng ngọc - 135

Lạm dụng mô-đun Thời gian. Nhập bằng đối số dòng lệnh.

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

Chỉnh sửa: Cảm ơn w0lf vì Thời gian đã giúp rút ngắn và khắc phục lỗi.


Chương trình của bạn không chính xác. Đối với đầu vào, 2014-09-01T17:30nó xuất ra chính xác "Mid", nhưng đối với 2014-09-01T17đầu ra "Off".
Cristian Lupascu

3

Groovy - 621 534 524 491 ký tự

Một số cách chơi gôn khác để làm, nhưng khá đơn giản khi tận dụng 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

mẫu chạy:

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

Ung dung:

@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
Kể từ Java 8, cũng có java.time.*, rất giống với Joda Time nhưng là một phần của JRE. Có lẽ điều này có thể rút ngắn mã một chút.
ntoskrnl

re: Java 8. điểm tuyệt vời
Michael Easter

Trong ví dụ thứ 3 đến cuối cùng của bạn '2014-01-05T08:08', ngày 5 tháng 1 năm 2014 là Chủ nhật. Vì vậy, nó phải là'Off'
BeetDemGuise

lại: ngày 5 tháng 1 năm 2014. Hoàn toàn đúng. Mã hiện tại là chính xác, nhưng chạy đầu ra là sai. Sẽ sửa chữa.
Michael Phục sinh

Đã thử java.time.*. Thất bại thảm hại. Trình phân tích cú pháp quá nghiêm ngặt. Sử dụng DateParsertừ nashorn (cũng là một phần của JRE8) có tính khoan dung và với một chút hack lạm dụng, thậm chí đủ khoan dung để bỏ qua phút & giây.
Mark Jeronimus

2

R, 243 204 ký tự

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)))])

Thụt lề và bình luận:

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

Ví dụ:

> 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

Bash, 286

đây là một câu trả lời đơn giản bằng cách sử dụng chương trình ngày

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

Đây là một cái khác!

JavaScript, 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'))}

Chưa hoàn thành:

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'))
}

Chỉ hoạt động trên các trình thông dịch trong đó chuỗi ngày ISO8601 có thể được truyền vào hàm Datetạo.

Cà phê, 192 189

Đáng ngạc nhiên, nó tồn tại lâu hơn trong CoffeeScript vì không có toán tử tạm thời trong ngôn ngữ đó (mà bạn có thể thấy từ JavaScript của mình, tôi đã dựa rất nhiều vào).

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

Đây là ở dạng chức năng, sử dụng một vài hack khó chịu.

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)]

Giải thích:

// 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

Python 3 - 352 ký tự

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
Bạn nên thay đổi s=['high','mid','off']thành s=['on','mid','off']- điều này không chỉ tiết kiệm được 2 ký tự, mà thông số kỹ thuật còn cho biết đầu ra "bật".
Sellyme

0

Java - 426 309/301? (Xem ý kiến)

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";
}

Ví dụ đầu ra:

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

Tôi đã sử dụng thủ thuật EXOR tương tự như trình Python. Tôi cũng đã sử dụng một +hàm OR, khi nó hoạt động weekend OR night.

Thủ thuật lớn khác của tôi: mặt nạ bit.

Ví dụ: để xem một số có nằm trong khoảng từ 2 đến 6 (Thứ Hai đến Thứ Sáu), trước tiên hãy tạo một mẫu bit trong đó các giá trị thú vị là 1:

  6   2 
0b1111100 = 124

Sau đó, sử dụng dịch chuyển bit để lấy bit thú vị cho LSB và giải nén nó:

(124 >> day_of_week) & 1

Tương tự, tôi đã tạo các mẫu bit trong nhiều tháng và giờ:

  9    4
0b1111110000 = 1008

      76          76
0b111110000000000001111111 = 16253055
0b000000011111100000000000 = 129024

Thật không may, hóa ra đơn giản x>y&x<zlà ngắn hơn trong hầu hết các trường hợp, vì vậy tôi đã không sử dụng nó ở một số nơi.

Và cuối cùng, một chút tin tặc (phụ thuộc vào việc thực hiện cao) với jdk.nashorn.internal.parser.DateParser: Khi parseEcmaDate()không hoàn toàn phân tích một ngày (như khi nó đọc giờ và kết thúc chuỗi), nó sẽ trả về sai.

  • Khi nó kết thúc đúng cách, ngày được lưu trữ trong một Integer[](ftw tự động mở hộp), với tháng được cố định là cơ số 0 (giống như các lớp Java khác).
  • Khi nó trả về false, nó đã hủy bỏ một nửa và không thực hiện việc sửa lỗi này. Tuy nhiên, nó vẫn đặt bất cứ thứ gì nó phân tích vào mảng, có sẵn. Do đó -(c?0:1).

Tôi nghĩ rằng chỉ sử dụng cũng .parse()có thể hoạt động (loại bỏ 8 ký tự), nhưng tôi đã không kiểm tra kỹ lưỡng với các đầu vào khác nhau. parsecuộc gọi nội bộ parseEcmaDatevà nếu nó thất bại, cuộc gọi parseLegacyDate. Cái sau có thể làm hỏng mảng, nhưng điều này đã không xảy ra với một vài trường hợp tôi đã thử nghiệm.
Mark Jeronimus

-1

Không có gì ngăn cản tôi bước vào chính mình, và dù sao cũng có những cái ngắn hơn ở đây

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');}

Chưa hoàn thành và nhận xét:

<?
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
}

Cũng lưu ý rằng lệnh date.timezonetrong php.ini phải được đặt, nếu không, Ngoại lệ sẽ bị ném.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.