今晚或本周末重新插上电源


20

这是我第一次打高尔夫球,所以请告诉我它是否太宽泛或者我缺少任何有关一个好的拼图的信息!

挑战

在安大略省以及世界其他地区,都使用“使用时间”(TOU)定价来计费,该定价会根据您使用电力的时间而有所不同,每千瓦时的成本有所不同。

给定日期和时间,我想知道我处于高峰时段(红色),高峰时段(黄色)还是非高峰时段(绿色)。

输入值

假设以可接受的无时区的ISO 8601日期-时间格式提供输入,且最小精度为小时:(YYYY-MM-DDThh[:mm[:ss]]T为文字)。

例子

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

输出量

输出应该是一个字符串OnMidOff

规则

  • 最短代码胜出
  • 就此挑战而言,请忽略法定假日
  • 假设在此帖子中找到了信息。将来,安大略省能源部可能会更改使用时间定价的实际规则。

信息

夏季工作日(5月1日至10月31日)

夏季工作日的使用时间时钟

  • 非高峰时间:19h00-07h00
  • 高峰:07h00-11h00和17h00-19h00
  • 高峰:11h00-17h00

冬季工作日(11月1日至4月30日)

冬季工作日的使用时间时钟

  • 非高峰时间:19h00-07h00
  • 高峰:11h00-17h00
  • 高峰:07h00-11h00和17h00-19h00

周末

周末使用时间时钟

  • 非高峰:全天

您确定冬季的工作日没有调峰/调峰吗?
约翰·德沃夏克

3
@JanDvorak,冬天人们在早晨和晚上使用照明和暖气;在夏季,他们在中午使用空调。
彼得·泰勒

4
这是codegolf.stackexchange.com/q/7008/194的重复边界(解析日期时间,并根据是否是工作日进行简单计算)。我认为季节依赖性足够不同,但是其他人可能会不同意。
彼得·泰勒

@PeterTaylor这里的规则似乎比链接的问题简单得多。例如,这不必处理leap年。
约翰·德沃夏克

3
通用的日期格式应该是YYYY-MM-DDThh[:mm[:ss]]因为只有应用分钟才能应用秒吗?
Cruncher 2014年

Answers:



8

Python 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<174<m<11False,这将评估到1+False => 1+0 => 1。否则,该运算将评估为1+True => 1+1 => 2

  • 最后,将上述操作的结果乘以一天是否是工作日以及时间是否在6 am-7pm之间。

    如果是这样False,则一天是一个周末,或者时间是在晚上7点至早上6点之间,结果将是(1|2)*0 => 0。否则结果将是(1|2)*1 => 1|2

结果0将打印Off1将打印Mid,然后2将打印On


高尔夫版本不是因为使用分号而实际上更长了吗?还是算换行符?
Beta Decay

通常计算换行符。在记事本++(其中我通常让我计数)ungolfed版本是4字节长在168
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)
Cristian Lupascu 2014年

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

编辑:感谢w0lf的时间,它有助于缩短和解决错误。


您的程序不正确。对于输入,2014-09-01T17:30它正确输出"Mid",但是对于2014-09-01T17输出"Off"
Cristian Lupascu 2014年

3

Groovy中- 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 2014年

回复:Java8。重点
迈克尔·复活节

在倒数第二个示例中'2014-01-05T08:08',2014年1月5日是星期日。因此,应该是'Off'
BeetDemGuise 2014年

回复:2014年1月5日。非常正确。当前代码正确,但是输出运行错误。将修复。
2014年

试过了java.time.*。惨败 解析器太严格了。使用DateParser从犀牛(也是JRE8的一部分),这是宽松的,并且以位辱骂黑客攻击,甚至宽松足以跳过分和秒。
Mark Jeronimus 2014年

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)

这是一个使用日期程序的简单bash答案

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

再来一个!

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

未缩小:

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

Python 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个字符,而且规范要求输出“ on”。
Sellyme 2014年

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

我使用了与Python提交相同的EXOR技巧。我还使用a +作为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[](自动拆箱ftw)中,月份固定为以0为基(类似于其他Java类)。
  • 当它返回false时,它会中途中止并且没有进行此修复。但是,它仍然将解析后的内容放入数组中,该数组随时可用。因此-(c?0:1)

我认为使用just .parse()也许也可以(减少8个字符),但是我还没有用不同的输入对它进行彻底的测试。parse内部调用parseEcmaDate,如果失败,则调用parseLegacyDate。后者可能会破坏阵列,但是在我测试的一些情况下并没有发生。
Mark Jeronimus 2014年

-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.timezone必须设置php.ini 中的指令,否则将引发Exception。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.