Aww, stary, ta data ważności nie pisze miesięcy listami! Nie wiem, czy wygasa 10 marca, czy 3 października ... Poczekaj, nie, nieważne, rok mówi 2012. (aleja oops w połowie zużyta cegła sera do kosza może jak zawodowiec)
Załóżmy więc przez chwilę, że jesteś zbyt zajęty, aby spróbować zrozumieć, kiedy ten słoik marinara ma wygasnąć. Chcesz tylko wersję Cliff Notes: jak prawdopodobne jest, że jest przeterminowana? Napiszmy kod!
Wiesz, że producenci drukują datę jako zamówioną potrójną liczbę całkowitą, w jednym z trzech formatów:
YEAR MONTH DAY
MONTH DAY YEAR
DAY MONTH YEAR
I wiesz, że niektóre daty można interpretować tylko na jeden lub dwa sposoby, a nie wszystkie trzy: 55 w 55-11-5
musi być rokiem, co oznacza, że to konkretne pudełko Twinkies wygasło 5 listopada 1955 r. Rok ten jest czasem podawany w czterech cyfrach i nie dwa, co może wykluczyć niektóre opcje. Kiedy są to dwie cyfry, 50..99 oznacza 1950..1999, a 0..49 oznacza 2000..2049.
Twoim zadaniem jest napisanie programu lub funkcji, która pobiera tablicę liczb całkowitych, która jest prawidłową datą w co najmniej jednej z powyższych interpretacji i daje procent szansy, że nadal jest dobra. Procentowa szansa to po prostu procent prawidłowych interpretacji daty, która przypada w dniu dzisiejszym lub później .
Tablica liczb całkowitych będzie [Int]
typu trzech długości twojego języka, jeśli jest argumentem funkcji i podana jako liczba całkowita rozdzielona myślnikiem, ukośnikiem lub spacjami (możesz wybrać), jeśli jest używana jako dane wejściowe STDIN do pełny program. *
„Dzisiejsza data” może być dzisiejszą rzeczywistą datą uzyskaną za pomocą funkcji daty lub datą podaną w dodatkowym argumencie funkcji lub dodatkowym parametrze w STDIN. Może to być sekunda epoki uniksowej, kolejny potrójny dzień-miesiąc wprowadzony na jeden z trzech powyższych sposobów lub inna wygodniejsza moda.
Zobaczmy kilka przykładów! Wprowadzanie daty wygaśnięcia będzie odbywało się w stylu rozdzielanym myślnikiem i przyjmijmy w poniższych przykładach, że dzisiejsza data to 5 lipca 2006 r.
14-12-14
- Obie ważne interpretacje tego (DMY i YMD) są równoważne, 14 grudnia 2014 r. Wynik wynosi 100, ponieważ ten produkt jest zdecydowanie dobry.8-2-2006
- Ostatni numer to na pewno rok, ponieważ ma cztery cyfry. Może to być 8 lutego (wygasł) lub 2 sierpnia (nadal dobry). Wyjście wynosi 50 .6-7-5
- To może być cokolwiek! Interpretacja „5 lipca 2006 r.” Jest nadal dobra (tylko na jeden dzień), ale pozostałe dwie są w 2005 r. I powinny zostać odrzucone tak szybko, jak to możliwe. Wyjście to 33 .6-5-7
- Tutaj dwie z trzech interpretacji są bezpieczne. Możesz zaokrąglać ułamek dziesiętny w górę lub w dół, więc 66 lub 67 są w porządku.12-31-99
- Okej, ten jest jednoznaczny z przełomu wieków (lata od 50 do 99 to 19XX, a 31 nie może być miesiącem). Duży tłuszcz 0 i naprawdę powinieneś częściej czyścić lodówkę.
Możesz bezpiecznie założyć, że wszelkie dane wejściowe, które nie spełniają powyższych standardów, nie są objęte powyższymi regułami dotyczącymi wyników.
Brak żądań internetowych lub standardowych luk. Biblioteki obsługi dat są dozwolone. To jest kod golfowy: może wygrać najkrótszy program.
* Jeśli używasz głupoty lub jakiegoś języka z podobnym upośledzeniem typu danych, możesz założyć, że ASCII pierwszych trzech wprowadzonych znaków to liczby całkowite dla daty. To wyklucza czterocyfrową logikę roku, oczywiście, ale myślę, że bylibyśmy zbyt zdumieni widząc rozwiązanie tego problemu w Brainfuck, aby cię za to lekceważyć.
Odpowiedzi:
k4
(90)(88)(87)(82)Powołać się
x
od.z.D
(a) do wbudowanego polecenia porównaniu do dzisiaj, lub dacie dosłownym swojego wyboru w inny sposób:Jest to w zasadzie port rozwiązania Pythona @ Alex-l, do którego dodano kilka różnych sztuczek golfowych:
źródło
"012201210"
, ponieważ#
cyklicznie pobiera jego elementy. W rzeczywistości, można zapisać drugą Char ten sposób przez zamianę dwóch ostatnich przypadkach:3 3#.:'"0122102"
.{c*(+/~d<x)%3-+/^d:{"D"$"."/:$|z,y,x+(c*19+x<50)*x<c::100}.'y@/:3 3#.:'$21020101}
.Ruby, 115 znaków
Definiuje funkcję,
f
która przyjmuje dwa argumenty: tablicę zawierającą dane wejściowe i „dzisiejszą” datę.Przykłady:
źródło
Python 2.7 - 172
Używam modułu datetime do ważności i porównywania dat. Jeśli
date
nie można utworzyć prawidłowej daty i godziny na podstawie danych wejściowych, podnosiValueError
. W ten sposóbs
suma dat, które nie wygasły,t
jest całkowitą liczbą ważnych dat. Korzystam z faktu, żeTrue == 1
do celów dodawania i indeksowania w Pythonie. Zapisuję też postać, używając 25 * (76,80) zamiast (1900,2000).Zauważ, że linie na drugim poziomie wcięcia używają znaku tabulacji, a nie 2 spacji.
Dodaj to do końca, aby przetestować:
źródło
PowerShell,
183173168Wprowadź jak
int[]
za pomocą parametru, nptry
/catch
, o ile nie wiem, czy wyjście na stderr jest dozwolone, czy nie.+"-1"
daty, która jest interpretowana jako.AddDays(-1)
przesunięcie bieżącej daty o jeden dzień, dzięki czemu możemy porównać do wczoraj (zamiast tylko dzisiaj). To rozwiązuje problem, że otrzymujemy datę z godziną 0:00, ale musimy porównać ją z datą od dzisiaj.źródło
R 269
Spodziewałem się, że będzie to łatwe w R, ale jednocyfrowe lata były dość dużą krzywą. Wydaje mi się, że to może być znacznie lepsze niż obecnie.
lubridate
jest pakietem CRAN, być może będziesz musiał go zainstalowaćinstall.packages("lubridate")
.Zastosowanie:
f(c(d1,d2,d3))
gdziec(d1,d2,d3)
jest wektorem liczb całkowitych.np .
f(c(6,10,14))
zwraca0.3333333
.lubridate
Pakiet posiada szereg funkcji otoki dla parsowania dat w różnych zleceń. Używam ich, aby zobaczyć, które formaty generują prawidłowe daty, wyrzucam niepoprawne, a następnie sprawdzam, które jeszcze nie wystąpiły.źródło
Mathematica,
163153164 bajty( edycja: ustalono daty poza zakresem 1950–2049)
Definiuje funkcję, którą możesz wywołać
Obecnie odsetek ten nie jest zaokrąglany (oczekiwanie na wyjaśnienie PO).
Tutaj jest nieco przydługi wyjaśnienie, które powinny być zrozumiałe bez wiedzy Mathematica (uwaga, że
&
czyni wszystko, co z niej zostało anonimowa funkcja, której parametry są określane jako#
,#2
,#3
...):Definiuje funkcję, która zamienia 3 parametry
a,b,c
w 3 listy{{a,b,c},{c,b,a},{c,a,b}
. Zauważ, że##
to tylko sekwencja wszystkich parametrów.Stosowana do daty wygaśnięcia daje listę
{y,m,d}
dla każdej z trzech możliwych kombinacji.Jest to anonimowa funkcja, która pobiera trzy parametry
a,b,c
i zwraca listę trzech, z których pierwszy został przekonwertowany na rok zgodnie z podanymi regułami: liczby pomiędzy50
i99
(modulo100
) są zamieniane na rok XX wieku, liczby między0
i49
( modulo100
) zostały przekształcone w rok 21 wieku, wszystkie pozostałe pozostały. Oto##2
sekwencja parametrów zaczynająca się od drugiego, tjb,c
.Zastosowane do każdego z trzech poprzednich wyników, to tylko kanonizuje formaty roku. Nazwijmy to,
canonicalDates
aby skrócić następujące wyrażenie:To odfiltrowuje nieprawidłowe interpretacje.
DateList@d
zapewnia pełną{y,m,d,h,m,s}
reprezentację różnych formatów dat. Zinterpretuje listy w tej samej kolejności, ale haczyk polega na tym, że można przekazać takie rzeczy, jak{8,2,2006}
w takim przypadku, które zostaną obliczone8 years + 2 months + 2006 days
. Sprawdzamy więc, czy pierwsze trzy elementy zwracanej listy są identyczne z danymi wejściowymi (co może się zdarzyć tylko wtedy, gdy miesiąc i dzień w odpowiednich przedziałach).Aby skrócić następujące wiersze,
validDates
odtąd będę odwoływał się do wyniku tego wyrażenia :Kolejna anonimowa funkcja, która pobiera datę i zwraca różnicę w dniach do dzisiaj (uzyskana z
Date[]
).Odwzoruj to na prawidłowe interpretacje dat.
Kolejna anonimowa funkcja, która podając list (
#
), zwraca procent liczb dodatnich na tej liście. To.
nie jest mnożenie, ale tylko cyfra dziesiętna, aby w rezultacie uniknąć liczb wymiernych (dostaniesz takie rzeczy100/3
zamiast33.333
- nie wiem, czy to jest problem).Zastosowanie do listy różnic dat daje nam ułamek interpretacji, które jeszcze nie wygasły.
źródło
JavaScript (E6) 159
164 172Edytuj Podziękowania dla nderscore za podpowiedzi i za popchnięcie mnie do ponownego myślenia. Zreorganizowano D, unikając parametrów i odcinając niektóre znaki.
Edycja 2 Kolejna sztuczka nderscore, 2 funkcje połączone w 1. Następnie dwa nawiasy usunęły scalone wyrażenia rozdzielone przecinkami w jedno. Czytelność w pobliżu 0. Sidenote: Brak zaokrąglenia może uratować kolejne 2 znaki (| 0).
Testuj w konsoli FireFox
Wynik:
Nie golfił
NB Funkcja D próbuje utworzyć datę z podanym rokiem, miesiącem, dniem, ale zwraca wartość false, jeśli utworzona data nie jest zgodna z zamierzeniami (! = Dzień lub miesiąc)
źródło
C # w LINQPad -
446408272 bajtówTrzecia edycja: Podziękowania dla Le Canard fou za wskazanie, że data i godzina są prawidłowe, a nie data i godzina. Druga edycja : Dzięki VisualMelon za to sprytne rozwiązanie!
Edycja: Dzięki podiluska i edc65 za pomoc w skróceniu kodu! Zauważyłem również, że moje rozwiązanie nie było poprawne, jeśli dane wejściowe roku miały 4 bajty, dlatego załączyłem naprawę tego problemu. Wynik dla tego rozwiązania wynosi 408 bajtów.
Mimo że nie biję żadnej z poprzednich odpowiedzi, nadal chciałem udostępnić moje rozwiązanie C #. Każda pomoc / sugestie są mile widziane! ;)
Wersja sformatowana i nie golfowa:
Próbowałem stworzyć rozwiązanie, w którym część „DateTime.TryParse” nie jest powtarzana jak w tym rozwiązaniu, ale była o 21 bajtów dłuższa.
Rozwiązanie bez powtarzania „DateTime.TryParse”: 467 bajtów
Wersja bez golfa:
źródło
int s=0;int a=d[2];int b=d[1];int e=d[0];
->int s=0,a=d[2],b=d[1],e=d[0];
DateTime.TryParse
wywołań było moim pierwszym instynktem, zastąpiłem je lambda, które również przywróciło wartość q. Wykonał także kilka innych kroków ( pastebin ), aby uzyskać 328 znaków:void g(int[]d){var q=new List<DateTime>();var p=".";int a=d[2],b=d[1],e=d[0],y;DateTime c;y=(a<100)?(a>49)?1900+a:2000+a:a;Action<string>z=(x)=>{if(DateTime.TryParse(x,out c))q.Add(c);};z(e+p+b+p+y);z(b+p+e+p+y);y=(e<100)?(e>49)?1900+e:2000+e:e;z(a+p+b+p+y);(q.Where(i=>i>=DateTime.Now).Count()*100/(q.Any()?q.Count:1)).Dump();}
Action<string>
wcześniej nie widziałem , więc mogłem się czegoś od ciebie nauczyć;) udało mi się sprowadzić twoją odpowiedź do 318 znaków, zastępującq.Where(i=>i>=DateTime.Now).Count
jąq.Count(i=>i>=DateTime.Now
. Usunąłem też nawiasy,x
aby zapisać 2 kolejne postacie!Haskell,
171165 znakówNazwa funkcji to
%
. Uruchom z datą testu jako krotkę w porządku kanonicznym (y, m, d) z faktycznym rokiem, a pieczęć kartonowa jako krotka z trzech liczb:źródło
Erlang, 146
Funkcją testową byłoby:
Nie golfił
To rozwiązanie opiera się na listach. Pożycza sztuczkę modulo na rok z rozwiązania Haskell. Służy również
calendar:valid_date/1
do obsługi niemożliwych dat ze względu na liczbę dni w danym miesiącu (np. „29-2-2” może być tylko w formacie YMD). Ponadto Today jest wdate()
formacie Erlanga (krotka YMD).źródło
APL (85)
Wykorzystuje to niektóre z nowych funkcji Dyalog APL 14, ale nie ma bibliotek zewnętrznych. Dla odmiany działa na TryAPL .
Jest to funkcja, która przyjmuje tablicę 3-elementową jako
⍵
argument po prawej stronie ( ), a datę do sprawdzenia jako⍺
argument po lewej stronie ( ) jako liczbę całkowitąYYYYMMDD
formatu. Tj. Data2014-07-09
jest reprezentowana jako liczba20140709
.Test:
Wyjaśnienie:
Z←(⊂⌽⍵),(⊂2⌽⍵),⊂⍵
: zamień podaną datę na format YMD(⊂⌽⍵)
, obracając, obracając ją w lewo o 2(⊂2⌽⍵)
lub po prostu nic nie robiąc⊂⍵
. Przynajmniej jedna z nich jest teraz poprawną datą w formacie YMD, może więcej niż jedną, jeśli data jest niejednoznaczna.{∧/12 31≥1↓⍵}¨Z
: sprawdź, czy każda data jest ważna: rok (pierwszy element) jest pomijany, a następnie miesiąc nie może być dłuższy niż 12, a dzień nie może być wyższy niż 31.Z/⍨
: filtruj prawidłowe daty odZ
.{
...}¨
: dla każdej ważnej daty:⍵+(99≥⊃⍵)×3↑1900+100×50>⊃⍵
: jeśli rok nie jest wyższy niż 99, dodaj 1900, a następnie 100, jeśli rok jest niższy niż 50.(3/100)⊥
: dekoduj go tak, jakby to był zbiór liczb podstawowych 100. (Rok jest wyższy niż 100, ale to nie ma znaczenia, ponieważ jest to pierwszy element.) Daje to liczbę dla każdej prawidłowej daty w tym samym formacie, co lewy argument.⍺≤
: dla każdej daty sprawdź, czy nie jest ona mniejsza niż⍺
. To da wektor binarny, gdzie 1 oznacza,OK
a 0 oznaczaspoiled
.100×(+/÷⍴)
: podziel sumę wektora binarnego przez jego długość i pomnóż przez 100.źródło
{100×(+/÷⍴)⍺≤((3/100)⊥⊢+(99≥⊃)×3↑1900+100×50>⊃)¨Z/⍨{∧/12 31≥1↓⍵}¨Z←(⌽⍵)(2⌽⍵)⍵}
Java: 349 znaków (3 bez spacji)
Oto klasa zawierająca, której można użyć do jej przetestowania, w tym (nieco) odśledzoną wersję metody:
To moja pierwsza runda golfa kodowego i myślę, że zorientowałem się, dlaczego zazwyczaj nie widzę zbyt wielu golfistów Java.
źródło
int[]
argument jako argument, a nie trzyint
.C # 287 bajtów
Pierwszy raz grałem w golfa, szukając porad. W szczególności usuwanie bajtów z powodu przestrzeni nazw.
Nadużywanie faktu, że wymagana jest tylko funkcja, a nie rzeczywisty program. Ponadto funkcja zawsze powoduje nieprzechwycony wyjątek.
Nie golfił
źródło
Mathematica , 118
Używając kodu m.buettner jako punktu wyjścia, mam kilka ulepszeń:
źródło