Порахуйте, скільки місяців триває цілих 31 день, рахуючи костяки


12

Скільки з вас, хто все ще користується власною ручкою, щоб визначити, чи є у місяця повний 31 день чи менше?

Ваша робота полягає в тому, щоб написати програму, щоб підрахувати, скільки місяців у місячному діапазоні ви маєте цілих 31 день, а скільки - менше 31 дня, "рахуючи костяки".

Відлік днів місяця за костяками

Люб’язно: amsi.org.au


Вхідні дані

Пара місяців, перший з яких не повинен хронологічно виходити до другого, поданий у будь-якому відповідному форматі. Наприклад: 201703 201902- березень 2017 р. По лютий 2019 р.. Зауважте, що вхідні дані повинні мати можливість включати всі роки від 1 до 9999 р. Вказаний діапазон місяців включає як початковий, так і кінцевий місяці.

Вихідні дані

Два цілих числа: кількість місяців у заданому діапазоні з 31 дією та кількість місяців у діапазоні менше ніж 31 день.

Приклад: 14 10- 14 коліс, 10 канавок (це означає, що в цьому місячному діапазоні ми маємо 14 місяців, які мають цілі 31 день, і 10 місяців, які мають менше 31 дня).

Наприклад, для введення, коли другий місяць у діапазоні приходить хронологічно до першого, наприклад 201612 201611, ви повинні вивести пару нуля.

Приклади введення та виведення

| 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         |

Правила

  • Ви можете вибрати будь-яку мову, яка вам подобається
  • Один вхід на рядок
  • Це , тому найкоротший код у байтах виграє!
  • Переможець буде обраний 9 квітня
  • Застосовуються стандартні лазівки
  • PS: це моє перше питання в PCG, це може мати деякі невідповідності. Не соромтесь редагувати та підтверджувати те, що для вас незрозуміло.

5
Ви говорите, що перший з них гарантовано прийде хронологічно до другого , але це неправда для тестового випадку 201612 201611.
Денніс

2
На сайті існує пісочниця, де ви можете опублікувати питання виключно, щоб усунути всі сумніви.
ghosts_in_the_code

1
Тридцять днів має вересень, квітень, червень та листопад. Після закінчення лютого всі решта мають тридцять один. Ось як я це пам’ятаю.
AdmBorkBork

@AdmBorkBork Єдина проблема з цим - це нескінченна циклічність (обов'язкова посилання на xkcd).
wizzwizz4

Я припускаю, що ви маєте намір використовувати григоріанський календар протягом усього періоду дат?
Призупинено до подальшого повідомлення.

Відповіді:


7

Желе , 21 байт

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

Приймає вхід як [[y, m], [y, m]].

Спробуйте в Інтернеті!

Як це працює

ḅ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.

5

JavaScript (ES6), 70 68 67 64 байт

Вводиться як два цілих числа у yyyymmформаті, в синтаксисі currying (a)(b). Виводить масив з двох цілих чисел [knuckles, grooves].

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

Відформатовано та прокоментовано

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)

Тестові справи

Примітка . Третій тестовий випадок не включений у цей фрагмент, оскільки він не працюватиме, якщо у вашому веб-переглядачі не ввімкнено функцію оптимізації викликів Tail.


5

Python 2 , 92 90 86 80 байт

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

Спробуйте в Інтернеті!

Ще 6 шляхом переходу на лямбда, завдяки @math_junkie за ідею. Тепер виводиться список, що містить два числа.

Попередня не лямбда-версія (86 байт)

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

Спробуйте це в Інтернеті!

2 врятовано завдяки @ovs за те, що він допомагає мені позбутися len(k). Я не думав використовувати None.

Введення - це список цілих чисел у форматі y1,m1,y2,m2

Деякий кредит завдяки @KeerthanaPrabhakaran, який отримав bin(2741)[2:]до того, як я це зробив, економить 1 байт на жорсткому кодуванні двійкового рядка.


Вражає ... к = бен (2741) [2:] * (з + 1-а) підірвав мій розум
officialaimm

1
Це на 2 байти коротше
до

Блискуче! Я намагався розробити мотику, щоб позбутися len(k)останнього шматочка. Дякую.
ElPedro

1
Ви можете зберегти 6 байт, скориставшись лямбда: TIO
математика наркомана

4

PHP , 259 256 249 248 237 221 байт

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

Формат введення: 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;

Спробуйте в Інтернеті!


Старіші версії

$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;

Спробуйте в Інтернеті!

$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;

Спробуйте в Інтернеті!

$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;

Спробуйте в Інтернеті!

$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;

Спробуйте в Інтернеті!

$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;

Спробуйте в Інтернеті!


3

Пакет, 93 байти

@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%

Приймає два параметри у форматі ymm (тобто 101 - 999912). Попереднє 129-байтове рішення на основі циклу:

@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%

Неправильний результат для 000101 999912, ймовірно, через ціле обмеження розміру?
officialaimm

1
@officialaimm Неправильний формат введення, вибачте - рік не повинен мати провідні нулі.
Ніл

3

Python 3.5 ( 164 162 154 152 150 148 140 137 байт)

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

приймає дані у вигляді yyyymm yyyymm

друкує висновок у вигляді числа_файлів з номером_обігу

  • збережено 2 байти: завдяки Коулу
  • збережено 8 байт: видалено небажані змінні
  • збережено 2 байти: зменшено t = 0; k = 0 як t = k = 0
  • збережено 2 байти: Завдяки Коулу (я цього раніше пропустив)
  • збережено 2 байти: Завдяки Keerthana
  • збережено 8 байт: видалено небажані змінні
  • збережено 3 байти: завдяки math_junkie (split ('') to split ())

1
Я думаю, що ви можете зменшити деякі байти, зробивши, n=intа також, можливо, трохи exectomfoolery.
cole

1
Я думаю, що можна зробити 2773&1<<r%12-1>0замістьint('101010110101'[r%12-1])
Loovjo

@Loovjo Я отримую помилку при цьому!
officialaimm

1
використовуючи print([k,t-k])як, print(k,t-k)що дасть бажаний результат, (k,g)тим самим зменшивши 2 байти!
Кеертана Прабхакаран

1
Я вважаю, що ви можете замінити split(' ')наsplit()
математика наркоман

3

Python 2 , 147 146 142 байт

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]

Спробуйте в Інтернеті!

  • Збережено 4 байти - Дякуємо @math_junkie за те, що він запропонував пункт if-else з пошуком масиву!

Розбивши код,

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]

1
Ви можете зберегти байти, замінивши if-elseпропозиції на пошукові масиви. Детальніше дивіться у цій публікації
математика-наркоман

Це був дійсно класний спосіб! Не знав цього раніше! Дякую!
Keerthana Prabhakaran

3

PHP, 120 103 97 96 байт

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

Бігайте так:

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

Пояснення

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.

Налаштування

  • Збережено 17 байт, використовуючи стиль часової мітки замість стилю об’єкта DateTime
  • Збережено 6 байт, не призначаючи змінну часової дати кінцевої дати $e, просто порівняйте безпосередньо
  • Збережено 1 байт, не зберігаючи кількість канавок, а просто обчисливши його після циклу

$x++замість +$x++також працює.
Тит

@Titus, у мене було , що на перший, але зрозумів , що з $xнеініціалізованих рядок буде 2017-12month, що непізнаний формат і результати в 1970
aross

Злий ... десь працював. Досить зла, хоча це працює без буквального +в рядку.
Тит

2

PowerShell , 96 байт

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

Спробуйте в Інтернеті!

Приймає інформацію як форму 2017-03. Використання вбудованої бібліотеки .NET дати і петлі через з входів $aв $bкожній ітерації збільшення $x++і додаванні , $zякщо струм .Monthє -in 2,4,6,9,11(тобто, не-31-денний місяці). Тоді ми виводимо загальні місяці за мінусом 31-денних місяців $x-$zта не-31-денних місяців $z.

Кидає помилку на 0001-01в 9999-12разі перевірки, оскільки в .NET підтримує років тільки до 9999, так кінцевих .AddMonths(1)причин переповнення. Але все-таки виводить правильні значення, оскільки це непостійна помилка; це просто викликає вихід циклу.

Можливо, це було б коротше, щоб це зробити арифметично, як відповіді Python або JavaScript, але я хотів показати підхід, використовуючи вбудовані .NET.


2

Баш , 113 байт

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

Спробуйте в Інтернеті!

потребує гольфу ...

приймає введення як 2016-03 2018-10

Виходи:

  1 28
  7 30
 12 31

неозорений:

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

1

Свіфт, 151 байт

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 - це масив з двох цілих чисел у форматі, як показано в прикладі

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.