Właśnie wpadłem na genialny pomysł na ułatwienie życia zawodowego - odliczanie do określonej daty, która liczy tylko dni robocze.
Podstawowym zadaniem jest utworzenie odliczania do określonej daty, która obejmuje tylko dni robocze w odliczaniu.
Ponieważ liczy się dzień roboczy poniedziałek , wtorek , środa , czwartek i piątek .
Dane wejściowe powinny być konkretną datą w „nieoficjalnym” europejskim formacie standardowym dd.MM.yyyy
i muszą być dzisiaj lub dzień w przyszłości.
Wyjście powinno być tylko liczbą dni pozostałych.
Ponieważ jest to gra w golfa, wygrywa najkrótszy kod.
Przypadek testowy:
Today | Input | Output
10.12.2018 | 17.12.2018 | 5
02.10.2018 | 16.10.2018 | 10
Jeśli pominąłem kilka rzeczy w pytaniu, proszę wybacz mi - to moje pierwsze pytanie :)
EDYTOWAĆ:
- Możesz użyć
false
jako wynik zamiast0
<- ale to nie jest piękne - Nie ma potrzeby przestrzegania DST
Odpowiedzi:
05AB1E ,
130128133131124123 bajtówOszalałem..
Dla języka golfowego 05AB1E nie ma znaczenia, czy dane wejściowe są przy pomocy
.
czy-
. Jednak 05AB1E nie ma żadnych wbudowanych obiektów Date ani obliczeń. Jedynym wbudowanym pod względem dat jest dzisiejszy rok / miesiąc / dzień / godziny / minuty / sekundy / mikrosekundy.Z tego powodu prawie cały kod, który widzisz, to ręczne obliczenia umożliwiające przejście do następnego dnia i obliczanie dnia tygodnia.
+5 bajtów z powodu części, o której zapomniałem we wzorze Zellera (rok-1 dla miesięcy styczeń i luty) ..
Wypróbuj online lub Wypróbuj online z emulowaną, podaną przez siebie datą „dzisiaj” .
Wyjaśnienie:
Ściana tekstu przychodzącego.
Zasadniczo kod jest zgodny z następującym pseudokodem:
1)
Date currentDate = today;
to ta część programu 05AB1E:2)
Integer counter = 0;
i 3)Start an infinite loop:
są proste w programie 05AB1E:4)
If(currentDate is NOT a Saturday and currentDate is NOT a Sunday):
to pierwsza trudna część z ręcznymi obliczeniami. Ponieważ 05AB1E nie ma wbudowanej daty, będziemy musieli ręcznie obliczyć dzień tygodnia .Ogólny wzór na to:
Gdzie w miesiącach od marca do grudnia:
[1, 31]
)[3, 12]
)A dla miesięcy styczeń i luty:
[1, 31]
)[13, 14]
)Wynik w dniu tygodniah , gdzie 0 = sobota, 1 = niedziela, ..., 6 = piątek.
Źródło: Zerger Zellera
Widzimy to w tej części programu 05AB1E:
5)
Counter += 1;
jest znowu prosty:6)
currentDate += 1; // Set currentDate to the next day in line
jest znowu bardziej skomplikowany, ponieważ musimy to zrobić ręcznie. Zostanie to rozwinięte do następującego pseudokodu:Źródła:
Algorytm określania, czy rok jest rokiem przestępnym.(EDYCJA: Nie ma już znaczenia, ponieważ używam alternatywnej metody do sprawdzania lat przestępnych, która pozwoliła zaoszczędzić 7 bajtów.)Algorytm do określania liczby dni w miesiącu.
6a)
Integer isLeapYear = ...;
odbywa się w następujący sposób w programie 05AB1E:Użyto również w mojej odpowiedzi 05AB1E , więc dodano kilka lat ilustrujących poszczególne kroki.
6b)
currentDate.month == 2 ?
i 6c)28 + isLeapYear
wykonuje się w następujący sposób:6d)
:
i 6e)31 - (currentDate.month - 1) % 7 % 2;
wykonuje się w następujący sposób:6f)
If(currentDate.day < daysInCurrentMonth):
odbywa się w następujący sposób:6g)
nextDate.day += 1;
wykonuje się w następujący sposób:6h)
Else:
i 6i)nextDate.day = 1;
wykonuje się w następujący sposób:6j)
If(currentDate.month < 12):
:6k)
nextDate.month += 1;
:6l)
Else:
, 6m)nextDate.month = 1;
i 6n)nextDate.year += 1;
wykonuje się w następujący sposób:I wreszcie o 8)
If(currentDate == parsed input-string):
i 9)Stop the infinite loop, and output the counter
:źródło
Excel 24 bajtów
Zakłada dane wejściowe w komórce A1
Używa wbudowanej funkcji. Niestety funkcja obejmuje zarówno datę dzisiejszą, jak i datę końcową. Od tego czasu OP wyjaśniło, że nie należy dziś liczyć, więc dodam jeden do TERAZ, aby dzisiaj nie liczyć.
Aby odpowiedzieć na komentarze dotyczące formatu liczby, ponownie jest to standard Excel:
źródło
10.12.2018
jest ciągiem, gdy jest przechowywany w komórce, a nie w dacie. Oczywistym rozwiązaniem, ale długo, aby skorygować ten będzie zmieniaćA1
sięDATE(RIGHT(A1,4),MID(A1,4,2),LEFT(A1,2))
w roztworzeHKCU\Control Panel\International\sDecimal
rejestru. W przypadku domyślnej instalacji systemu Windows w USA, czyli MM / dd / rrrr. W większości krajów UE byłoby to ustawienie domyślne.R , 76 bajtów
Przyjrzyj się również tej 72-bajtowej odpowiedzi R, która jest również niezależna od ustawień regionalnych.
Wypróbuj online!
weekdays
podaje tekstowe dni tygodnia, dlatego zliczamy dni w sekwencji między dzisiaj a danymi wejściowymi, które nie zawierająS
, i dodajemy jeden do wyniku.źródło
Java 10,
233232226 bajtówData zawsze przypomina mi, jak naprawdę pełna jest Java.
UWAGA: Istnieją teraz dwie krótsze odpowiedzi Java (poniżej 175 bajtów), jedna z inteligentnym użyciem przestarzałych metod z wcześniejszych wersji Java autorstwa @LukeStevens , a druga
java.time.LocalDate
z nowymi od Java 8 przez @ OlivierGrégoire .Wypróbuj online.
Wyjaśnienie:
źródło
e=s.clone()
?Calendar s=Calendar.getInstance(),e=s.getInstance()
, co niestety kończy się dokładnie taką samą długością.C
rzeczywiście nie jest konieczne. To było ze starej części kodu, w której również użyłemC
gdzie indziej. Dzięki temu mogłem zagrać w golfa 1 bajtvar s=Calendar.getInstance();var e=s.getInstance();
. :)java.time
.JavaScript (ES6),
116103 bajtówWypróbuj online!
W jaki sposób?
.toJSON()
YYYY-MM-DD
YYYY-MM-DD
DD.MM.YYYY
D.getDay()
źródło
MATL , 24 bajty
Wypróbuj online!
W połowie się udało :-)
Wyjaśnienie
źródło
16.10.2018
czy dzisiaj (poniedziałek01-10-2018
) spowoduje11
, jutro10
itd.Wolfram Language (Mathematica) ,
6456 bajtówWypróbuj online!
DayCount[x,y,"Weekday"]
zlicza liczbę dni tygodnia międzyx
iy
.Wejściami
x
iy
może być wiele rzeczy, w tym fantazyjne,DateObject
takie jak zwracane przezToday
, lub ciąg znaków w formacie (niestety)mm.dd.yyyy
.Moja poprzednia próba przekształciła dane
dd.mm.yyyy
wejściowe wDateObject
powiedzenie Mathematica, jak je parsować; nowe rozwiązanie po prostu zmienia ciąg, aby ustawić dzień i miesiąc w kolejności zgodnej z oczekiwaniami Mathematica.Warto zauważyć, że 28-bajtowe rozwiązanie
DayCount[Today,#,"Weekday"]&
nie tylko doskonale sprawdza się w przypadku formatu wejściowego miesiąc-dzień-rok, ale także poprawnie obsługuje jednoznaczne dane wejściowe dzień-miesiąc-rok, takie jak31.12.2018
, co nie mogło oznaczać „12 dnia 31-go” miesiąc". Więc to prawda przez ponad 60% czasu :)źródło
Perl 6 , 61 bajtów
Wypróbuj online!
źródło
R, 72 znaki
Odmiana odpowiedzi udzielonej przez @ngm, która pozwala greplowi zaoszczędzić kilka znaków i działa w lokalizacjach innych niż angielski.
sum(strftime(seq(Sys.Date(),as.Date(scan(,""),"%d.%m.%Y"),1),'%u')<6)+1
źródło
Java (OpenJDK 8) ,
174166165 bajtówZ odrobiną inspiracji z odpowiedzi Kevina i dobrym włokiem przez przestarzałe Date API, udało mi się uzyskać bardziej zwięzłe rozwiązanie Java.
-8 bajtów dzięki pomysłowej analizie wyrażeń regularnych Kevina
-1 bajty dzięki sprytnej bitowej operacji Nevay
Wypróbuj online!
Wyjaśnienie
źródło
d=d[0].split
przestarzałym.parse
domyślnym formatemMM/dd/yyyy
formatu. Jeden mały błąd w swoim poście, który maszimport java.text.*;
zamiastimport java.util.*;
w kodzie i// Required import for both Calendar and Date
w wyjaśnieniu (nawet jeśli nie używaszCalendar
).java.text
naprawiłem! Dzięki!d=d[0].split
z varargs, zmiana danych wejściowych na zwykły ciąg znaków, usunięcied=d[0].split("\\.");
i zmianad[1]+"/"+d[0]+"/"+d[2]
nad.replaceAll("(..).(..).","$2/$1/")
zapisywanie 7 bajtów .r+=new Date(s).getDay()%6<1?0:1,s+=864e5);
nas+=864e5)r+=new Date(s).getDay()%6<1?0:1;
. :)r-=-new Date(s).getDay()%6>>-1;
Czerwony , 72 bajty
Wypróbuj online!
Przyjmuje datę w formacie dd-mm-rrrr, na przykład 31-10-2018 (działa również z 10-paź-2018)
Ścisłe wejście:
Czerwony , 97 bajtów
Wypróbuj online!
Premia:
Zwraca listę dat / dni roboczych dni roboczych do podanej daty:
Czerwony , 235 bajtów
Wypróbuj online!
źródło
JavaScript,
8785 bajtówZwraca
false
za0
.Wypróbuj online lub sprawdź następne 31 dni
źródło
Python 2 ,
163156149147 bajtówWypróbuj online!
-7 dzięki dzięki @mypetlion
-7 więcej dzięki dzięki @ovs
+30 ze względu na bardzo restrykcyjny format wejściowy, który zauważyłem dopiero przed opublikowaniem mojego poprzedniego kodu, który pobierał dane jako np .
(2018,11,1)
:-(źródło
(0,1)[t.weekday()<5]
. Booleany Pythona są podklasąint
iTrue, False
mogą być używane w operacjach arytmetycznych jako1,0
. Zamień go na,c+=t.weekday()<5
aby zaoszczędzić 7 bajtów.Java (JDK 10) , 171 bajtów
Wypróbuj online!
Kredyty
źródło
(.*)\\.(.*)\\.(.*)
TO(..).(..).(.*)
.replaceAll
technice jego odpowiedź może być golfa o 7 bajtów, więc twoja jest jeszcze nieco dłuższa. ;)JavaScript (Node.js) ,
168160139133 bajtów35 bajtów mniej dzięki Quintec i Kevin Cruijssen
Wypróbuj online!
źródło
f=
liczby do liczby bajtów (a w TIO możesz umieścić ją w nagłówku), dlatego @Quintec stwierdził, że ma 139 bajtów zamiast 141 bajtów. Ponadto, można zmienićif((d.getDay()+1)%7>1)n++;
don+=-~d.getDay()%7>1;
golfa ją do 133 bajtów .-~i
jest to samo, co(i+1)
również. Jeśli jeszcze go nie widziałeś, wskazówki dotyczące gry w JavaScript w JavaScript i wskazówki dotyczące gry w <wszystkie języki> mogą być interesujące do przeczytania. :)Python3 i Numpy , 96 bajtów
Nie mogłem być mniejszy niż nudne gotowe rozwiązanie ...
Wypróbuj online!
źródło
PowerShell ,
10799 bajtów-8 bajtów dzięki mazzy
Wypróbuj online!
Wykonuje regex
-split
na wejściu$args
, przechowuje wartości do$d
Ays,$m
onths i$y
uszu, odpowiednio. Następnie wchodzi wfor
pętlę, inicjuje się$a
do dzisiejszej daty. Pętla trwa, dopóki$a
nie-l
upłyniet
nasza docelowa data wejścia. Każda iteracja dodajemy1
days
się$a
i sprawdzenie czy prąduD*k
(skrótDayOfWeek
) mieści się w zakresie1..5
(czyli od poniedziałku do piątku). Ten wynik boolowski jest kumulowany$o
i kiedy jesteśmy poza pętlą, ta wartość pozostaje w potoku, a dane wyjściowe są niejawne.źródło
$d,$m,$y=$args-split'\.';for($a=date;$a-lt(date "$y-$m-$d");$a=$a|% *ys 1){$o+=($a|% D*k)-in1..5};$o
for(...){...}
i$o
można go usunąć, więc jesteśmy teraz poniżej 100!Python 2 ,
147143141140 bajtówWypróbuj online!
Pobiera ciąg e, który reprezentuje datę zakończenia w formacie „dd.MM.RRRR”. Opcjonalnie przyjmuje również datę początkową, ale oczekuje się, że będzie to data / godzina.
Data rozpoczęcia s jest domyślnie ustawiona na dzisiejszą datę jako obiekt datetime.date, aby nie uwzględniać czasu. Czas zakończenia jest analizowany w obiekcie datetime.datetime, a następnie konwertowany na datę, ponieważ obiekty datetime.date nie mają metody parsowania, a okresów danych nie można dodawać do / odejmować od dat. Iteruje przez każdy dzień w (początek, koniec] i dodaje 1 do sumy, jeśli jego liczba dni w tygodniu wynosi <5. ([0–4] to [pn – pt], [5–6] to [sob. – Niedz.]).
Przetwarzanie Datetime jest najgorsze.
EDYCJA: Mapa Stole ElPedro (int, rzecz) sztuczka, aby zapisać 4 bajty.
EDYCJA 2: ELEKTRYCZNY BOOGALOO: Zapisano 2 bajty, czyniąc z niego funkcję anonimową. (Dzięki Aaron!)
EDYCJA 3: xzakres -> zasięg. (Jeszcze raz dziękuję, Aaron!)
źródło
f=
from lambda expressions hererange
rather thanxrange
it should still work just fine.PHP, 66 bytes
empty output for
0
; insert+
betweenecho
and$r
to fix.Run as pipe with
-nr
or try it online.60 bytes with unary output:
źródło
PHP (with Carbon), 107 bytes
źródło
IBM/Lotus Notes Formula - 99 bytes
Takes input from a date/time field
i
. The input format ofi
is set to.
separated so there is no need to convert the input. Notes can take a date input with any separator as long as you tell it before what it is going to be (hope that's not cheating!). Formula is in computed numeric fieldo
on the same form.Interesting aside: Ever since
@For
and@While
were introduced into the Formula language in (I think) R6 by the great Damien Katz the only use I have found for them is code golfing. I have never used them in a production app.There is no TIO available for formula so here is a screenshot taken on 02.10.2018:
źródło
Ruby, 81 bytes
Try it online!
źródło
K4, 40 bytes
Solution:
Explanation:
Calculate the difference between the dates, use modulo 7 to ignore weekends, sum up.
Notes:
"D"$,/|"."\:x
źródło
C (clang),
209208205 bytesCompiler flags
-DU=u=localtime(&b)
-DW=tm_wday
-DY=tm_year
-DT=tm_yday
(52 bytes).Try it online!
-1 byte thanks to @JonathanFrech
źródło
?i++:0
->&&++i
.q,
5279 bytesin q, each date has an underlying integer value, based on how many days have passed since the start of the millenium. Applying 'mod 7' to this, you get unique values for each day of the week (0 for Saturday, 6 for Friday). So when 2 > x mod 7, don't increment the counter, to avoid counting weekends.
EDIT: Missed strict date format, editing
EDIT2: Included
źródło
{sum 1<mod[d+til("D"$x 10 vs 67893401)-d:.z.d]7}
for 48 bytes without resorting to K verbs.