Bu gece veya bu hafta sonu tekrar takın


20

Bu benim ilk kod golf bu yüzden çok geniş veya iyi bir bulmaca için herhangi bir bilgi eksik varsa lütfen bana bildirin!

Meydan okuma

Ontario ve muhtemelen dünyanın diğer bölgelerinde, elektrik, kullanım zamanına göre kilowatt saat başına maliyeti değiştiren Kullanım Süresi (TOU) fiyatlandırması kullanılarak faturalandırılır .

Bir tarih ve saat verildiğinde, zirve (kırmızı), orta tepe (sarı) veya yoğun olmayan (yeşil) zaman diliminde olup olmadığımı bilmek istiyorum.

Giriş

Girdinin , minimum saat hassasiyetiyle kabul edilebilir bir saat dilimi içermeyen ISO 8601 tarih-saat biçiminde sağlandığını varsayın : YYYY-MM-DDThh[:mm[:ss]](T değişmezdir).

Örnekler

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

Çıktı

Çıktı bir dizi olmalıdır On, Midya da Off.

kurallar

  • En kısa kod kazanır
  • Bu zorluğun amaçları doğrultusunda, yasal tatilleri yok sayın
  • Bu gönderide bulunan bilgileri varsayalım. Kullanım süresi fiyatlandırmasının gerçek kuralları gelecekte Ontario Enerji Bakanlığı tarafından değişebilir.

Bilgi

Yaz hafta içi (1 Mayıs - 31 Ekim)

Yaz hafta içi kullanım saati

  • Yoğun olmayan: 19: 00-07: 00
  • Orta tepe noktası: 07h00 - 11h00 ve 17h00 - 19h00
  • Tepe noktasında: 11h00 - 17h00

Kış hafta içi (1 Kasım - 30 Nisan)

Kış hafta içi kullanım saati

  • Yoğun olmayan: 19: 00-07: 00
  • Orta tepe noktası: 11h00 - 17h00
  • Tepe noktasında: 07h00 - 11h00 ve 17h00 - 19h00

Hafta sonları

Hafta sonları kullanım saati

  • Yoğun olmayan: Bütün gün

Hafta içi kış günlerinin orta tepe / tepe üstü değişmediğinden emin misiniz?
John Dvorak

3
@ JanDvorak, kışın insanlar sabahları ve akşamları ışık ve ısıtma kullanır; yaz mevsiminde hava-con kullanıyorlar.
Peter Taylor

4
Bu, codegolf.stackexchange.com/q/7008/194 kodunun sınırda bir kopyasıdır (bir tarih saatini ayrıştırın ve iş günü olup olmadığına bağlı olarak basit bir hesaplama yapın). Sezon bağımlılığının yeterince farklı olduğunu düşünüyorum, ama diğerleri aynı fikirde olmayabilir.
Peter Taylor

@PeterTaylor burada bağlantılı sorudan çok daha basit görünüyor. Örneğin bunun artık yılları işlemek zorunda değil.
John Dvorak

3
YYYY-MM-DDThh[:mm[:ss]]Saniye cinsinden genel tarih biçimi sadece dakikalar uygulanabiliyorsa uygulanmalı mıdır?
Cruncher

Yanıtlar:


3

Yakut - 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]}

Bu, bir dizeyi parametre olarak alan ve bir dize döndüren bir işlevi temsil eder.

İşte bazı test senaryolarını içeren çevrimiçi bir demo: http://ideone.com/wyIydw


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]

Gerekirse, son satırdaki mantığın açıklaması aşağıdadır:

Son satır 'OMOfinfd', koşullarının değerlendirilmesine bağlı olarak bir dilim yazdırır .

  • İlk olarak, işlemi değerlendirin 1+((10<t<17)==(4<m<11)).

    Koşullar arasındaki XNOR 10<t<17ve 4<m<11ise False, bu değerlendirilecektir 1+False => 1+0 => 1. Aksi takdirde, işlem değerlendirilir 1+True => 1+1 => 2.

  • Son olarak, yukarıdaki operasyonun sonucunu günün hafta içi olup olmadığı ve saat 6 ile akşam 7 arasında olup olmadığı ile çarpın.

    Bu durumda False, gün bir hafta sonu veya saat 19: 00-18: 00 arasındadır ve sonuç olacaktır (1|2)*0 => 0. Aksi takdirde sonuç olacaktır (1|2)*1 => 1|2.

Bir sonucu 0yazdırır Off, 1yazdırır Midve 2yazdırılacaktır On.


Noktalı virgül kullandığınız için golf edilmiş sürüm daha uzun değil mi? Yoksa yeni satırlar sayılıyor mu?
Beta Çürümesi

Yeni satırlar genellikle sayılır. Notepad ++ (genellikle sayılarımı alırım) ungolfed sürümü 168'de 4 bayt daha uzun.
BeetDemGuise

3
@BeetDemGuise Düzenle → EOL Dönüştürme → UNIX / OSX Biçimi.
Schism

5

C # - 240 220 karakter

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

Özel birşey yok. Düz ileri kodlama.

W0lf teşekkürler :)


1
Sana kısaltmak düşünüyorum s.Length==13?s+":00:00":s.Length==16?s+":00":siçin(s+":00:00").Substring(0,19)
Cristian Lupascu

5

Yakut - 135

Zaman modülünü kötüye kullanır. Komut satırı bağımsız değişkenine göre giriş.

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

Düzenleme: Zaman kısaltmak ve bir hatayı çözmek için yardımcı w0lf teşekkürler.


Programınız yanlış. Giriş 2014-09-01T17:30için doğru çıktı verir "Mid", ancak 2014-09-01T17çıktı için "Off".
Cristian Lupascu

3

Groovy - 621 534 524 491 karakter

Biraz daha golf yapmak, ancak Joda-Time'ı kullanırken oldukça basit

@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

örnek çalışı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

Ungolfed:

@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'den beri, java.time.*Joda Time'a çok benzeyen ancak JRE'nin bir parçası olan da var. Belki de bu kodu biraz kısaltabilir.
ntoskrnl

re: Java 8. mükemmel nokta
Michael Easter

Sondan üçüncü örneğinizde '2014-01-05T08:08', 5 Ocak 2014 bir Pazar. Böylece, olmalı'Off'
BeetDemGuise

re: 5 Ocak 2014. Oldukça doğru. Geçerli kod doğru, ancak çıkış çalışması yanlış. Düzeltecek.
Michael Easter

Denedim java.time.*. perişan başarısız oldu. Ayrıştırıcı çok katı. Kullanım DateParserhoşgörülü ve kötü niyetli hack biraz, dakika ve saniye atlamak için bile hoşgörülü, yeterli uzunlukta ile Nashorn (JRE8 bir parçası) dan.
Mark Jeronimus

2

R, 243 204 karakter

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

Girintili ve yorumlu:

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

Örnekler:

> 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

Baş, 286

bu tarih programını kullanarak basit bir bash cevabı

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

İşte bir tane daha!

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

Unminified:

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

Yalnızca bir ISO8601 tarih dizesinin kurucuya geçirilebileceği tercümanlar üzerinde çalışır Date.

CoffeeScript, 192 189

Şaşırtıcı bir şekilde, CoffeeScript'te daha uzun çünkü bu dilde üçlü bir operatör yok (JavaScript'imden de görebileceğiniz gibi, büyük ölçüde güvendim).

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

Bu fonksiyon formunda, birkaç kötü kesmek kullanır.

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

Açıklaması:

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

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
Sen değişmelidir s=['high','mid','off']için s=['on','mid','off']sadece 2 karakter kurtarmak yapar, ancak Spec "açık" çıkışına diyor -.
Sellyme

0

Java - 426309/301 ? (Yorumlara bakınız)

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

Örnek çıktı:

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 gönderimi ile aynı EXOR hilesini kullandım. Ayrıca +bir OR işlevi olarak da kullandım weekend OR night.

Diğer büyük numaram: bit maskeleri.

Örneğin, bir sayının 2 ile 6 arasında (Pazartesi - Cuma) olup olmadığını görmek için, önce ilginç değerlerin 1 olduğu bir bit deseni oluşturun:

  6   2 
0b1111100 = 124

Ardından, ilginç biti LSB'ye almak ve çıkartmak için bit kaydırmayı kullanın:

(124 >> day_of_week) & 1

Benzer şekilde, aylar ve saatler boyunca bit desenleri yaptım:

  9    4
0b1111110000 = 1008

      76          76
0b111110000000000001111111 = 16253055
0b000000011111100000000000 = 129024

Ne yazık ki, x>y&x<zçoğu durumda sadece daha kısa çıkıyor , bu yüzden bazı yerlerde kullanmadım.

Ve son olarak, biraz hackery (son derece uygulamaya bağlı) jdk.nashorn.internal.parser.DateParser: Bir parseEcmaDate()tarihi tamamen ayrıştırmazsa (saati okuduğunda ve dizenin sonuna geldiğinde olduğu gibi), false değerini döndürür.

  • Düzgün bir şekilde bittiğinde, tarih, Integer[]ay (0) olarak (diğer Java sınıfları gibi) sabit olacak şekilde (otomatik kutudan çıkarma ftw) içinde depolanır .
  • False değerini döndürdüğünde yarıda kesildi ve bu düzeltmeyi yapmadı. Ancak yine de diziye ayrıştırılmış olan her şeyi koyuyor, ki bu da hazır. Dolayısıyla -(c?0:1).

Bence kullanmak .parse()da işe yarayabilir (8 karakter tıraş), ancak farklı girişlerle iyice test etmedim. parsedahili olarak arar parseEcmaDateve başarısız olursa arar parseLegacyDate. İkincisi diziyi bozabilir, ancak bu test ettiğim birkaç durumla olmadı.
Mark Jeronimus

-1

Hiçbir şey kendime girmemi engellemiyor ve yine de burada daha kısa olanlar var, bu yüzden…

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

İncelenmemiş ve yorum yapılmamış:

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

Ayrıca date.timezonephp.ini içindeki yönerge ayarlanmalıdır, aksi takdirde bir istisna atılır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.