Twoim wyzwaniem jest napisanie programu, który, biorąc pod uwagę rok, generuje w nim liczbę „piątek trzynastych”.
Zasady i szczegóły:
- Możesz przyjmować dane wejściowe za pośrednictwem
STDIN
lub jako argument przekazywany do programu. - Powinieneś wypisać wynik na
STDOUT
. - Możesz założyć, że dane wejściowe będą ważne i nie będą poprzedzać kalendarza gregoriańskiego (w takich przypadkach dozwolone jest niezdefiniowane zachowanie).
- Biblioteki kalendarza / daty są dozwolone.
To jest golfowy kod , więc wygrywa najkrótszy kod (w bajtach).
Odpowiedzi:
APL (Dyalog APL) z cal z dfns , 29 bajtów
Wypróbuj online!
⍳ 12
liczby całkowite od jednego do dwunastu⎕ ,¨
wprowadź dane numeryczne i wstaw do każdej z dwunastu liczb{
…}¨
Na każdej z par zastosuj funkcję…cal⍵
dostać kalendarz na ten rok-miesiąc2 ↓
upuść dwa wiersze (podpis i dni)⍉
transponuj (abyśmy mogli adresować kolumny zamiast wierszy)¯5 ↑
weź ostatnie pięć (dwie cyfry dla każdego piątku i soboty plus jedna spacja)3 ↑
weź dwie pierwsze (dwie cyfry w piątek plus spację)⍉
transponuj (więc otrzymujemy kolejność czytania),
strzępy⍎
wykonać jako wyrażenie APL (podaje listę dat piątków)13 ∊
czy trzynaście jest członkiem tej listy?+/
zsumuj 12 booleanówKorzystając z algorytmu @ Wrzlprmft , możemy to zrobić bez bibliotek dla 53 bajtów:
-∘0 1
odejmij zero i jeden400 100 4 ∘.|
tabela reszty podziału dla dwóch lat (w poprzek) podzielona przez te liczby (w dół)0 ≠.=
wewnętrzny „produkt” z 0, ale używając ≠ i = zamiast +. ×⊢ ,
wstaw niezmodyfikowany rok argumentu2 3 ¯1 +.×
produkt wewnętrzny z tymi numerami14 |
pozostała część podziału po podzieleniu przez czternaście'21232211321211' ⌷⍨
indeks do tego ciąguźródło
Mathematica
49 46 45 4442Jako czysta funkcja : 42 znaki
Przykład
Jako nazwana funkcja : 44 znaki
Przykłady
źródło
f=DayName@{#,m,6}~Table~{m,12}~Count~Friday&
Ruby,
49 48 4746Edycja: Ogoliłem postać, cofając się o tydzień, dzięki Janowi, a drugą, przechodząc z Time.new do Time.gm
Edycja: Kosztem trochę zaciemnienia, mogę dostać się do 46 za pomocą
źródło
Time.gm(m,i).wday<1
. Nie wiem też, dlaczego nazywasz tę funkcję.PowerShell,
6863585250Dzięki Iszi za wskazówkę.
Biorąc pod uwagę fakt, że jeśli pierwszym dniem miesiąca jest niedziela, 13 będzie piątek.
Próbowałem też:
ale to nie to samo
$args
w bloku skryptu.źródło
$n
się$args
w pętli, a można to zrobić bez$n=read-host;
końca. Zapisuje 8. Usuń @, jak wspomniano powyżej, i jesteś w dół do 54.$args
na$input
, więc karmienie rok z rurociągu, a skrypt będzie działał, ale zawsze wyprowadza 3.R
767257źródło
"%a %d")=="Fri 13"
ze"%w%d)=="513")
używając dow jako liczba i usunięcie spacji.seq
jedynych w miesiącu jest tutaj naprawdę krótsze!sum(format(as.Date(paste(scan(),1:12,13,sep="-")),"%w%d")=="513")
ma tylko 65 znaków!<
to zmusiłoby znak do liczby całkowitej. Niezła sztuczka!Python 2,7
9086Poniedziałek 9 może nie mieć tego samego pierścienia, ale działa równie dobrze.
Edycja: półtora roku, aby zauważyć, że
date
jest krótszy niżdatetime
:)źródło
from datetime import*
f=lambda y:sum([date(y,m,13).weekday()==4 for m in range(1,13)])
.... Rozwiązanie tego samego rozmiaru z importem (86 bajtów).Nieużywanie żadnych bibliotek ani wbudowanych funkcji daty:
Golfscript - 51
Python -
8279Zasadniczo ten sam algorytm.
Za pomocą tej sztuczki można ją pograć w golfa w celu:
źródło
do
301+287Nie jest to najkrótsza odpowiedź, ale nie korzysta z bibliotek.
źródło
static char GetNumberOfFriday13s(int year) { const string perpetualCalendar = "1221212213113213122221122131122121221311321312222112213112212122131132131222211221311221212213113213112213113213122221122131122121221311321312222112213112212122131132131222211221311221212213113213122213113213122221122131122121221311321312222112213112212122131132131222211221311221212213113213122221122213122221122131122121221311321312222112213112212122131132131222211221311221212213113213122221122131"; return perpetualCalendar[year % 400];
. Nie będzie działać przez lata negatywne.v[0]
powinien byćv[1]
. Możesz też trochę zagrać w golfa; rozważ użyciestrcat
, przechowywanie znaków do bezpośredniego drukowaniaa[]
i odjęcie stałych numerycznych zamiast stałych znakowych. :)main(int x,char**v){char p[400],*a[]={"1221212213113213","2131222","21122131","1222","112213113","122223113","122221122"},*b="adcadcadcaebcadcadcafbcadcadcagbcadcadcadc";*p=0;for(;*b;b++)strcat(p,a[*b-97]);putchar(p[atoi(v[1])%400]);}
(215 znaków)C (
151145137131130 130 znaków)Jestem zaskoczony, widząc, że istnieje tylko jedno inne rozwiązanie, które nie korzysta z wbudowanych narzędzi kalendarza. Oto (matowe) podejście matematyczne, również w C:
(Powyższe kompiluje się w GCC bez błędów)
Alternatywne rozwiązanie: C (287-> 215 znaków)
Raczej podobało mi się rozwiązanie Williama Totlanda i jego użycie kompresji. Naprawiłem dwa małe błędy i poprawiłem kod, aby skrócić jego długość:
źródło
PHP, 82
<?for($i=1,$c=0;$i<13;$i++)$c+=(date("N",mktime(0,0,0,$i,1,$argv[1]))==7);echo $c;
Oparte na
„Każdy miesiąc, który zaczyna się w niedzielę, zawiera piątek trzynasty, a co najmniej jeden piątek trzynastego w każdym roku kalendarzowym”.
From http://en.wikipedia.org/wiki/Friday_the_13th
źródło
bash
4736Dzięki @DigitalTrauma za zapisanie 10 znaków przy użyciu
seq
domyślnego startu do1
.(Poprzednia wersja używała
echo
błędu z powodu pustej linii kiedy<(echo $1-{1..12}-6$'\n')
. Więc ta funkcja działała dobrze do dzisiaj jest piątek.Zobaczmy:
To zależy od ustawień regionalnych , jeśli nie działa, być może trzeba
lub
W funkcję; +7 -> 43
Premia: +78 -> 121
Stamtąd, jeśli moja funkcja stanie się:
lub
źródło
C
. Ale jest błąd ...%s\\n
seq
aby zrzucić 8 znaków:date -f<(seq -f$1-%g-6 1 12)|grep -c ^F
seq -f$1-%g-6 12|date -f-|grep -c ^F
JavaScript, 70
źródło
,b,c
z deklaracji funkcji (! Jest OK do wycieku vars do golfa), jak równieżb
zostanie wyrzucony jakNumber
możesz+=
wynikiem testu zamiast&&b++
:b+=/^F/.test(new Date(a,c,6))
. Możesz jednak zapisać kolejny bajt, używając!new Date(a,c,1).getDay()
(to działa, ponieważgetDay
zwraca 0 dla niedzieli, a jeśli 13 to piątek, 1 to niedziela) zamiast tego,test
który w sumie powinien zaoszczędzić 7 bajtów!k
64 znaków
Czyta ze standardowego
źródło
Common Lisp (CLISP), 149
źródło
DO#
1101019392C # Linq 88
Podziękowania dla Jeppe Stiga Nielsena za linq i sugestię sprawdzenia w niedzielę 8.
Dzięki Danko Durbić za sugestie
>
zamiast==
.źródło
c+=(int)new DateTime(y,i,13).DayOfWeek==5?1:0;
użyj odpowiednikac+=new DateTime(y,i,8).DayOfWeek==0?1:0;
. Sztuką jest odjąć5
, ponieważ wtedy możesz pozbyć się rzutowaniaint
, a także liczba8
ma jedną cyfrę mniej niż liczba13
. Niedziela ósma!int g(int y){return Enumerable.Range(1,12).Count(m=>new DateTime(y,m,8).DayOfWeek==0);}
. Oczywiście jako lambday=>Enumerable.Range(1,12).Count(m=>new DateTime(y,m,8).DayOfWeek==0)
..DayOfWeek<1
.c#
odpowiedzi, ale nie wiadomo, jak ją zastosowaćlinq
.DayOfWeek
z żadną inną liczbą całkowitą niż0
-error CS0019: Operator '<' cannot be applied to operands of type 'System.DayOfWeek' and 'int'
.PHP, 55 bajtów
Uruchom z
echo <year> | php -nR '<code>'
.Zasadniczo to samo, co Oleg próbował i Damir Kasipovic , tylko z lepszym golfem:
każdy miesiąc, który zaczyna się w niedzielę, ma piątek 13.
Więc przeglądam miesiące i liczę pierwsze dni w niedziele.
awaria
źródło
K, 42
.
źródło
Bash (
5247 znaków)źródło
Rebol, 63
Przykład użycia w konsoli Rebol:
Alternatywnym rozwiązaniem, które zbiera cały piątek 13 w danym roku, jest:
źródło
Bash and Sed, 39
ncal
drukuje kalendarz na dany rok z dniami tygodnia w dół po lewej stronie.sed
z/g
flagą wypada wszystkie 13 z nowymi liniamigrep -c
liczy linie zaczynające się od „2” (20 zawsze następuje po 13)Dzięki @DigitalTrauma za znalezienie błędu w mojej starej wersji i zaproponowanie rozwiązania!
źródło
ncal $1|sed /F/s/13/\\n/g|grep -c ^\ 2
Scala,
7668 znakówW 78 znakach:
def f(y:Int)=0 to 11 count(new java.util.GregorianCalendar(y,_,6).get(7)==6)
Nic nadzwyczajnego, z wyjątkiem używania magicznych liczb dla
DAY_OF_WEEK = 7
iFRIDAY = 6
.Wersja 68 znaków:
def f(y:Int)=0 to 11 count(new java.util.Date(y-1900,_,6).getDay==5)
Tak, Java zmieniła wartości stałych dnia tygodnia między interfejsami API.
źródło
new java.util.GregorianCalendar
musi być tak długo :(Python 195/204
Działa tylko w poprzednich latach, ponieważ
monthdatescalendar
zwraca kalendarz na dany rok do chwili obecnej . Myślę, że zostało jeszcze wiele możliwości optymalizacji :).Inne rozwiązanie działa na każdą datę, ale nie jest mniejsze:
źródło
Perl 6,
5553Stara odpowiedź:
źródło
Python (v2) 120
źródło
Perl + lib POSIX 55
Z ideą nie szuka
13th
, ale po pierwsze, i jaksunday
jest0
to let Zapisz 3 znaków! Dzięki @ Iszi i Danko Durbić!Można obliczyć 2010 do 2017 (dla próbki) w następujący sposób:
(Ok, nie ma nowej linii , ale o to nie pytano;)
Stary post: 63
W akcji:
źródło
W Smalltalk (Squeak / Pharo flavour) zaimplementuj tę metodę w Integer ( 86 znaków)
Następnie używać go tak:
2014countFriday13
.Oczywiście moglibyśmy użyć krótszej nazwy, ale wtedy nie byłby to Smalltalk
źródło
C ++ - Zbyt wiele bajtów :(
Wypróbowałem rozwiązanie, które nie korzysta z żadnych bibliotek dat.
Znalazłem całkiem fajne (jeśli sam mogę to powiedzieć) rozwiązanie. Niestety nie mogę go skrócić, co naprawdę mnie wkurza, ponieważ wydaje mi się, że powinien istnieć lepszy sposób.
Rozwiązanie opiera się na tym algorytmie, który sam w sobie ma tylko 44 bajty. Niestety potrzebuję kolejnych 100 bajtów, aby ładnie ją owinąć ...
Wyjście przez kod powrotu (w C ++, użycie
cout
lubprintf
cokolwiek podobnego wymaga innego#include
, co jeszcze bardziej rozwaliłoby rozwiązanie).Program sterownika / testu:
Dane wyjściowe programu sterownika:
źródło
($m<3?$y--:$y-2)+3
zamiastd=13,
,d+=m<3?y--:y-2,
id+4
powinny działać jak dobrze i oszczędza dużo.+5
zamiast+3
i-5
powinien też działać i oszczędza 2 bajty.for(m=0;++m<13;)
oszczędza jeden bajt. Przejściem=0
do funkcji head oszczędza kolejny bajt; a przejście()%7||++f
do głowicy pętli ratuje kolejną. Zmniejszono z 149 do 136 bajtów.Clojure,
207187 bajtów-20 bajtów poprzez pozbycie się
import
i niektórych białych spacji, za którymi tęskniłem.Począwszy od 1 stycznia danego roku, pętla każdego dnia. Jeśli dzień jest w piątek trzynastego, zwiększa się zliczanie. Pętla trwa aż do następnego roku.
źródło
PHP, brak wbudowanych, 81 bajtów
Uruchom z
echo <year> | php -nR '<code>'
.awaria
Dni powtarza się co 400 lat.
W wynikach dla 1600 do 1999 (na przykład) istnieje 28-letni okres z zaledwie trzema przerwami:
Po skorygowaniu roku o te luki możemy uzyskać wynik za pomocą prostego skrótu:
Nie krótkie (95 bajtów), ale ładne. I możemy grać w golfa
źródło
for(;++$m<13;23*$m/9+($m<3?$y--:$y-2)+5+$y/4-$y/100+$y/400)%7?:$f++)$y=$argn;echo$f;
Japt
-x
, 10 bajtówSpróbuj
źródło