Policz, ile miesięcy ma pełne 31 dni, licząc kostki

12

Ilu z was, którzy nadal używają własnej kostki, aby ustalić, czy miesiąc ma pełne 31 dni lub krócej?

Twoim zadaniem jest napisanie programu zliczającego, ile miesięcy w danym miesiącu mają pełne 31 dni, a ile mniej niż 31 dni, „licząc kostki”.

Liczenie dni miesiąca przez kostki

Dzięki uprzejmości: amsi.org.au


Wejście

Para miesięcy, z których pierwszy nie musi przychodzić chronologicznie przed drugim, podanym w dowolnym odpowiednim formacie. Na przykład: 201703 201902- od marca 2017 r. Do lutego 2019 r. Opisz wybrany format wejściowy. Należy pamiętać, że dane wejściowe muszą obejmować wszystkie lata od 1 do 9999. Określony zakres miesięcy obejmuje zarówno miesiące początkowe, jak i końcowe.

Wynik

Dwie liczby całkowite: liczba miesięcy w danym przedziale z 31 dniami i liczba miesięcy w przedziale poniżej 31 dni.

Przykład: 14 10- 14 kostek, 10 rowków (oznacza to, że w tym przedziale mamy 14 miesięcy, które mają pełne 31 dni i 10 miesięcy, które mają mniej niż 31 dni).

Na przykład w przypadku, gdy drugi miesiąc w przedziale jest chronologicznie przed pierwszym 201612 201611, musisz na przykład wyzerować parę.

Przykłady wejścia i wyjścia

| Input         | Output      |
|---------------|-------------|
| 201703 201902 | 14 10       |
| 201701 202008 | 26 18       |
| 000101 999912 | 69993 49995 |
| 201802 201803 | 1 1         |
| 201601 201601 | 1 0         |
| 201612 201611 | 0 0         |

Zasady

  • Możesz wybrać dowolny język
  • Jedno wejście na linię
  • To jest , więc wygrywa najkrótszy kod w bajtach!
  • Zwycięzca zostanie wybrany 9 kwietnia
  • Obowiązują standardowe luki
  • PS: to moje pierwsze pytanie w PCG, może mieć pewne niespójności. Edytuj i potwierdź, co jest dla Ciebie niejasne.
Rizki Pratama
źródło
5
Twierdzisz, że pierwsza z nich jest chronologicznie chroniona przed drugą , ale jest to nieprawda w przypadku testowym 201612 201611.
Dennis
2
Na stronie istnieje piaskownica, w której możesz opublikować pytanie wyłącznie w celu wyjaśnienia wszystkich wątpliwości.
ghosts_in_the_code
1
Trzydzieści dni to wrzesień, kwiecień, czerwiec i listopad. Po lutym cała reszta ma trzydzieści jeden lat. Tak to pamiętam.
AdmBorkBork
@AdmBorkBork Jedynym problemem jest nieskończone zapętlenie (obowiązkowe odniesienie xkcd).
wizzwizz4
Zakładam, że zamierzasz używać kalendarza gregoriańskiego w całym zakresie dat?
Wstrzymano do odwołania.

Odpowiedzi:

7

Galaretka , 21 bajtów

ḅ12r/ị7RḂṁ12¤żC$S×⁼Ṣ$

Przyjmuje dane wejściowe jak [[y, m], [y, m]].

Wypróbuj online!

Jak to działa

ḅ12r/ị7RḂṁ12¤żC$S×⁼Ṣ$  Main link. Argument: [[a, b], [c, d]]

ḅ12                    Unbase 12; yield [x, y] := [ 12a + b, 12c + d].
   r/                  Reduce by range; yield [x, ..., y].
           ¤           Combine the five links to the left into a niladic chain.
      7                  Set the return value to 7.
       R                 Range; yield [1, 2, 3, 4, 5, 6, 7].
        Ḃ                Bit; yield [1, 0, 1, 0, 1, 0, 1].
         ṁ12             Mold 12; repeat the Booleans to create an array of length
                         12. Yields [1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1].
     ị                 At-index; yield the elements of the array to the right at 
                       the indices (1-based and modular) of the array to the left.
               $       Combine the two links to the left into a monadic chain.
              C          Complement; map t -> 1-t over the array.
             ż           Zip the original array with the complements.
                S      Take the sum of each column.
                    $  Combine the two links to the left into a monadic chain.
                  Ṣ      Sort [[a, b], [c, d]].
                   ⁼     Compare the result with [[a, b], [c, d]], yielding 1 if
                         the input is sorted, 0 if not.
                 ×     Multiply the results to both sides.
Dennis
źródło
5

JavaScript (ES6), 70 68 67 64 bajtów

Pobiera dane wejściowe jako dwie liczby całkowite w yyyymmformacie, w składni curry (a)(b). Zwraca tablicę dwóch liczb całkowitych [knuckles, grooves].

a=>g=(b,c=d=0)=>a>b?[c,d-c]:g(--b,c+!((b%=100)>11||b/.87&!!++d))

Sformatowane i skomentowane

a =>                        // main function: takes start date (a) as input / returns g
  g = (                     // recursive function g, which takes:
        b,                  //   - b = end date
        c = d = 0           //   - c = number of knuckles
      ) =>                  // and also keeps track of: d = total number of months
    a > b ?                 // if a is greater than b:
      [ c, d - c ]          //   stop recursion and return the final result
    :                       // else:
      g(                    //   do a recursive call to g():
        --b,                //   - decrement the end date
        c +                 //   - increment the # of knuckles if
        !(                  //     both of these conditions are false:
          (b %= 100)        //     - the end month (now stored in b in 0-based indexing)
          > 11 ||           //       is greater than 11
          b / 0.87 & !!++d  //     - the number of days in this month is not 31
        )                   //       (at the same time, d is incremented if the first
      )                     //       condition is false)

Przypadki testowe

Uwaga : Trzeci przypadek testowy nie jest zawarty w tym fragmencie, ponieważ nie będzie działał, chyba że w przeglądarce włączona jest funkcja optymalizacji połączenia z ogonem.

Arnauld
źródło
5

Python 2 , 92 90 86 80 bajtów

lambda a,b,c,d:[(bin(2741)[2:]*(c+1-a))[b-1:-12+d or None].count(x)for x in'10']

Wypróbuj online!

6 więcej, przechodząc na lambda, dzięki dzięki @math_junkie za pomysł. Teraz wyświetla listę zawierającą dwie liczby.

Poprzednia wersja inna niż lambda (86 bajtów)

a,b,c,d=input()
for x in'10':print(bin(2741)[2:]*(c+1-a))[b-1:-12+d or None].count(x),

Wypróbuj online stary!

2 zapisane dzięki dzięki @ovs za pomoc w pozbyciu się len(k). Nie myślałem o użyciuNone .

Dane wejściowe to lista liczb całkowitych w formacie y1,m1,y2,m2

Pewne uznanie dzięki @KeerthanaPrabhakaran, który dostał bin(2741)[2:]wcześniej, co zrobiłem, co pozwala zaoszczędzić 1 bajt na sztywnym kodowaniu łańcucha binarnego.

ElPedro
źródło
Imponujące ... k = bin (2741) [2:] * (c + 1-a) wiał mój umysł
officialaimm
1
To o 2 bajty krócej
2017
Znakomity! Próbowałem wypracować motykę, aby pozbyć się len(k)ostatniego kawałka. Dzięki.
ElPedro
1
Możesz zapisać 6 bajtów, używając lambda: TIO
matematyki
4

PHP , 259 256 249 248 237 221 bajtów

Outgolfed by aross : https://codegolf.stackexchange.com/a/114512/38505

Format wejściowy: yyyymm,yyyymm

$i=explode(",",fgets(STDIN));$_="DateTime::createFromFormat";foreach(new DatePeriod($_(Ym,$i[0]),new DateInterval(P1M),$_(Ym,$i[1])) as$f)date(t,mktime(0,0,0,$f->format(m),1,$f->format(y)))>30?++$x:++$y;
echo $x.' '.++$y;

Wypróbuj online!


starsza wersja

$i=explode(",",fgets(STDIN));$_="DateTime::createFromFormat";$y=1;foreach(new DatePeriod($_("Ym",$i[0]),new DateInterval('P1M'),$_("Ym",$i[1])) as$f)date("t",mktime(0,0,0,$f->format("m"),1,$f->format("y")))==31?++$x:++$y;
echo $x.' '.$y;

Wypróbuj online!

$i=explode(",",fgets(STDIN));$_="DateTime::createFromFormat";$y=1;foreach(new DatePeriod($_(Ym,$i[0]),DateInterval::createFromDateString('1 month'),$_(Ym,$i[1])) as$f)date(t,mktime(0,0,0,$f->format(m),1,$f->format(y)))>30?++$x:++$y;
echo $x.' '.$y;

Wypróbuj online!

$i=explode(",",fgets(STDIN));$_="DateTime::createFromFormat";$y=1;foreach(new DatePeriod($_(Ym,$i[0]),DateInterval::createFromDateString('1 month'),$_(Ym,$i[1])) as$f)date(t,mktime(0,0,0,$f->format(m),1,$f->format(y)))==31?++$x:++$y;
echo $x.' '.$y;

Wypróbuj online!

$i=explode(",",fgets(STDIN));$_="DateTime::createFromFormat";foreach(new DatePeriod($_("Ym",$i[0]),DateInterval::createFromDateString('1 month'),$_("Ym",$i[1])) as$f)date("t",mktime(0,0,0,$f->format("m"),1,$f->format("y")))==31?++$x:++$y;
echo $x.' '.++$y;

Wypróbuj online!

$i=explode(",",fgets(STDIN));$_="DateTime::createFromFormat";$y=1;foreach(new DatePeriod($_("Ym",$i[0]),DateInterval::createFromDateString('1 month'),$_("Ym",$i[1])) as$f)date("t",mktime(0,0,0,$f->format("m"),1,$f->format("y")))==31?++$x:++$y;
echo $x.' '.$y;

Wypróbuj online!

ʰᵈˑ
źródło
3

Partia, 93 bajty

@set/ag=(y=%2/100-%1/100)*5+(x=%2%%100+6)*5/12-(w=%1%%100+5)*5/12,k=y*12+x-w-g
@echo %k% %g%

Akceptuje dwa parametry w formacie ymm (tj. 101 - 999912). Poprzednie 129-bajtowe rozwiązanie oparte na pętli:

@set/al=%1-%1/100*88,u=%2-%2/100*88,k=g=0
@for /l %%i in (%l%,1,%u%)do @set/a"m=%%i%%12,k+=1451>>m&1,g+=2644>>m&1
@echo %k% %g%
Neil
źródło
Nieprawidłowy wynik dla 000101 999912, prawdopodobnie z powodu limitu liczby całkowitej?
officialaimm
1
@officialaimm Niepoprawny format wejściowy, przepraszam - rok nie powinien mieć zer wiodących.
Neil
3

Python 3.5 ( 164 162 154 152 150 150 140 140 137 bajtów)

n=int;a,b=input().split();t=k=0
for r in range(n(a[4:]),(n(b[:4])-n(a[:4]))*12+n(b[4:])+1):t+=1;k+=n('101010110101'[r%12-1])
print(k,t-k)

repl.it

przyjmuje dane wejściowe w postaci rrrrrrrrrm

wypisuje dane wyjściowe jako numer_kolki numer_krwi

  • zapisane 2 bajty: Dzięki Cole
  • zapisane 8 bajtów: usunięto niechciane zmienne
  • zapisane 2 bajty: zmniejszone t = 0; k = 0 jako t = k = 0
  • zapisane 2 bajty: Dzięki Cole'owi (wcześniej tego mi brakowało)
  • zapisane 2 bajty: Dzięki Keerthana
  • zapisane 8 bajtów: usunięto niechciane zmienne
  • zapisane 3 bajty: Dzięki math_junkie (split ('') to split ())
Officialaimm
źródło
1
Myślę, że możesz zmniejszyć niektóre bajty, robiąc, n=inta może także trochę execwygłupów.
cole
1
Myślę, że możesz to zrobić 2773&1<<r%12-1>0zamiastint('101010110101'[r%12-1])
Loovjo,
@Loovjo Dostaję błąd!
officialaimm
1
użycie print([k,t-k])as print(k,t-k)dałoby pożądany wynik, (k,g)zmniejszając w ten sposób 2 bajty!
Keerthana Prabhakaran
1
Wierzę, że można zastąpić split(' ')zsplit()
matematyki junkie
3

Python 2 , 147 146 142 bajtów

def s(a,b):y=100;r=bin(2741)[2:];x=b/y-a/y;i=r*(x-1);return((0,0),map((i+r[a%y-1:]+r[:b%y]if i or x else r[a%y-1:b%y]).count,('1','0')))[a<=b]

Wypróbuj online!

  • Zapisane 4 bajty - Podziękowania dla @math_junkie za zasugerowanie klauzuli if-else przy wyszukiwaniu tablic!

Rozbijając kod,

def s(a,b):
 y=100
 r=bin(2741)[2:] #'101010110101'
 x=b/y-a/y #to get the difference between the two years
 i=r*(x-1)
 return((0,0),map((i+r[a%y-1:]+r[:b%y]if i or x else r[a%y-1:b%y]).count,('1','0')))[a<=b]
Keerthana Prabhakaran
źródło
1
Możesz zapisać bajty, zastępując if-elseklauzule przeglądami tablic. Zobacz ten post, aby poznać szczegóły
matematyka ćpun
To był naprawdę fajny sposób! Nie wiedziałem tego wcześniej! Dzięki!
Keerthana Prabhakaran
3

PHP, 120 103 97 96 bajtów

for($f=strtotime;$f($argv[2])>=$n=$f($argv[1].+$x++.month);)$k+=date(t,$n)>30;echo+$k,_,$x-1-$k;

Uruchom tak:

php -nr 'for($f=strtotime;$f($argv[2])>=$n=$f($argv[1].+$x++.month);)$k+=date(t,$n)>30;echo+$k,_,$x-1-$k;' 0001-01 9999-12;echo
> 69993_49995

Wyjaśnienie

for(
  $f=strtotime;          # Alias strtotime function which is called twice.
  $f($argv[2]) >=        # Create end date timestamp. Iterate until the end
                         # date is reached.
  $n=$f(
    $argv[1].+$x++.month # Create timestamp from start date + X months.
  );
)
  $k+=date(t,$n) > 30;   # If "t" of current date (days in month) is 31
                         # increment $k (knuckles).

echo+$k,_,$x-1-$k;       # Compute grooves (iterations - $k) and output,
                         # implicit cast to int to account for 0 count.

Poprawki

  • Zapisano 17 bajtów, używając stylu znacznika czasu zamiast stylu obiektu DateTime
  • Zapisano 6 bajtów, nie przypisując znacznika daty zakończenia do zmiennej $e, po prostu porównaj bezpośrednio
  • Zaoszczędzono 1 bajt, nie licząc rowków, a jedynie obliczając go po pętli
aross
źródło
$x++zamiast +$x++też działa.
Tytus
@Titus, miałem to na początku, ale zdałem sobie sprawę, że przy $xniezainicjalizowanym łańcuchu będzie 2017-12month, który jest nierozpoznanym formatem i rezultatem w 1970 roku
aross
Wicked ... gdzieś to działało. Na tyle zły, że działa bez literału +w łańcuchu.
Tytus
2

PowerShell , 96 bajtów

for($a,$b=[datetime[]]$args;$a-le$b;$a=$a.AddMonths(1)){$x++;$z+=$a.Month-in2,4,6,9,11};$x-$z;$z

Wypróbuj online!

Pobiera dane wejściowe jako formularz 2017-03. Korzysta z wbudowanych bibliotek dat .NET i pętli od danych wejściowych $ado $b, każda iteracja zwiększa się $x++i dodaje, $zjeśli bieżący .Monthjest -in 2,4,6,9,11(tj. Miesiąc inny niż 31-dniowy). Następnie wyprowadzamy nasze całkowite miesiące minus miesiące nieprzeznaczone na 31 dni i miesiące $x-$znieprzyjęte na 31 dni $z.

Rzuca błąd na 0001-01do 9999-12badania sprawy, ponieważ .NET obsługuje tylko lata do 9999tak ostatecznych .AddMonths(1)przyczyn przepełnienie. Nadal jednak wyświetla prawidłowe wartości, ponieważ jest to błąd nie kończący się; powoduje tylko zamknięcie pętli.

Prawdopodobnie byłoby to krótsze, aby zrobić to arytmetycznie, na przykład odpowiedzi w języku Python lub JavaScript, ale chciałem pokazać podejście z wykorzystaniem wbudowanych platform .NET.

AdmBorkBork
źródło
2

Bash , 113 bajtów

s="$1-1";e="$2-1";sort <(while [ "$s" \< "$e" ];do s=$(date +%F -d"$s+1month");date +%d -d"$s-1day";done)|uniq -c

Wypróbuj online!

potrzebuje gry w golfa ...

przyjmuje dane jako 2016-03 2018-10

wyjścia:

  1 28
  7 30
 12 31

bez golfa:

s="$1-1"
e="$2-1"                     # adds first day of month to the dates
sort <(                    
while [ "$s" \< "$e" ]; do   #iterates over dates
s=$(date +%F -d"$s+1month")  #adds one month to start date
date +%d -d"$s-1day"         #outputs last day of previous month
done) | uniq -c              #counts ocurrences of day number prevously sorted
marcosm
źródło
1

Szybki, 151 bajtów

let f={(m:[Int])->[Int] in var k=[0,0]
(m.min()!...m.max()!).map{$0%100}.filter{$0>0&&$0<13}.forEach{m in let n = m>7 ?m-7:m
k[(n%2+1)%2]+=1}
return k}

input to tablica dwóch liczb całkowitych w formacie zgodnym z przykładem

John McDowall
źródło