Parmak eklemlerini sayarak tam 31 gününüzün kaç ay olduğunu sayın


12

Bir ayın 31 gün veya daha kısa bir süreye sahip olup olmadığını belirlemek için hala kendi ekleminizi kullanan kaçınız?

İşiniz, bir ay aralığında kaç ayın, tam 31 gününüzün ve kaçının "eklemleri sayarak" 31 günden az sürdüğünü saymak için bir program yazmaktır.

Mafsallarla ayın günlerini sayma

Nezaket: amsi.org.au


Giriş

İlki herhangi bir uygun formatta verilen ikincisinden önce kronolojik olarak gelmek zorunda olmayan bir çift ay. Örneğin: 201703 201902- Mart 2017 - Şubat 2019. Lütfen seçtiğiniz giriş biçimini açıklayın. Girdinin 1 ile 9999 arasındaki tüm yılları içermesi gerektiğini unutmayın. Belirtilen ay aralığı hem başlangıç ​​hem de bitiş aylarını içerir.

Çıktı

İki tamsayı: 31 gün ile verilen aralıktaki ay sayısı ve 31 günden az olan aralıktaki ay sayısı.

Örnek: 14 10- 14 parmak eklemi, 10 oluk (bu ay aralığında tam 31 gün ve 14 ayın 31 günden az olduğu anlamına gelir).

Aralıktaki ikinci ayın kronolojik olarak birinciden önce geldiği bir girdi için, örneğin 201612 201611 , bir çift sıfır vermeniz gerekir.

Giriş ve çıkış örnekleri

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

kurallar

  • İstediğiniz herhangi bir dili seçebilirsiniz
  • Her satıra bir giriş
  • Bu , bayt en kısa kod kazanır!
  • Kazanan 9 Nisan'da seçilecek
  • Standart boşluklar geçerlidir
  • Not: Bu PCG'deki ilk sorum, bazı tutarsızlıklar olabilir. Sizin için belirsiz olan şeyleri düzenlemek ve onaylamaktan çekinmeyin.

5
Birincisinin ikincisinden önce kronolojik olarak geleceğini garanti edersiniz , ancak bu test durumu için yanlıştır 201612 201611.
Dennis

2
Sitede , tüm şüpheleri gidermek için sadece soruyu gönderebileceğiniz bir sanal alan var .
ghosts_in_the_code

1
Otuz gün Eylül, Nisan, Haziran ve Kasım aylarıdır. Şubat ayının bitiminden sonra, geri kalanların otuz bir tane var. Ben böyle hatırlıyorum.
AdmBorkBork

@AdmBorkBork Bununla ilgili tek sorun sonsuz döngüdür (zorunlu xkcd referansı).
wizzwizz4

Tarih aralığında Gregoryen takvimini kullanmayı düşündüğünüzü sanıyorum?
sonraki duyuruya kadar duraklatıldı.

Yanıtlar:


7

Jöle , 21 bayt

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

Gibi girdi alır [[y, m], [y, m]].

Çevrimiçi deneyin!

Nasıl çalışır

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

Girdi yyyymmbiçiminde sözdiziminde iki tamsayı olarak alır (a)(b). İki tamsayı dizisi çıkarır [knuckles, grooves].

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

Biçimlendirilmiş ve yorumlanmış

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)

Test senaryoları

Not : Üçüncü test durumu bu snippet'e dahil değildir, çünkü tarayıcınızda Kuyruk Çağrısı Optimizasyonu etkin olmadığı sürece çalışmaz.


5

Python 2 , 92 90 86 80 bayt

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

Çevrimiçi deneyin!

Fikir için @math_junkie sayesinde bir lambda dönüştürerek 6 tane daha. Şimdi iki sayıyı içeren bir liste çıkarır.

Önceki lambda olmayan sürüm (86 bayt)

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

Çevrimiçi eski deneyin!

2 kurtulmak için @ovs sayesinde kurtardı len(k). Kullanmayı düşünmemiştimNone .

Girdi, biçimdeki tamsayıların bir listesidir y1,m1,y2,m2

Biraz bin(2741)[2:]önce @KeerthanaPrabhakaran nedeniyle ben var ikili kod sabit üzerinden kodlama üzerinde 1 bayt tasarruf nedeniyle kredi .


Etkileyici ... k = bin (2741) [2:] * (c + 1-a) aklımı patladı
officialaimm

1
Bu 2 bayt daha kısa
ovs

Parlak! Ondan kurtulmak için çapa yapmaya çalışıyordumlen(k)Son dilimden . Teşekkürler.
ElPedro

1
Lambda: TIO kullanarak 6 bayt tasarruf edebilirsiniz
math junkie

4

PHP , 259 256 249 248 237 221 bayt

Aros tarafından geride bırakıldı : https://codegolf.stackexchange.com/a/114512/38505

Giriş Formatı: 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;

Çevrimiçi deneyin!


eski versiyonlar

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

Çevrimiçi deneyin!

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

Çevrimiçi deneyin!

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

Çevrimiçi deneyin!

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

Çevrimiçi deneyin!

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

Çevrimiçi deneyin!


3

Toplu, 93 bayt

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

İki parametreyi ymm biçiminde kabul eder (örn. 101 - 999912). Önceki 129 bayt döngü tabanlı çözüm:

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

Muhtemelen tamsayı boyutu sınırı nedeniyle 000101 999912 için yanlış sonuç?
officialaimm

1
@officialaimm Yanlış giriş biçimi, özür dilerim - yıl başında sıfır olmamalıdır.
Neil

3

Piton 3,5 ( 164 162 154 152 150 148 140 137 bayt)

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 şeklinde girdi alır yyyymm

çıktıyı sayı_o_kökü sayısı olarak yazdırır

  • 2 bayt kaydedildi: Cole sayesinde
  • 8 bayt kaydedildi: istenmeyen değişkenler kaldırıldı
  • 2 bayt kaydedildi: azaltılmış t = 0; k = 0, t = k = 0 olarak
  • 2 bayt kurtardı: Cole sayesinde (Daha önce kaçırmıştım)
  • 2 bayt kurtardı: Keerthana sayesinde
  • 8 bayt kaydedildi: istenmeyen değişkenler kaldırıldı
  • 3 bayt kaydedildi: Teşekkür etmek math_junkie (bölünmeye bölünmüş (' ') ())

1
Sanırım bazı baytları n=intve belki de bazı exectomrukları azaltabilirsiniz .
Cole

1
Bence sen 2773&1<<r%12-1>0yerine yapabilirsinint('101010110101'[r%12-1])
Loovjo

@Loovjo Bunu yaparken hata alıyorum!
officialaimm

1
kullanılarak print([k,t-k])olarak print(k,t-k)arzu edilen bir sonuç ortaya (k,g)böylece 2 bayt azaltılması!
Keerthana Prabhakaran

1
Ben değiştirmek inanıyorum split(' ')ilesplit()
matematik bağımlısı

3

Python 2 , 147 146 142 bayt

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]

Çevrimiçi deneyin!

  • 4 bayt kaydedildi - dizi arama ile if-else cümlesi önerdiği için @math_junkie teşekkürler!

Kodu yıkmak,

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
Yan if-elsetümceleri dizi aramalarıyla değiştirerek bayt kaydedebilirsiniz . Ayrıntılar için bu
gönderiye

Gerçekten harika bir yoldu! Daha önce bilmiyordum! Teşekkürler!
Keerthana Prabhakaran

3

PHP 120 103 97 96 bayt

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

Şu şekilde çalıştırın:

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

açıklama

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.

Düzenlemeler

  • DateTime nesne stili yerine zaman damgası stili kullanılarak 17 bayt kaydedildi
  • Değişkene bitiş tarihi zaman damgası atamayarak 6 bayt kaydedildi $e, sadece doğrudan karşılaştırın
  • Oluk sayısını koruyarak değil, sadece döngüden sonra hesaplayarak 1 bayt tasarruf

$x++yerine +$x++çalışır.
Titus

@Titus, ilk başta bunu yaptım, ancak ilklendirilmeden $xdizenin 2017-12monthtanınmayan bir biçim olduğunu ve 1970'de sonuçlanacağını fark ettim.
aross

Kötü ... bir yerde çalıştı. Dizede bir değişmez olmadan çalışmasına rağmen yeterince kötü +.
Titus

2

PowerShell , 96 bayt

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

Çevrimiçi deneyin!

Girişi form olarak alır 2017-03. Kullanımları yerleşik .NET tarih kütüphaneler ve içinden girişlerine gelen döngüler $aiçin $b, her yineleme artırma $x++ve ekleyerek $zakım halinde .Montholduğu -in 2,4,6,9,11(yani olmayan bir 31 günlük ay). Sonra toplam aylarımızı eksi 31 günlük $x-$zolmayan aylar ve 31 günlük olmayan aylar çıkarırız $z.

.NET yalnızca yıllara kadar desteklediği 0001-01için 9999-12test durumunda bir hata alır 9999, bu nedenle son.AddMonths(1) durum taşmaya neden olur. Yine de doğru değerleri verir, çünkü bu sonlandırılamayan bir hatadır; sadece döngünün çıkmasına neden olur.

Muhtemelen bunu Python veya JavaScript cevapları gibi aritmetik olarak yapmak daha kısa olurdu, ancak .NET yerleşiklerini kullanarak bir yaklaşım göstermek istedim.


2

darbe , 113 bayt

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

Çevrimiçi deneyin!

golf ihtiyacı var ...

girişi alır 2016-03 2018-10

çıktılar:

  1 28
  7 30
 12 31

ungolfed:

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

Swift, 151 bayt

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, örneğe göre biçimdeki iki tamsayıdan oluşan bir dizidir

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.