นับจำนวนเดือนที่มี 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แต่นี้เป็นเท็จกรณีทดสอบ
Dennis

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)

กรณีทดสอบ

หมายเหตุ : กรณีทดสอบที่สามไม่รวมอยู่ในตัวอย่างนี้เพราะมันจะไม่ทำงานยกเว้นว่าเบราว์เซอร์ของคุณเปิดใช้งานการเพิ่มประสิทธิภาพการโทรหาง


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 ไบต์ในการเข้ารหัสสตริงไบนารี่อย่างหนัก


น่าประทับใจ ... k = bin (2741) [2:] * (c + 1-a) พัดใจ
Officialaimm

1
นี่คือ 2 ไบต์ที่สั้นกว่า
ovs

ยอดเยี่ยม! ฉันพยายามที่จะกำจัดจอบเพื่อกำจัดlen(k)ชิ้นส่วนสุดท้าย ขอบคุณ
ElPedro

1
คุณสามารถบันทึกได้ 6 ไบต์โดยใช้แลมบ์ดา: TIO
math junkie

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 อาจเป็นเพราะการ จำกัด ขนาดจำนวนเต็มหรือไม่
อย่างเป็นทางการ

1
@officialaimm รูปแบบการป้อนที่ไม่ถูกต้องขออภัยปีที่ไม่ควรมีศูนย์นำหน้า
Neil

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

พิมพ์เอาต์พุตเป็นnumber_of_knuckles number_of_grooves

  • บันทึก 2 ไบต์:ขอบคุณCole
  • บันทึกแล้ว 8 ไบต์:นำตัวแปรที่ไม่ต้องการออก
  • บันทึกแล้ว 2 ไบต์:ลดลง t = 0; k = 0 เป็น t = k = 0
  • บันทึก 2 ไบต์:ขอบคุณ Cole (ฉันเคยคิดถึงเรื่องนี้มาก่อน)
  • บันทึก 2 ไบต์:ขอบคุณKeerthana
  • บันทึกแล้ว 8 ไบต์:นำตัวแปรที่ไม่ต้องการออก
  • บันทึกแล้ว 3 ไบต์:ขอบคุณmath_junkie (แยก ('') เพื่อแยก ())

1
ฉันคิดว่าคุณสามารถลดจำนวนไบต์ได้ด้วยการทำn=intและอาจเป็นexecโรงเก็บปืน
โคล

1
ฉันคิดว่าคุณสามารถทำได้2773&1<<r%12-1>0แทนint('101010110101'[r%12-1])
Loovjo

@ Loovjo ฉันได้รับข้อผิดพลาดในการทำเช่นนั้น!
อย่างเป็นทางการ

1
ใช้print([k,t-k])ตามที่print(k,t-k)ต้องการจะให้ผลลัพธ์ที่ต้องการ(k,g)ซึ่งจะช่วยลด 2 ไบต์!
กีรนาปราการะรัน

1
ฉันเชื่อว่าคุณสามารถแทนที่split(' ')ด้วยsplit()
คณิตศาสตร์ junkie

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ข้อด้วยการค้นหาอาร์เรย์ ดูโพสต์นี้สำหรับรายละเอียด
คณิตศาสตร์ junkie

นั่นเป็นวิธีที่ยอดเยี่ยมจริงๆ! ไม่เคยรู้มาก่อน! ขอบคุณ!
กีรนาปราการะรัน

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


2

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

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 ไบต์

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 เป็นอาร์เรย์ของจำนวนเต็มสองจำนวนในรูปแบบตามตัวอย่าง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.