Najwyższe środy


22

Najwyższe środy

Twoim zadaniem jest policzenie liczby środy przypadającej na pierwszy dzień miesiąca w danym roku. Na przykład 7-13-16jest pierwszą środą. Aby zachować spójność, użyj kalendarza gregoriańskiego dla wszystkich dat.

Wkład

Dane wejściowe do Twojego programu / funkcji będą wynosić rok (np. 2016) I będą elastyczne. Rok będzie liczbą całkowitą między 1912 a 2233 włącznie.

Wydajność

Wynik jest również elastyczny i powinna być liczbą pierwszych środy (np 18.).

Punktacja

To jest więc wygrywa najkrótszy kod w bajtach!

Przypadki testowe

wejście -> wyjście
--------------------
1912 -> 19
1914 -> 16
1984 -> 17
1996 -> 19
2063 -> 19
2150 -> 16
2199 - > 18
2233 -> 18

Odpowiedzi:


7

MATL , 38 36 34 bajtów

FT+"@llI$YO]q&:t8XO!s9\~)9#1$ZOZps

Wypróbuj online! Lub sprawdź wszystkie przypadki testowe (zajmuje kilka sekund).

Wyjaśnienie

FT+     % Input year implicitly. Add [0 1] element-wise. Gives array with input year
        % and next year
"       % For each of those two years
  @     %   Push year
  ll    %   Push 1 twice. This indicates January 1.
  I$YO  %   Convert year, month, day to serial date number
]       % End for each. We now have the serial date number for January 1 of the input
        % year and that of the following year
q       % Subtract 1 to the latter, to yield December 31 of the input year
&:      % Inclusive range between those two numbers. This gives an array of serial date
        % numbers for the whole input year
t       % Push another copy of that array
8XO     % Convert to date string with format 8. This gives weekday as "Mon", "Tue" etc.
        % The result is a 3-column 2D char array, where each row is a day
!s      % Transpose, sum of each column. 'Wed' gives 288 (sum of ASCII codes)
9\~     % 288 gives 0 modulo 9, and is the only weekday to do so. So we compute modulo 9
        % and negate. This gives true for Wednesdays, false for the rest
)       % Apply as logical index into the array of serial date numbers
9#1$ZO  % Array of month numbers corresponding to those serial date numbers
Zp      % Array that contains true for prime numbers, false for the rest
s       % Sum of array. Display implicitly

Jestem przekonany, że MATL nie da się pokonać w wyzwaniach opartych na randkach. Powinniśmy stworzyć DATL, który jest zoptymalizowany pod kątem wyzwań związanych z datą.
Suever

@Suever Haha, ładne imię
Luis Mendo

20

Python 2, 95 93 68 67 bajtów

lambda y:0x10ea2c8dbb06c5619/5**((y+((y-22)/99-y/2002)*16)%28)%5+16

Dzięki @Josay za grę w golfa z 1 bajtu!

Przetestuj na Ideone .


3
Możesz zapisać 1 znak 0x10ea2c8dbb06c5619zamiast 19501370182350951961.
SylvainD

Rozumiem ideę, big_constant//5**long_expressionale jak, u licha, przyszedłeś z tą stałą i taką ekspresją? To szalone: ​​D
Sherlock9

2
Stała jest prostą tabelą przeglądową, w której używane są podstawowe 5 cyfr, ale konwertowane na podstawową 10, dzięki czemu cyfry są wyodrębniane numerycznie, a nie za pomocą indeksu ciągów. To wyrażenie wygląda mi na wieczny kalendarz. (Problem byłby zbyt łatwy, gdyby ograniczał się do lat od 1901 do 2099, ponieważ odpowiedzi powtarzają się co 28 lat w tym przedziale, więc byłoby to tylko przypadkiem wzięcia roku mod 28 i sprawdzenia go w tabeli. )
Neil

13

Brain-Flak , 6588 , 2310 , 2308 , 2290 bajtów

Po pierwsze, nie napisałem prawie 100% tego programu, co prawdopodobnie świadczy o ogromnej wielkości programu. Większość tego kodu została napisana przez mój własny algorytm golfowy Brain-Flak . Wraz z dodatkowym skryptem Pythona napisałem, aby podpowiedzieć go we właściwym kierunku.

Wypróbuj online!

({}<(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((()()())){}{}){})[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])()())[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])())()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())>[(((((((((()()()()())){}{}){}){}){}){}[()]){}){}){}]){({}[()]<{}>)}{}({}<{{}}>)

Chociaż ten program jest dość długi jak na golfa kodowego, tak naprawdę jest całkiem przyzwoity dla Brain-Flak. Obecnie rekord świata w dzieleniu liczb całkowitych wynosi ponad 1000 bajtów.

Wyjaśnienie

Algorytm jest dość prosty. Ponieważ dostępna jest ograniczona liczba lat (321), po prostu wypycha odpowiedzi w odwrotnej kolejności pod dane wejściowe i używa algorytmu wyszukiwania, aby znaleźć poprawną odpowiedź. Podczas gdy kodowanie na stałe wszystkich 321 możliwości może wydawać się raczej nieefektywne przy tak złożonym zadaniu, jak i języku tak ezoterycznym jak uderzenie mózgu, może być najlepszym rozwiązaniem. (Planuję się dowiedzieć w nadchodzącym tygodniu).

Ponieważ większość z 321 liczb wynosi średnio około 18 i różnią się one nieznacznie z roku na rok, zamiast wypychać wszystkie liczby indywidualnie, przepycham pierwszy rok (2233) normalnie, a następnie po prostu powielam i zmieniam nieco wartość każdego roku po. W ten sposób zamiast płacić za push ~ 18 przez wszystkie 321 lat, płacę tylko za push ~ 2 za każdy rok.

Po wysłaniu wszystkich odpowiedzi odejmuje 1912 od danych wejściowych ({}[(((((((((()()()()())){}{}){}){}){}){}[()]){}){}){}])(może to być nieoptymalne, przepisałem optymalizator, aby pominąć pewne wartości, które moim zdaniem nie byłyby optymalne, ponieważ liczby zakodowane na stałe są procesem nadwykładniczym i uruchomienie go do końca może mieć zajęło kilka dni).

Następnie odejmuje jeden od pierwszego elementu i wyskakuje z drugiego elementu, aż wynik osiągnie zero {({}[()]<{}>)}.

Zeruje zero {}i wszystkie elementy poniżej górnego elementu ({}<{{}}>).


Jakie jest ogólne podejście do liczb golfowych?
Neil

Prostym pomysłem jest to, że jeśli masz liczbę z czynnikami n i m, naciskasz n m-1 razy, a następnie pop m-1 razy. Początkowe wypychanie jest oceniane jako n, a każde pop ocenia jako dodatkowe n, co oznacza, że ​​(1 + m-1) (n) jest taki sam jak mn. Odbywa się to rekurencyjnie, ponieważ aby pchnąć n, musimy również zagrać w golfa n. Ponieważ ta metoda nie działa dobrze w przypadku niektórych liczb, w szczególności liczb pierwszych, rozglądamy się, aby sprawdzić, czy w pobliżu jest bardziej wydajna liczba, a jeśli tak, wyrażamy to jako sumę tej liczby i różnicy.
Wheat Wizard

Rozumiem ... więc podane dwie liczby ni mktóre mają długości ki l, przypuszczam n+mmiałby długość k+l? Co n*m?
Neil

n*mbyłoby k+4m-4lub l+4n-4. Wynika to z faktu, że mnożenie jest zakodowane na stałe. Najpierw pchamy n m-1czasy. Aby to zrobić, potrzebujemy ksymboli do wyrażenia ni 2m-2symboli do wyrażenia wypchnięć (każde naciśnięcie to 2 symbole). Potem pukamy m-1, kosztując nas dodatkowo 2m-2(popy również kosztują 2 symbole). To sumuje się do k+4m-4. możemy także pomnożyć m*n(własność przemienną), aby uzyskać l+4n-4. Wynik będzie krótszy z dwóch.
Wheat Wizard

1
Cóż, jeśli to prawda, to +1kosztuje 2, *2kosztuje 4, *3kosztuje 8, *4kosztuje 12, co jest droższe niż *2*2, więc nie warto (spośród liczb poniżej 1000 znalazłem tylko 10, które nie wykorzystały *2: 1, 2, 3 , 4, 5, 9, 15, 27, 45, 135). W 1912 r. Najlepsze, co mogłem zrobić, ((((((1+1+1)*2+1)*2*2+1)*2+1)*2+1)*2+1)*2*2*2to długość 52.
Neil

7

Bash + wspólne narzędzia, 39

ncal $1|grep W|factor|egrep -c ': \S+$'

Trwa rok wprowadzania jako parametr wiersza polecenia. Zazwyczaj wysyła takie wiadomości do STDERR - myślę, że jest to zgodne z prawem w przypadku tej meta-odpowiedzi :

factor: We is not a valid positive integer

Jeśli chcesz jawnie wyłączyć dane wyjściowe STDERR, możesz to zrobić, uzyskując wynik 43 :

ncal $1|grep W|factor 2>-|egrep -c ': \S+$'

Zauważ, że zakłada to ustawienie regionalne w języku angielskim lub C / POSIX. Nie działa tak dobrze w gd_GB.utf8, gdzie wszystkie nazwy dni są skrótem Di.
Toby Speight

6

Oktawa, 86 bajtów

Pod żadnym względem nie jest to szybkie. Ale tak naprawdę nie jest to celem golfa kodowego, prawda?

function r=p(y)r=0;for(i=698346:7:815953)d=datevec(i);r+=d(1)==y*isprime(d(3));end;end

Oktawa może śledzić daty według „numeru daty” - liczby dni, w których 1 stycznia 0 jest dniem 1. Według tego pomiaru 3 stycznia 1912 r. (Pierwsza środa w naszym zestawie) to dzień 698,346. Zacznij od tego i powtarzaj co 7 dni (wszystkie środy) do końca 2233 r. I dodaj 1, jeśli rok jest rokiem docelowym ORAZ dzień miesiąca jest liczbą pierwszą.


5

Python 2.7, 166 , 165 , 150 bajtów

from datetime import*
y=input()
d,c=date(y,1,1),0
while d.year==y:n=d.day;c+=n>1<2==d.weekday()>0<all(n%x for x in range(2,n));d+=timedelta(1)
print c

Z pewnością jest tu miejsce na ulepszenia. Jestem raczej nowy w golfie w Pythonie. To używa datetimemodułu. Pętla przechodzi przez wszystkie dni w roku, dodając jeden do akumulatora, jeśli spełnia kryterium. Następnie drukuje wynik. Większość dużych obciążeń znajduje się w module, więc kod może być dość cienki.

Jeden bajt zapisany dzięki Morgan Thrapp i 15 bajtów zapisanych przez Pietu1998 .


1
Możesz zapisać jeden bajt, przełączając n%x==0na n%x<1.
Morgan Thrapp

2
Nie -1jest to konieczne, ponieważ rangeindeks końcowy jest wyłączny. Dodatkowo możesz przekonwertować na filtergenerator. [0for x in range(2,n)if n%x<1]
PurkkaKoodari

Możesz użyć any(...)lub all(...)zamiast not filter(...).
kennytm

1
Łącząc powiązane porównania i allmożesz uratować całą grupę. c+=n>1<2==d.weekday()>0<all(n%x for x in range(2,n))
PurkkaKoodari

3

J, 44 bajty

+/@(valdate*3=weekday)@,.&(,/(>:,"0/p:)i.12)

Właśnie odkryłem, że J ma wbudowane funkcje do manipulacji datami.

Stosowanie

Dodatkowe polecenia są używane do formatowania wielu wejść / wyjść.

   f =: +/@(valdate*3=weekday)@,.&(,/(>:,"0/p:)i.12)
   (,.f"0) 1912 1914 1984 1996 2063 2150 2199 2233
1912 19
1914 16
1984 17
1996 19
2063 19
2150 16
2199 18
2233 18

Wyjaśnienie

+/@(valdate*3=weekday)@,.&(,/(>:,"0/p:)i.12)  Input: year
                                       i.12   The range [0, ..., 11]
                              >:              Increment each to get the months [1, ..., 12]
                                    p:        Get the first 12 primes [2, ..., 37]
                                ,"0/          Make a table between each month and prime
                           ,/                 Join the rows
                       ,.&                    Prepend the year to each
                                              The date format is YYYY MM DD
            3=weekday                         Check if each date occurs on Wednesday
    valdate*                                  and is a valid date
+/@                                           Count the number of true values and return

1

PowerShell v3 +, 99 95 bajtów

Podejście brutalnej siły -

param($y)(1..12|%{$m=$_;2,3,5,7,11,13,17,19,23,29,31|?{(date "$m-$_-$y").DayofWeek-eq3}}).Count

Pobiera dane wejściowe $y, pętle od 1do 12, tymczasowo zapisuje miesiąc $m, a następnie zapętla każdą liczbę pierwszą od 2do 31. Dla każdego z nich konstruujemy jeden Get-Datez tego konkretnego dnia, a następnie wybieramy tylko te z DayOfWeek -equal do 3(tj. Środa). Hermetyzuje to wszystko w parens, aby sformułować tablicę, i bierze .Countje.


Alternatywnie podejście matematyczne -

PowerShell v3 +, 105 bajtów

param($y)(16,19,18,20,16,18,19)[($a=(date "1-1-$y").DayOfWeek)]+(1,-3,0,1,2)[$y%5]*($a-in0,2,3,4)*!($y%4)

Skończyło się na tym, że włosy były tylko dłuższe niż podejście brutalnej siły, ale włączam to tutaj, ponieważ może być korzystne dla innych.

Ponownie przyjmuje dane $yjako rok. Tym razem wykonujemy operacje matematyczne ściśle w oparciu o pierwszy dzień roku. Najpierw obliczamy, który to dzień tygodnia, i zapamiętujemy go $ado wykorzystania później. To indeksuje do pierwszej tablicy, która daje nam zwykle prawidłową liczbę. Musimy dodać do tego drugi indeks oparty na tym, czy jest to potencjalny rok przestępny, czy jest to niedziela, wtorek, środa lub czwartek, i na podstawie tego, jaki jest rok.

Jest to oparte na poniższej obserwacji. Pierwsza kolumna to dzień tygodnia 1 stycznia, druga to zwykłe wyjście. O ile rok nie jest jedną ze środkowych liczb, to jest to liczba w parenach. Ostatnia kolumna opisuje działanie indeksowania% 5.

Jan-1 -> #  ... Except if $y=       (then it's this number) | $y % 5 =
Sun   -> 16 ... 1928 1956 1984 etc. (17)                    |    3
Mon   -> 19
Tue   -> 18 ... 1924 1952 1980 etc. (20)                    |    4
Wed   -> 20 ... 1936 1964 1992 etc. (17)                    |    1
Thur  -> 16 ... 1920 1948 1976 etc. (17)                    |    0
Fri   -> 18
Sat   -> 19

Uwaga: w obu przypadkach założono, że en-usjest to bieżące ustawienie programu PowerShell dla informacji o kulturze / dacie. Formatowanie daty i DayOfWeekliczby mogą wymagać odpowiedniego dostosowania w przypadku innych wariantów kultury.


1

Rubinowy, 83 + 15 ( -rdate -rprimeflagi) = 98 bajtów

Wypróbuj online! (Zaimportowane moduły są wstawiane, ponieważ idk, jeśli mogę używać flag w repl.it)

->y{k=0;Prime.each(31){|d|k+=(1..12).count{|m|Date.new(y,m,d).wday==3 rescue p}};k}

1

JavaScript ES6, 187 182 181 179 bajtów

179 Zamieniono w pętli for na pętlę while

z=y=>{D=new Date("1/3/1912");N=0;a=()=>D.getFullYear();b=()=>D.getDate();c=()=>D.setDate(b()+7);for(;a()<=y;c())N+=y-a()?0:-1<[2,3,5,7,11,13,17,19,23,29,31].indexOf(b());return N}

181 Zagęszczony trójskładnikowy

z=y=>{D=new Date("1/3/1912");N=0;a=()=>D.getFullYear();b=()=>D.getDate();c=()=>D.setDate(b()+7);while(a()<=y){N+=y-a()?0:-1<[2,3,5,7,11,13,17,19,23,29,31].indexOf(b());c()}return N}

182 Połączone dwie pętle

z=y=>{D=new Date("1/3/1912");N=0;a=()=>D.getFullYear();b=()=>D.getDate();c=()=>D.setDate(b()+7);while(a()<=y){N+=a()==y?-1<[2,3,5,7,11,13,17,19,23,29,31].indexOf(b()):0;c()}return N}

187

z=y=>{D=new Date("1/3/1912");N=0;a=()=>D.getFullYear();b=()=>D.getDate();c=()=>D.setDate(b()+7);while(a()<y)c();for(;a()==y;c())N+=-1<[2,3,5,7,11,13,17,19,23,29,31].indexOf(b());return N}

Nie sądzę, żeby to się liczyło, ponieważ w tym przykładzie podałeś pierwszą pierwszą środę dla konkretnego roku. Wyzwanie PO stanowi, że potrzebuje on jedynego parametru ... Jak dotąd wielki wysiłek ...
WallyWest

„Dane wejściowe do Twojego programu / funkcji będą wynosić rok” - ale to, co wskazujesz, nie jest tym. Pierwszą środę 1912 r. Wykorzystuję jako zalążek, ponieważ jest ona lub jest przed każdą inną środą w okresie wyznaczonym przez OP, ale równie dobrze mogłabym wykorzystać dowolną środę z 1911 r. Lub przed nią, aby ją zaliczyć. Dane wejściowe do mojej funkcji to jeszcze rok, a funkcja nadal oblicza liczbę głównych środy w danym roku w ramach czasowych sugerowanych przez PO, więc nie jestem pewien, jak to nie pasuje do wyzwania.
Pandacoder

Ach, przepraszam ... Na początku nie zdawałem sobie sprawy, że używasz tego jako składnika siewnego ... Świetny pomysł ... Zwłaszcza biorąc pod uwagę, że twoje rozwiązanie pokonuje moje o około 30 ..;)
WallyWest

1
Dzięki. Inspirację czerpałem z implementacji Bamona-Flaka Eamona Olive, która zgodnie z jego wyjaśnieniem ma wszystkie wstępnie zaprogramowane odpowiedzi.
Pandacoder

1

Partia, 248 bajtów

@set/ad=0,l=1,n=20
@for /l %%i in (1913,1,%1)do @set/ad=(d+l+1)%%7,l=!(%%i%%4)-!(%%i%%100)+!(%%i%%400)
@goto %l%%d%
:03
:06
@set/an-=1
:12
:13
:16
@set/an-=1
:01
:04
:14
@set/an-=1
:00
:05
:10
:15
@set/an-=1
:02
:11
@echo %n%

Objaśnienie: djest dniem tygodnia, w którym 0dla poniedziałku, który jest dogodnie 1 stycznia 1912 r., lJest flaga wskazująca, czy rok jest rokiem przestępnym, 1dla 1912 r. Następnie przechodzimy od 1913 do roku wejściowego, aktualizując dzień tydzień i przeliczanie flagi roku przestępnego w miarę upływu czasu. Na koniec używamy flagi roku przestępnego i dnia tygodnia, aby zindeksować coś, co jest efektywnie dużą instrukcją zmiany w celu ustalenia nliczby pierwszych środy. Ustawienie wartości n20 i zmniejszenie jej wraz ze spadkiem jest jednak tańsze niż użycie logiki sterowania przepływem, ale wynik jest taki, że jeśli 1 stycznia roku bez skoku jest czwartek lub niedziela, to jest 16 pierwszych środy i tak dalej dla innych przypadków .


1

JavaScript ES6 206 203 199 197 195 183 182 179

Nie najkrótszy, ale na razie najlepszy, co mogę zrobić ... Sugestie dotyczące gry w golfa mile widziane ...

p=n=>--d-1?n%d&&p(n):1;v=Date;D=(x,y)=>new v(x.setDate(x.getDate()-y));W=a=>eval('for(Z=0,z=D(w=new v(a,11,31),(w.getDay()+4)%7);z>new v(a,0,1);)Z+=~~p(d=z.getDate()),z=D(z,7);Z')

Zmiany:

  1. zmiana komponentu trójskładnikowego z: 3>=x?3-x:10-xna 6-(x+10)%7, zapisywanie: 3 Zmiany w lokalizacjach deklaracji;
  2. scalono x=w.getDay();z=D(w,6-(x+10)%7)z z=D(w,6-(w.getDay()+10)%7), zapisując: 4
  3. przesunięto Z=0z forpętli na deklarację daty i wciśnięto z=D(w,6-(x+10)%7)w forpętlę, aby uporządkować, oszczędzając: 2
  4. przesunięto w=new Date(a,Z=0,1)deklarację do forpętli, scalając z istniejącą wdeklaracją, oszczędzając: 2
  5. przepisanie funkcji szukania głównego na funkcję testowania głównego, oszczędność: 12
  6. zmiana +!!na, ~~aby zmniejszyć i nadal konwertować p(d=1)z NaNna 0, umożliwiając działanie funkcji Prime Test, oszczędzając: 1
  7. Przeniesiono wszystkie dodatkowe funkcje z głównej funkcji wywołującej W, ponownie zdefiniowano forpętlę - przechodząc w odwrotną stronę od 31 grudnia, zapisując Dateobiekt jako osobną zmienną, a następnie ponownie zapisując forpętlę do evalwywołania; oszczędność 3.

@PandaCoder, nadrabiam zaległości, kolego!


1

R, 149 147 bajtów

y=function(x){s=strftime;b=ISOdate
a=seq(b(x,1,1),t=b(x,12,31),b='d')
length(a[s(a,'%u')==3&trimws(s(a,'%e'))%in%c(2,3,5,7,11,13,17,19,23,29,31)])}

Przetestuj na Ideone .


0

Groovy, 126

Groovy nie ma sprawdzania poprawności liczb pierwszych, musiał to również zbudować.

{n->p={x->x<3||(2..Math.sqrt(x)).every{x%it}};(new Date("1/1/$n")..new Date("12/31/$n")).collect{it[7]==4&&p(it[5])?it:0}-[0]}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.