Đếm xem có bao nhiêu tháng có đủ 31 ngày bằng cách đếm đốt ngón tay


11

Có bao nhiêu bạn vẫn sử dụng đốt ngón tay của chính mình để xác định xem một tháng có đủ 31 ngày hay ít hơn không?

Công việc của bạn là viết một chương trình để đếm bao nhiêu tháng, trong một tháng, có đủ 31 ngày và bao nhiêu ngày có ít hơn 31 ngày bằng cách "đếm số đốt ngón tay".

Đếm số ngày trong tháng bằng đốt ngón tay

Lịch sự: amsi.org.au


Đầu vào

Một vài tháng, lần đầu tiên không phải theo thứ tự thời gian trước lần thứ hai, được đưa ra trong bất kỳ định dạng phù hợp. Ví dụ: 201703 201902- Tháng 3 năm 2017 đến tháng 2 năm 2019. Vui lòng mô tả định dạng đầu vào bạn chọn. Lưu ý rằng đầu vào phải có thể bao gồm tất cả các năm từ 1 đến 9999. Phạm vi tháng được chỉ định bao gồm cả tháng bắt đầu và tháng kết thúc.

Đầu ra

Hai số nguyên: số tháng trong phạm vi đã cho với 31 ngày và số tháng trong phạm vi có ít hơn 31 ngày.

Ví dụ: 14 10- 14 đốt ngón tay, 10 rãnh (có nghĩa là trong phạm vi tháng đó, chúng tôi có 14 tháng có đủ 31 ngày và 10 tháng có ít hơn 31 ngày).

Ví dụ, đối với đầu vào trong đó tháng thứ hai trong phạm vi xuất hiện theo thứ tự thời gian trước lần đầu tiên 201612 201611, bạn phải xuất một cặp số không.

Ví dụ về đầu vào và đầu ra

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

Quy tắc

  • Bạn có thể chọn bất kỳ ngôn ngữ nào bạn thích
  • Một đầu vào trên mỗi dòng
  • Đây là , vì vậy mã ngắn nhất tính bằng byte sẽ thắng!
  • Người chiến thắng sẽ được chọn vào ngày 9 tháng 4
  • Áp dụng sơ hở tiêu chuẩn
  • PS: đây là câu hỏi đầu tiên của tôi trong PCG, nó có thể có một số mâu thuẫn. Hãy chỉnh sửa và xác nhận những gì không rõ ràng cho bạn.

5
Bạn nói rằng cái đầu tiên được đảm bảo theo thứ tự thời gian trước cái thứ hai , nhưng điều này là sai cho trường hợp thử nghiệm 201612 201611.
Dennis

2
Có tồn tại một hộp cát trên trang web nơi bạn có thể đăng câu hỏi chỉ để xóa tất cả các nghi ngờ.
ghosts_in_the_code 30/03/2017

1
Ba mươi ngày có tháng chín, tháng tư, tháng sáu và tháng mười một. Sau khi xong tháng hai, tất cả những người còn lại có ba mươi mốt. Đó là cách tôi nhớ nó.
admBorkBork 30/03/2017

@AdmBorkBork Vấn đề duy nhất với điều đó là vòng lặp vô hạn (tham chiếu xkcd bắt buộc).
wizzwizz4

Tôi đoán bạn có ý định sử dụng lịch Gregorian trong suốt phạm vi ngày?
Tạm dừng cho đến khi có thông báo mới.

Câu trả lời:


7

Thạch , 21 byte

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

Đưa đầu vào như thế nào [[y, m], [y, m]].

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

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

Lấy đầu vào là hai số nguyên trong yyyymmđịnh dạng, theo cú pháp currying (a)(b). Xuất ra một mảng gồm hai số nguyên [knuckles, grooves].

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

Định dạng và nhận xét

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)

Các trường hợp thử nghiệm

Lưu ý : Trường hợp thử nghiệm thứ ba không được bao gồm trong đoạn trích này, vì nó sẽ không hoạt động trừ khi trình duyệt của bạn đã bật Tối ưu hóa cuộc gọi.


5

Python 2 , 92 90 86 80 byte

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

Hãy thử trực tuyến!

Thêm 6 bằng cách chuyển đổi sang lambda, với lời cảm ơn @math_junkie cho ý tưởng. Bây giờ xuất ra một danh sách chứa hai số.

Phiên bản không phải lambda trước đó (86 byte)

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

Hãy thử trực tuyến cũ!

2 lưu với lời cảm ơn @ovs đã giúp tôi thoát khỏi len(k). Tôi đã không nghĩ về việc sử dụng None.

Đầu vào là danh sách các số nguyên ở định dạng y1,m1,y2,m2

Một số tín dụng do @KeerthanaPrabhakaran đã nhận được bin(2741)[2:]trước khi tôi thực hiện giúp tiết kiệm 1 byte so với mã hóa chuỗi nhị phân cứng.


Ấn tượng ... k = bin (2741) [2:] * (c + 1-a) đã thổi vào tâm trí tôi
chính thức tuyên bố

1
Đây là 2 byte ngắn hơn
ovs 30/03/2017

Xuất sắc! Tôi đã cố gắng tập cuốc để thoát khỏi len(k)miếng bánh cuối cùng. Cảm ơn.
ElPedro

1
Bạn có thể lưu 6 byte bằng cách sử dụng lambda: TIO
nghiện toán học

4

PHP , 259 256 249 248 237 221 byte

Bị ruồng bỏ bởi aross : /codegolf//a/114512/38505

Định dạng đầu vào: 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;

Hãy thử trực tuyến!


Các phiên bản cũ hơn

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

Hãy thử trực tuyến!

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

Hãy thử trực tuyến!

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

Hãy thử trực tuyến!

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

Hãy thử trực tuyến!

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

Hãy thử trực tuyến!


3

Mẻ, 93 byte

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

Chấp nhận hai tham số ở định dạng ymm (tức là 101 - 999912). Giải pháp dựa trên vòng lặp 129 byte trước đây:

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

Kết quả không chính xác cho 000101 999912, có lẽ do giới hạn kích thước số nguyên?
chính thức tuyên bố

1
@officialaimm Định dạng nhập sai, xin lỗi - năm không nên có số 0 đứng đầu.
Neil

3

Python 3.5 ( 164 162 154 152 150 148 140 137 byte)

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)

thay thế

lấy đầu vào dưới dạng yyyymm yyyymm

in đầu ra dưới dạng number_of_knuckles number_of_groove

  • đã lưu 2 byte: Nhờ Cole
  • đã lưu 8 byte: loại bỏ các biến không mong muốn
  • đã lưu 2 byte: giảm t = 0; k = 0 là t = k = 0
  • đã lưu 2 byte: Cảm ơn Cole (tôi đã bỏ lỡ điều này trước đây)
  • đã lưu 2 byte: Nhờ Keerthana
  • đã lưu 8 byte: loại bỏ các biến không mong muốn
  • đã lưu 3 byte: Nhờ math_junkie (split ('') để split ())

1
Tôi nghĩ rằng bạn có thể giảm một số byte bằng cách thực hiện n=intvà có lẽ một số exectomfoolery.
cole

1
Tôi nghĩ bạn có thể làm 2773&1<<r%12-1>0thay vìint('101010110101'[r%12-1])
Loovjo 30/03/2017

@Loovjo Tôi đang gặp lỗi khi làm như vậy!
chính thức tuyên bố

1
sử dụng print([k,t-k])như print(k,t-k)sẽ tạo ra kết quả mong muốn (k,g)do đó giảm 2 byte!
Keerthana Mitchhakaran

1
Tôi tin rằng bạn có thể thay thế split(' ')bằngsplit()
nghiện toán học

3

Python 2 , 147 146 142 byte

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]

Hãy thử trực tuyến!

  • Đã lưu 4 byte - Cảm ơn @math_junkie đã gợi ý mệnh đề if-other với tra cứu mảng!

Phá vỡ mã,

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
Bạn có thể lưu byte bằng cách thay thế các if-elsemệnh đề bằng tra cứu mảng. Xem bài đăng này để biết chi tiết
nghiện toán học

Đó thực sự là một cách tuyệt vời! Không biết điều đó trước đây! Cảm ơn!
Keerthana Mitchhakaran

3

PHP, 120 103 97 96 byte

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

Chạy như thế này:

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

Giải trình

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.

Tinh chỉnh

  • Đã lưu 17 byte bằng cách sử dụng kiểu dấu thời gian thay vì kiểu đối tượng DateTime
  • Đã lưu 6 byte bằng cách không gán dấu thời gian ngày kết thúc cho biến $e, chỉ cần so sánh trực tiếp
  • Đã lưu 1 byte bằng cách không giữ số rãnh, nhưng chỉ tính toán nó sau vòng lặp

$x++thay vì +$x++cũng hoạt động.
Tít

@Titus, tôi đã có đến nỗi lúc đầu, nhưng nhận ra rằng với $xuninitialized chuỗi sẽ 2017-12month, mà là một định dạng và kết quả không được công nhận vào năm 1970
aross

Ác ... nó làm việc ở đâu đó. Đủ độc ác mặc dù nó hoạt động mà không có một nghĩa đen +trong chuỗi.
Tít

2

PowerShell , 96 byte

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

Hãy thử trực tuyến!

Lấy đầu vào dưới dạng 2017-03. Sử dụng các thư viện ngày .NET tích hợp và các vòng lặp từ đầu vào $ađến $b, mỗi lần lặp tăng dần $x++và thêm vào $znếu hiện tại .Month-in 2,4,6,9,11(tức là một tháng không phải là 31 ngày). Sau đó, chúng tôi sản xuất tổng số tháng của chúng tôi trừ đi các tháng không phải là 31 ngày $x-$zvà các tháng không phải là 31 ngày $z.

Tung một lỗi trên 0001-01để 9999-12kiểm tra trường hợp, vì .NET chỉ hỗ trợ năm lên đến 9999, vì vậy trận chung kết .AddMonths(1)nguyên nhân một tràn. Tuy nhiên, vẫn đưa ra các giá trị chính xác bởi vì đó là lỗi không kết thúc; nó chỉ làm cho vòng lặp thoát ra.

Có lẽ sẽ ngắn hơn để làm điều này một cách hợp lý, như câu trả lời của Python hoặc JavaScript, nhưng tôi muốn hiển thị một cách tiếp cận bằng cách sử dụng .NET dựng sẵn.


2

Bash , 113 byte

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

Hãy thử trực tuyến!

cần chơi gôn ...

lấy đầu vào là 2016-03 2018-10

đầu ra:

  1 28
  7 30
 12 31

vô dụng:

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 byte

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}

đầu vào là một mảng gồm hai số nguyên theo định dạng theo ví dụ

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.