นับถอยหลังวันทำงาน


17

ฉันแค่มีความคิดอัจฉริยะที่ทำให้ชีวิตการทำงานง่ายขึ้น - นับถอยหลังสู่วันที่ระบุซึ่งนับเฉพาะวันทำงาน


ภารกิจพื้นฐานคือการสร้างการนับถอยหลังถึงวันที่ระบุซึ่งรวมเฉพาะวันทำงานในการนับถอยหลัง

ในฐานะที่นับวันทำงานจันทร์ , อังคาร , พุธ , พฤหัสบดีและศุกร์

อินพุตควรเป็นวันที่ที่ระบุในรูปแบบมาตรฐานยุโรป "ไม่เป็นทางการ" dd.MM.yyyyและต้องเป็นวันนี้หรือวันในอนาคต

ผลลัพธ์ควรเป็นจำนวนวันที่เหลืออยู่เท่านั้น

ในขณะที่มันเป็นรหัสที่สั้นที่สุดชนะ


กรณีทดสอบ:

  Today    |   Input    | Output
10.12.2018 | 17.12.2018 |    5
02.10.2018 | 16.10.2018 |   10

หากฉันพลาดบางสิ่งในคำถามโปรดยกโทษให้ฉัน - เป็นคำถามแรกของฉัน :)

แก้ไข:

  • คุณสามารถใช้falseเป็นเอาต์พุตแทนที่จะเป็น0 <- แต่ไม่สวย
  • ไม่จำเป็นต้องเคารพ DST

9
มีเหตุผลใดที่อยู่เบื้องหลังรูปแบบอินพุตแบบ"ไม่เป็นทางการ" ของยุโรปหรือไม่ ฉันทามติของเราคืออนุญาตให้มีการป้อนข้อมูลที่ยืดหยุ่นเมื่อทำได้
Arnauld

6
มีจุดใดในการเพิ่ม "ความท้าทายพิเศษ" ของรูปแบบวันที่ยากต่อการประมวลผลหรือไม่ ดูเหมือนว่าภาษา wrt ที่ไม่เป็นธรรมซึ่งมีรูปแบบวันที่ที่ยืดหยุ่น ...
Quintec

3
@Hille ฉันไม่ได้บอกว่ามันเป็น "ยาก" มันเป็นเพียงการรบกวนที่ไม่จำเป็นโดยเฉพาะอย่างยิ่งในรหัสกอล์ฟ ... โปรดทราบลิงค์ที่ Arnauld โพสต์ข้างต้น ... โดยทั่วไปการป้อนข้อมูลที่มีความยืดหยุ่นเป็นบรรทัดฐาน ...
Quintec

6
อย่างไรก็ตามคุณทราบว่านี่เป็นความท้าทายครั้งแรกของคุณ ฉันขอเชิญคุณใช้The Sandboxสำหรับการปรับแต่งก่อนโพสต์ความท้าทายไปยังหน้าหลัก! มิฉะนั้นเป็นงานที่ดีและฉันจะได้เห็นบางอย่างจากคุณ!
Giuseppe

7
ไม่ประทับใจกับรูปแบบการป้อนข้อมูลที่เข้มงวด แต่นอกเหนือจากความท้าทายที่ดี
ElPedro

คำตอบ:


18

05AB1E , 130 128 133 131 124 123 ไบต์

žežfžg)V0[Y`UÐ3‹12*+>13*5÷s3‹Xα©т%D4÷®т÷©4÷®·()ćsO7%2@+Y`т‰0Kθ4ÖUD2Qi\28X+ë<7%É31α}‹iY¬>0ëY1¾ǝDÅsD12‹i>1ë\1Dǝ¤>2}}ǝVYI'.¡Q#

ฉันออกไปจากใจ ..

สำหรับภาษากอล์ฟ 05AB1E มันไม่สำคัญเลยไม่ว่าจะเป็นการป้อนข้อมูลด้วย.หรือ-หรืออย่างไรก็ตาม 05AB1E ไม่มี builtins สำหรับวัตถุหรือการคำนวณ Date builtin เพียงอย่างเดียวเกี่ยวกับวันที่มีคือวันนี้ปี / เดือน / วัน / ชั่วโมง / นาที / วินาที / microseconds

ด้วยเหตุนี้รหัสเกือบทั้งหมดที่คุณเห็นคือการคำนวณด้วยตนเองเพื่อไปยังวันถัดไปและการคำนวณวันในสัปดาห์

+5 ไบต์เนื่องจากส่วนหนึ่งฉันลืมสูตรของเซลเลอร์ (ปีที่ 1 สำหรับเดือนมกราคมและกุมภาพันธ์) ..

ลองออนไลน์หรือทดลองออนไลน์ด้วยวันที่กำหนดเองของ 'วันนี้''วันนี้'

คำอธิบาย:

กำแพงข้อความที่เข้ามา

โดยทั่วไปรหัสดังต่อไปนี้หลอกรหัส:

1   Date currentDate = today;
2   Integer counter = 0;
3   Start an infinite loop:
4*    If(currentDate is NOT a Saturday and currentDate is NOT a Sunday):
5       Counter += 1;
6*    currentDate += 1; // Set currentDate to the next day in line
7     If(currentDate == parsed input-string):
8       Stop the infinite loop, and output the counter

1) Date currentDate = today;เป็นส่วนหนึ่งของโปรแกรม 05AB1E นี้:

že          # Push today's day
  žf        # Push today's month
    žg      # Push today's year
      )     # Wrap them into a single list
       V    # Pop and store this list in variable `Y`

2) Integer counter = 0;และ 3) Start an infinite loop:ตรงไปตรงมาในโปรแกรม 05AB1E:

0     # Push 0 to the stack
 [    # Start an infinite loop

4) If(currentDate is NOT a Saturday and currentDate is NOT a Sunday):เป็นส่วนแรกที่มีการคำนวณด้วยตนเอง เนื่องจาก 05AB1E ไม่มีตัวสร้างวันที่เราจะต้องคำนวณวันในสัปดาห์ด้วยตนเอง

สูตรทั่วไปในการทำเช่นนี้คือ:

h=(q+13(m+1)5+K+K4+J42J)mod7,

เดือนมีนาคมถึงเดือนธันวาคม:

  • qคือdayของเดือน ([1, 31])
  • mคือดัชนี 1 ดัชนีmonth ([3, 12])
  • Kคือปีแห่งศตวรรษ (yearmod100 )
  • Jคือศตวรรษที่จัดทำดัชนี 0 (year100)

และสำหรับเดือนมกราคมและกุมภาพันธ์:

  • qคือdayของเดือน ([1, 31])
  • mคือดัชนี 1month+12 ([13, 14])
  • Kเป็นปีของศตวรรษที่สำหรับปีที่ผ่านมา (คน(year1)mod100 )
  • Jคือศตวรรษที่จัดทำดัชนี 0 สำหรับปีที่แล้ว (year1100)

ส่งผลให้ในวันของสัปดาห์h , โดยที่ 0 = วันเสาร์, 1 = วันอาทิตย์, ... , 6 = วันศุกร์
ที่มา: ความสอดคล้องของ Zeller

เราสามารถเห็นสิ่งนี้ได้ในโปรแกรม 05AB1E นี้:

Y             # Push variable `Y`
 `            # Push the day, month, and year to the stack
  U           # Pop and save the year in variable `X`
   Ð          # Triplicate the month
    3        # Check if the month is below 3 (Jan. / Feb.),
              # resulting in 1 or 0 for truthy/falsey respectively
      12*     # Multiply this by 12 (either 0 or 12)
         +    # And add it to the month
              # This first part was to make Jan. / Feb. 13 and 14

>             # Month + 1
 13*          # Multiplied by 13
    5÷        # Integer-divided by 5
s3           # Check if the month is below 3 again (resulting in 1 / 0)
   Xα         # Take the absolute difference with the year
     ©        # Store this potentially modified year in the register
      т%      # mYear modulo-100
D4÷           # mYear modulo-100, integer-divided by 4
®т÷©4÷        # mYear integer-divided by 100, and then integer-divided by 4
®·(           # mYear integer-divided by 100, doubled, and then made negative
)             # Wrap the entire stack into a list
 ć            # Extract the head (the counter variable that was also on the stack)
  s           # Swap so the calculated values above are as list at the top
   O          # Take the sum of this entire list
    7%        # And then take modulo-7 to complete the formula,
              # resulting in 0 for Saturday, 1 for Sunday, and [2, 6] for [Monday, Friday]

2@            # Check if the day is greater than or equal to 2 (so a working day)

5) Counter += 1;ตรงไปข้างหน้าอีกครั้ง:

     # The >=2 check with `2@` results in either 1 for truthy and 0 for falsey
+    # So just adding it to the counter variable is enough

6) currentDate += 1; // Set currentDate to the next day in lineมีความซับซ้อนมากกว่าเดิมเพราะเราต้องทำด้วยตนเอง ดังนั้นสิ่งนี้จะถูกขยายเป็นโค้ดหลอกต่อไปนี้:

a   Integer isLeapYear = ...;
b   Integer daysInCurrentMonth = currentDate.month == 2 ?
c                                 28 + isLeapYear
d                                :
e                                 31 - (currentDate.month - 1) % 7 % 2;
f   If(currentDate.day < daysInCurrentMonth):
g     nextDate.day += 1;
h   Else:
i     nextDate.day = 1;
j     If(currentDate.month < 12):
k       nextDate.month += 1;
l     Else:
m       nextDate.month = 1;
n       nextDate.year += 1;

แหล่งที่มา:
อัลกอริทึมสำหรับการพิจารณาว่าปีเป็นปีอธิกสุรทินหรือไม่ (แก้ไข: ไม่มีความเกี่ยวข้องอีกต่อไปเนื่องจากฉันใช้วิธีการทางเลือกเพื่อตรวจสอบปีอธิกสุรทินซึ่งบันทึกได้ 7 ไบต์)
อัลกอริทึมสำหรับกำหนดจำนวนวันในหนึ่งเดือน

6a) Integer isLeapYear = ...;ทำสิ่งนี้ในโปรแกรม 05AB1E:

Y             # Push variable `Y`
 `            # Push the days, month and year to the stack
  т‰          # Divmod the year by 100
    0K        # Remove all items "00" (or 0 when the year is below 100)
      θ       # Pop the list, and leave the last item
       4Ö     # Check if this number is visible by 4
         U    # Pop and save the result in variable `X`

นอกจากนี้ยังใช้ในคำตอบ 05AB1E ของฉันด้วยดังนั้นจึงมีการเพิ่มตัวอย่างบางปีเพื่อแสดงขั้นตอน

6b) currentDate.month == 2 ?และ 6c) 28 + isLeapYearทำเช่นนี้:

D            # Duplicate the month that is now the top of the stack
 2Q          # Check if it's equal to 2
   i         # And if it is:
    \        #  Remove the duplicated month from the top of the stack
     28X+    #  Add 28 and variable `X` (the isLeapYear) together

6d) :และ 6e) 31 - (currentDate.month - 1) % 7 % 2;ทำเช่นนี้:

ë           # Else:
 <          #  Month - 1
  7%        #  Modulo-7
    É       #  Is odd (shortcut for %2)
     31     #  Push 31
       α    #  Absolute difference between both
}           # Close the if-else

6f) If(currentDate.day < daysInCurrentMonth):ทำดังนี้:

     # Check if the day that is still on the stack is smaller than the value calculated
 i    # And if it is:

6g) nextDate.day += 1;ทำเช่นนี้:

Y       # Push variable `Y`
 ¬      # Push its head, the days (without popping the list `Y`)
  >     # Day + 1
   0    # Push index 0

        # (This part is done after the if-else clauses to save bytes)
}}      # Close the if-else clauses
  ǝ     # Insert the day + 1 at index 0 in the list `Y`
   V    # Pop and store the updated list in variable `Y` again

6h) Else:และ 6i) nextDate.day = 1;ทำเช่นนี้แล้ว:

ë        # Else:
 Y       #  Push variable `Y`
  1      #  Push a 1
   ¾     #  Push index 0
    ǝ    #  Insert 1 at index 0 (days part) in the list `Y`

6j) If(currentDate.month < 12)::

D           # Duplicate the list `Y`
 Ås         # Pop and push its middle (the month)
   D12     # Check if the month is below 12
       i    # And if it is:

6k) nextDate.month += 1;:

>       # Month + 1
 1      # Push index 1

        # (This part is done after the if-else clauses to save bytes)
}}      # Close the if-else clauses
  ǝ     # Insert the month + 1 at index 1 in the list `Y`
   V    # Pop and store the updated list in variable `Y` again

6l) Else:, 6m) nextDate.month = 1;และ 6n) nextDate.year += 1;จะทำดังนี้:

ë        # Else:
 \       #  Delete the top item on the stack (the duplicated month)
  1      #  Push 1
   D     #  Push index 1 (with a Duplicate)
    ǝ    #  Insert 1 at index 1 (month part) in the list `Y`

 ¤       #  Push its tail, the year (without popping the list `Y`)
  >      #  Year + 1
   2     #  Index 2

         # (This part is done after the if-else clauses to save bytes)
}}       # Close the if-else clauses
  ǝ      # Insert the year + 1 at index 2 in the list `Y`
   V     # Pop and store the updated list in variable `Y` again

และสุดท้ายที่ 8) If(currentDate == parsed input-string):และ 9) Stop the infinite loop, and output the counter:

Y          # Push variable `Y`
 I         # Push the input
  '.¡     '# Split it on dots
     Q     # Check if the two lists are equal
      #    # And if they are equal: stop the infinite loop
           # (And output the top of the stack (the counter) implicitly)

5
คุณเป็นคนบ้า ... มีการโหวต
AdmBorkBork

1
โปรแกรม 05AB1E ที่ยาวที่สุด?
Luis Mendo

2
@ LuisMendo ปิด แต่ฉันเกรงว่าฉันมี05AB1E ตอบตัวเองที่ยาวกว่าและอีกอันที่ใกล้เกินไป .. ;) ฉันแน่ใจว่าฉันจะสามารถเล่นกอล์ฟได้ที่นี่ไม่กี่ไบต์และทำให้มันง่ายขึ้น ส่วนต่าง ๆ ของการนำรหัสหลอกไปใช้ในวันถัดไป จะมองพรุ่งนี้เช้า แต่เพิ่งกลับมาจากการเล่นกีฬาและจะเข้านอนเร็ว ๆ นี้
Kevin Cruijssen

11

Excel 24 ไบต์

ถือว่าอินพุตใน Cell A1

=NETWORKDAYS(NOW()+1,A1)

ใช้ฟังก์ชั่นในตัว น่าเสียดายที่ฟังก์ชั่นนี้มีทั้งวันนี้และวันที่สิ้นสุด OP ได้ชี้แจงไปแล้วว่าจะไม่นับในวันนี้ดังนั้นฉันจึงเพิ่มหนึ่งรายการเข้าไปในตอนนี้เพื่อไม่นับในวันนี้

ในการจัดการกับความคิดเห็นเกี่ยวกับรูปแบบของตัวเลขอีกครั้งนี่เป็นมาตรฐานของ Excel: enter image description here


แม้ว่าสิ่งนี้จะทำงานกับค่าวันที่ แต่ก็ไม่สามารถป้อนข้อมูลตามที่ระบุไว้ นั่นคือ (อย่างน้อยในเวอร์ชัน US) 10.12.2018เป็นสตริงเมื่อเก็บไว้ในเซลล์แทนที่จะเป็นวันที่ ที่เห็นได้ชัด แต่ยาวแก้ปัญหาในการแก้ไขปัญหานี้จะมีการเปลี่ยนแปลงA1ไปDATE(RIGHT(A1,4),MID(A1,4,2),LEFT(A1,2))ในการแก้ปัญหาของคุณ
เทย์เลอร์สกอตต์

โชคไม่ดีที่ชุมชนตัดสินใจว่าภาษาจะต้องทำงานภายใต้การตั้งค่าเริ่มต้นของพวกเขาให้ถูกต้อง (ข้อยกเว้นอย่างหนึ่งที่ฉันได้เห็นคือภาษา - IE หากภาษาของคุณรองรับทั้งภาษาอังกฤษและสเปนคุณอาจใช้อย่างง่ายดาย แต่ . นี้จะต้องระบุไว้) นอกจาก OP (@hille) ยังไม่ได้ระบุว่ารูปแบบที่มีความยืดหยุ่นและในความเป็นจริงที่ระบุไว้ค่อนข้างตรงข้าม (ดูความคิดเห็นที่สองกับคำถามนี้)
เทย์เลอร์สกอตต์

2
รูปแบบที่ไม่ได้มาตรฐานมันขึ้นอยู่กับสถานที่ Excel อ่านรูปแบบจากHKCU\Control Panel\International\sDecimalสตริงรีจิสตรี ตามค่าเริ่มต้นการติดตั้ง US Windows นั่นคือ MM / dd / yyyy ในประเทศในสหภาพยุโรปส่วนใหญ่จะเป็นค่าเริ่มต้น
Erik A

@luisMendo ใช่มันใช้งานได้ ฉันไม่เห็นความกระจ่างใด ๆ หากไม่นับวันสุดท้ายแทนฉันสามารถมี = NETWORKDAYS (NOW (), A1-1) ฉันรู้ว่ามันคงเป็นจำนวนไบต์เดียวกันเสมอไม่ว่าจะชี้แจงอะไร
Keeta - คืนสถานะโมนิก้า

ดีใจที่ได้ผล ฉันลบ downvote
Luis Mendo

11

R , 76 ไบต์

โปรดดูคำตอบ 72 ไบต์ R ที่เป็นอิสระต่อภาษาด้วย

sum(!grepl("S",weekdays(seq(Sys.Date(),as.Date(scan(,""),"%d.%m.%Y"),1))))+1

ลองออนไลน์!

weekdaysให้วันที่เป็นข้อความในสัปดาห์ดังนั้นเราจึงนับจำนวนวันตามลำดับระหว่างวันนี้และอินพุตที่ไม่มีSและเพิ่มหนึ่งรายการลงในผลลัพธ์


8

Java 10, 233 232 226 ไบต์

import java.util.*;d->{int r=0;var s=Calendar.getInstance();s.setTime(new Date());var e=s.getInstance();for(e.setTime(new java.text.SimpleDateFormat("dd.MM.yyyy").parse(d));!s.after(e);s.add(5,1))if(s.get(7)%7>1)r++;return r;}

Date มักทำให้ฉันนึกถึงว่า verbose Java เป็นอย่างไร ..

หมายเหตุ: ขณะนี้มีคำตอบสั้น ๆ ของ Java สองคำ (ต่ำกว่า 175 ไบต์) หนึ่งเดียวที่ใช้วิธีเลิกใช้อย่างชาญฉลาดจาก Java เวอร์ชันก่อนหน้าโดย@LukeStevensและอีกวิธีหนึ่งคือใช้java.time.LocalDateใหม่ตั้งแต่ Java 8โดย@ OlivierGrégoire @

ลองออนไลน์

คำอธิบาย:

import java.util.*;            // Required import for both Calendar and Date
d->{                           // Method with String parameter and integer return-type
  int r=0;                     //  Result-integer, starting at 0
  var s=Calendar.getInstance();//  Create a Calendar instance for the start-date
  s.setTime(new Date());       //  Set the start date to today
  var e=s.getInstance();       //  Create a Calendar instance for the end-date
  for(e.setTime(               //  Set the end date to:
        new java.text.SimpleDateFormat("dd.MM.yyyy")
                               //   Create a formatter for the "dd.MM.yyyy" format
         .parse(d));           //   And parse the input-String to a Date
      !s.after(e)              //  Loop as long as we haven't reached the end date yet
      ;                        //    After every iteration:
       s.add(5,1))             //     Increase the start-date by 1 day
    if(s.get(7)%7>1)           //   If the day of the week is NOT a Saturday or Sunday:
                               //   (SUNDAY = 1, MONDAY = 2, ..., SATURDAY = 7)
      r++;                     //    Increase the result-sum by 1
  return r;}                   //  Return the result-sum

คุณสามารถทำe=s.clone()อะไร
Quintec

1
นอกจากนี้เรายังสามารถ (ฉันสมมติ) ทำCalendar s=Calendar.getInstance(),e=s.getInstance()ซึ่งน่าเสียดายที่กลายเป็นความยาวเดียวกัน
Misha Lavrov

1
@MishaLavrov Ah คงCไม่จำเป็นแน่นอน มันมาจากส่วนเก่าของรหัสที่ฉันยังใช้ที่Cอื่น สามารถเล่นกอล์ฟ 1 ไบต์ได้ด้วยการใช้var s=Calendar.getInstance();var e=s.getInstance();ขอบคุณ :)
Kevin Cruijssen

1
150 ไบต์java.timeโดยใช้
Olivier Grégoire

1
ทำ! มันใกล้เคียงกับไบต์เป็นคำตอบอื่น ๆ แต่ก็ยังไม่ชนะ
Olivier Grégoire

7

JavaScript (ES6), 116 103 ไบต์

f=(d,n=+new Date)=>(D=new Date(n)).toJSON()<d.split`.`.reverse().join`-`&&(D.getDay()%6>0)+f(d,n+864e5)

ลองออนไลน์!

อย่างไร?

n n

nD.toJSON()วิธีการ:

YYYY - MM - DD T hh : mm : ss.sss Z

YYYY-MM-DDdYYYY-MM-DDDD.MM.YYYY

d.split`.`.reverse().join`-`

D.getDay()0606

(D.getDay() % 6 > 0) + f(d, n + 864e5)

86,400,000n


6

MATL , 24 ไบต์

46tQZt24&YO:Z':X-9XO83-z

ลองออนไลน์!

ฉันไม่ต้องการที่จะมีรูปแบบการป้อนข้อมูลใด ๆ เพื่อให้ภาษากอล์ฟรหัสเฉพาะได้รับประโยชน์มาก

คุณครึ่งหนึ่งประสบความสำเร็จ :-)

คำอธิบาย

46      % Push 46 (ASCII for '.')
tQ      % Duplicate, add 1: gives 47 (ASCII for '/')
Zt      % Implicit input. Replace '.' by '/' in the input string
24&YO   % Convert string with date format 24 ('dd/mm/yyyy') to serial date number.
        % This is an integer representing day starting at Jan-1-0000
:       % Inclusive range from 1 to that
Z'      % Push current date and time as a serial number. Integer part is day;
        % decimal part represents time of the day
:       % Inclusive range from 1 to that
X-      % Set difference. Gives serial numbers of days after today, up to input
9XO     % Convert each number to date format 9, which is a letter for each day
        % of the week: 'M', 'T', 'W', 'T', ' F', 'S', 'S'
83-     % Subtract 83 (ASCII for 'S')
z       % Number of nonzeros. Implicit display

หากฉันเข้าใจความท้าทายอย่างถูกต้องคุณจะป้อนวันที่เพียงครั้งเดียวและเปรียบเทียบกับวันที่วันนี้ ตัวอย่างเช่น16.10.2018จะได้วันนี้ (วันจันทร์01-10-2018) ส่งผลให้เกิด11วันพรุ่งนี้10เป็นต้น
Kevin Cruijssen

@KevinCruijssen อ๊ะ ขอบคุณ! แก้ไขแล้วตอนนี้
Luis Mendo

1
และด้วยจำนวนไบต์เดียวกัน :) ดี +1 จากฉัน
Kevin Cruijssen

6

ภาษา Wolfram (Mathematica) , 64 56 ไบต์

DayCount[Today,""<>#~StringTake~{{4,6},3,-4},"Weekday"]&

ลองออนไลน์!

DayCount[x,y,"Weekday"]นับจำนวนของวันธรรมดาระหว่างและxy

อินพุตxและyสามารถมีได้หลายสิ่งรวมถึงสิ่งที่DateObjectชอบเช่นที่ส่งคืนโดยTodayหรือสตริงในรูปแบบ (น่าเสียดายที่)mm.dd.yyyy(น่าเสียดาย)

ความพยายามครั้งก่อนของฉันพยายามเปลี่ยนdd.mm.yyyyอินพุตให้เป็นDateObjectโดยบอก Mathematica ว่าจะแยกวิเคราะห์อย่างไร โซลูชั่นใหม่เพียงแค่จัดเรียงสตริงใหม่เพื่อใส่วันและเดือนตามที่ Mathematica คาดไว้

เป็นที่น่าสังเกตว่าโซลูชัน 28 ไบต์DayCount[Today,#,"Weekday"]&ไม่เพียงทำงานได้อย่างสมบูรณ์แบบสำหรับรูปแบบอินพุตเดือนต่อวัน แต่ยังจัดการได้อย่างถูกต้องวันต่อเดือนที่ไม่สงสัยเช่น31.12.2018ซึ่งไม่น่าจะหมายถึง "วันที่ 12 ของวันที่ 31 เดือน". ดังนั้นมันถูกต้องมากกว่า 60% ของเวลา :)



5

R, 72 ตัวอักษร

รูปแบบของคำตอบที่ให้บริการโดย @ngm ซึ่งหลีกเลี่ยง grepl เพื่อบันทึกอักขระสองสามตัวและทำงานในที่ที่ไม่ใช่ภาษาอังกฤษ

sum(strftime(seq(Sys.Date(),as.Date(scan(,""),"%d.%m.%Y"),1),'%u')<6)+1


1
สั้นลงและกว้างขึ้นอีกด้วย คำตอบที่ดีและยินดีต้อนรับสู่โรงพยาบาล
ngm

1
ยินดีต้อนรับสู่ PPCG! คุณสามารถเพิ่มการเชื่อมโยงติ้ว - มันง่ายและรูปแบบคำตอบสำหรับคุณ :)
Jayce

5

Java (OpenJDK 8) , 174 166 165 ไบต์

ด้วยแรงบันดาลใจเล็กน้อยจากคำตอบของ Kevin และการสำรวจที่ดีผ่าน Date Date ที่เลิกใช้ฉันจึงพยายามหาวิธีแก้ปัญหา Java ที่กระชับยิ่งขึ้น

-8 ไบต์ขอบคุณที่การแยก regex วันที่ประดิษฐ์ของ Kevin

-1 ไบต์ต้องขอบคุณการทำงานระดับบิตที่ชาญฉลาดของ Nevay

import java.util.*;d->{long r=0,s=new Date().getTime(),e=Date.parse(d.replaceAll("(..).(..).","$2/$1/"));for(;s<=e;s+=864e5)r-=-new Date(s).getDay()%6>>-1;return r;}

ลองออนไลน์!

คำอธิบาย

import java.util.*;                         // Required import for Date 
long r=0,                                   // Initialise result variable
     s=new Date().getTime(),                // Current date in millis
     e=Date.parse(
         d.replaceAll("(..).(..).","$2/$1/")// Use regex to convert to MM/dd/yyyy
     );                                     // Parse date arg using deprecated API
for(;s<=e;                                  // Loop while current millis are less than date arg (e.g. date is before)       
    s+=864e5)                               // Add 86400000 ms to current date (equiv of 1 day)
    r-=-new Date(s).getDay()%6>>-1;        // If day is Sunday (0) or Saturday (6) don't increment, else add 1
return r;                                   // When loop finished return result

1
คำตอบที่ดี! การใช้งานสมาร์ทของ varargs กับd=d[0].splitและเลิก.parseกับรูปแบบเริ่มต้นMM/dd/yyyyรูปแบบ หนึ่งความผิดพลาดเล็กน้อยในโพสต์ของคุณคุณมีimport java.text.*;แทนที่จะเป็นimport java.util.*;ในรหัสของคุณและ// Required import for both Calendar and Dateในคำอธิบายของคุณ (แม้ว่าคุณจะไม่ได้ใช้Calendar)
Kevin Cruijssen

@KevinCruijssen ไม่ทราบว่าทำไมฉันถึงมีjava.textแต่ตอนนี้คงที่! ขอบคุณ!
ลุคสตีเวนส์

1
ถึงแม้ว่าผมจะชอบd=d[0].splitกับ varargs เปลี่ยนการป้อนข้อมูลเพื่อสตริงปกติการลบd=d[0].split("\\.");และการเปลี่ยนแปลงd[1]+"/"+d[0]+"/"+d[2]ที่จะd.replaceAll("(..).(..).","$2/$1/") ช่วยประหยัด 7 ไบต์
Kevin Cruijssen

1
และไบต์อีก 1โดยการเปลี่ยนไปr+=new Date(s).getDay()%6<1?0:1,s+=864e5); s+=864e5)r+=new Date(s).getDay()%6<1?0:1;:)
Kevin Cruijssen

1
-1 ไบต์:r-=-new Date(s).getDay()%6>>-1;
Nevay

4

สีแดง 72 ไบต์

func[a][b: now/date s: 0 until[if b/weekday < 6[s: s + 1]a < b: b + 1]s]

ลองออนไลน์!

ใช้วันที่ในรูปแบบ dd-mm-yyyy เช่น 31-10-2018 (ใช้ได้กับ 10-Oct-2018)

อินพุตที่เข้มงวด:

สีแดง 97 ไบต์

func[a][a: do replace/all a".""-"b: now/date s: 0 until[if b/weekday < 6[s: s + 1]a < b: b + 1]s]

ลองออนไลน์!

โบนัส:

ส่งคืนรายการวันที่ / วันทำงานของวันทำงานจนถึงวันที่กำหนด:

สีแดง 235 ไบต์

f: func [ a ] [
    b: now/date
    d: system/locale/days
    collect [ 
        until [ 
            if b/weekday < 6 [ 
                keep/only reduce [ b ":" d/(b/weekday) ]
            ]
            a < b: b + 1
        ]
    ]
]

ลองออนไลน์!


อ๊ะไม่ยุติธรรมในไพ ธ อนฉันต้องใช้เวลาประมาณ 72 ไบต์ในการประมวลผลรูปแบบ IO นี้ ... : P
Quintec

1
โดยปกติแล้วการแก้ปัญหาสีแดงของฉันอยู่ในหมู่คนที่ยาวที่สุด แต่โชคดีที่ Red ข้อเสนอที่ดีมากกับวัน :)
เลน Ivanov

1
90 ไบต์เพื่อประมวลผลหลาม ... ฉันทำไปแล้วฉันออกจนกว่าจะมีรูปแบบการป้อนข้อมูลที่ยืดหยุ่นมากขึ้น: P
Quintec


3

Python 2 , 163 156 149 147 bytes

lambda s:sum((date.today()+timedelta(x)).weekday()<5for x in range((date(*map(int,(s.split(".")[::-1])))-date.today()).days))
from datetime import*

ลองออนไลน์!

-7 ด้วย @mypetlion

-7 เพิ่มเติมด้วย @ovs

+30 เนื่องจากรูปแบบการป้อนข้อมูลที่เข้มงวดมากซึ่งฉันสังเกตเห็นเพียงก่อนที่ฉันจะโพสต์รหัสก่อนหน้าของฉันซึ่งใช้อินพุตเช่น(2018,11,1):-(


2
ไม่จำเป็นต้องใช้สิ่งนี้: (0,1)[t.weekday()<5]. booleans หลามเป็น subclass ของintและสามารถนำมาใช้ในการดำเนินการทางคณิตศาสตร์เป็นTrue, False 1,0แทนที่ด้วยc+=t.weekday()<5เพื่อบันทึก 7 ไบต์
mypetlion

1
149 ไบต์เป็นแลมบ์ดา
ovs

ขอบคุณ @mypetlion ฉันไม่ควรพลาดอันนั้น
ElPedro

ขอบคุณ @ovs ครั้งที่สองที่คุณได้ช่วยเร็ว ๆ นี้ ครั้งที่แล้วน่าประทับใจมาก -30 พยายามหาวิธีนำสิ่งนี้ไปใช้กับแลมบ์ดา
ElPedro

3

Java (JDK 10) , 171 ไบต์

s->{int c=0;for(var t=java.time.LocalDate.now();!t.parse(s.replaceAll("(..).(..).(.*)","$3-$2-$1")).equals(t);t=t.plusDays(1))c-=t.getDayOfWeek().getValue()/6-1;return c;}

ลองออนไลน์!

เครดิต


1
คุณสามารถเปลี่ยนไป(.*)\\.(.*)\\.(.*) (..).(..).(.*)
Kevin Cruijssen

ด้วยreplaceAllเทคนิคของคุณคำตอบของเขาสามารถเล่นกอล์ฟได้ 7 ไบต์เช่นกันอย่างไรก็ตามคุณก็ยังคงยาวกว่าเดิมเล็กน้อย ;)
Kevin Cruijssen

@KevinCruijssen ขอบคุณสำหรับ regex! และไม่ต้องกังวล: ฉันไม่รังเกียจคำตอบอีกต่อไป;)
Olivier Grégoire

3

JavaScript (Node.js) , 168 160 139 133 ไบต์

ขอบคุณ 35 ไบต์น้อยกว่ากับQuintecและKevin Cruijssen

D=>{var i=D.split('.'),n=0;for(var d=new Date();d<=new Date(i[2],i[1]-1,i[0]);d.setDate(d.getDate()+1))n+=-~d.getDay()%7>1;return n;}

ลองออนไลน์!

D=>{
  var i=D.split('.'),                 // Splits the date string by .
      n=0;                            // Counter variable
  for(var d=new Date();               // For the actual date
      d<=new Date(i[2],i[1]-1,i[0]);      // As long as the date is less or equal the requested date
      d.setDate(d.getDate()+1))           // Count the date one up
    n+=-~d.getDay()%7>1;                // If the date is not a Sunday or Saturday
  return n;                           // Return the counter variable
}

1
158 bytesกับแลมบ์ดา
Quintec

1
139 ไบต์พร้อมการปรับปรุงหากเงื่อนไข
Quintec

1
เนื่องจากวิธีการของคุณไม่ซ้ำคุณไม่จำเป็นต้องเพิ่มการf=นับไบต์ (และใน TIO คุณสามารถใส่ไว้ในส่วนหัว) ซึ่งเป็นเหตุผลที่ @Quintec ระบุว่าเป็น 139 ไบต์แทน 141 ไบต์ นอกจากนี้คุณสามารถเปลี่ยนif((d.getDay()+1)%7>1)n++;เพื่อn+=-~d.getDay()%7>1;การกอล์ฟไปยัง133 ไบต์
Kevin Cruijssen


1
เคล็ดลับเพิ่มเติมเล็กน้อยสำหรับการอ้างอิงในอนาคต
Shaggy

3

Python3 & Numpy , 96 ไบต์

ฉันไม่สามารถมีขนาดเล็กกว่าโซลูชันสำเร็จรูปที่น่าเบื่อได้ ...

from numpy import*
d=datetime64
lambda s:busday_count(d('today'),d(f'{s[6:]}-{s[3:5]}-{s[:2]}'))

ลองออนไลน์!


ต้องเข้าสู่ Python 3;)
ElPedro

จากการนำเข้าของคุณคุณไม่ได้ใช้Python 3แต่เป็นPython 3 ที่มีจำนวนมาก
Jonathan Frech

@ JonathanFrech ควรจะอยู่ในชื่อหรือไม่ อื่น ๆ ที่ใช้ python ก็ใช้ไลบรารีเช่นกันเนื่องจาก python ไม่มีประเภทข้อมูลในตัวสำหรับวันที่หรือเวลา
Aaron

1
ขึ้นอยู่กับคำจำกัดความของคุณของbuiltin - modules เช่นdatetimeเป็นโมดูลไลบรารีมาตรฐานและดังนั้นฉันจะถือว่าพวกเขาเป็นส่วนหนึ่งของภาษาหลัก อย่างไรก็ตามเมื่อมีการใช้งานโมดูลของบุคคลที่สามอย่างNumpyจะช่วยเพิ่มความสามารถของภาษาและดังนั้นฉันจึงเห็นว่ามันเป็นภาษาอื่น
Jonathan Frech

2

PowerShell , 107 99 ไบต์

-8 ไบต์ขอบคุณที่มาซี่

$d,$m,$y=$args-split'\.';for($a=date;$a-lt(date "$y-$m-$d");$a=$a|% *ys 1){$o+=($a|% D*k)-in1..5}$o

ลองออนไลน์!

ดำเนินการ regex -splitบนอินพุต$argsเก็บค่าไว้ใน$days, $months และ ear $yตามลำดับ จากนั้นเข้าสู่forลูปเริ่มต้น$aวันที่วันนี้ ห่วงอย่างต่อเนื่องในขณะที่$aเป็น-lESS than วันที่เป้าหมายการป้อนข้อมูลของเรา การวนซ้ำแต่ละครั้งที่เราเพิ่ม1da ysไป$aและการตรวจสอบว่ากระแสD*k(สั้นDayOfWeek) อยู่ในช่วง1..5(เช่นวันจันทร์ถึงวันศุกร์) ผลลัพธ์บูลีนนั้นจะถูกสะสมเข้ามา$oและเมื่อเราออกจากลูปแล้วค่าที่เหลืออยู่บนไพพ์ไลน์


100 ไบต์ $d,$m,$y=$args-split'\.';for($a=date;$a-lt(date "$y-$m-$d");$a=$a|% *ys 1){$o+=($a|% D*k)-in1..5};$o
mazzy

1
@ mazzy แน่นอน นอกจากนี้เครื่องหมายอัฒภาคระหว่างfor(...){...}และ$oสามารถลบออกได้ดังนั้นตอนนี้เราต่ำกว่า 100!
AdmBorkBork

2

Python 2 , 147 143 141 140 ไบต์

from datetime import*
lambda e,s=date.today():sum((s+timedelta(x+1)).weekday()<5for x in range((date(*map(int,e.split(".")[::-1]))-s).days))

ลองออนไลน์!

รับสตริง e ซึ่งแทนวันที่สิ้นสุดในรูปแบบ "dd.MM.YYYY" ทางเลือกยังใช้วันที่เริ่มต้นด้วยซึ่งคาดว่าจะเป็นวันที่และเวลา

วันที่เริ่มต้น, s, เป็นค่าเริ่มต้นเป็นวันที่วันนี้เป็นวัตถุ datetime.date เพื่อไม่สนใจเวลา เวลาสิ้นสุดจะถูกแยกวิเคราะห์เป็นวัตถุ datetime.datetime จากนั้นแปลงเป็นวันที่เนื่องจากวัตถุ datetime.date ไม่มีวิธีการแยกวิเคราะห์และไม่สามารถเพิ่มชุดข้อมูลไปที่ / ลบจากวันที่ วนซ้ำทุก ๆ วันใน (เริ่มต้น, สิ้นสุด] และเพิ่ม 1 ไปยังยอดรวมถ้าจำนวนวันทำงานของมันคือ <5 ([0-4] คือ [จันทร์ถึงศุกร์], [5-6] คือ [เสาร์ - อาทิตย์])

การแยกวิเคราะห์วันที่และเวลาเป็นสิ่งที่เลวร้ายที่สุด

แก้ไข: Stole ElPedro's map(int,thing) trick to save 4 bytes.

แก้ไข 2: ELECTRIC BOOGALOO: บันทึก 2 ไบต์โดยทำให้เป็นฟังก์ชันที่ไม่ระบุตัวตน (ขอบคุณแอรอน!)

แก้ไข 3: ช่วง xrange -> (ขอบคุณ Aaron อีกครั้ง!)


1
You're welcome! Nice answer :)
ElPedro

1
It is convention you can leave off the f= from lambda expressions here
Aaron

1
"Datetime parsing is the worst, you guys" Hahahaha feel my pain, you succeeded where I failed though :P
Quintec

@Aaron I'm never sure if that's okay with multiple functions or with import statements, thanks!
Triggernometry

1
You can also use range rather than xrange it should still work just fine.
Aaron

2

PHP, 66 bytes

for($t=time();$t<strtotime($argn);)$r+=date(N,$t+=86400)<6;echo$r;

empty output for 0; insert + between echo and $r to fix.

Run as pipe with -nr or try it online.


60 bytes with unary output:

for($t=time();$t<strtotime($argn);)echo date(N,$t+=86400)<6;


1

IBM/Lotus Notes Formula - 99 bytes

d:=i;c:=0;@While(d>@Today;@Set("c";c+@If(@Weekday(d)=1:7;0;1));@Set("d";@Adjust(d;0;0;-1;0;0;0)));c

Takes input from a date/time field i. The input format of i is set to . separated so there is no need to convert the input. Notes can take a date input with any separator as long as you tell it before what it is going to be (hope that's not cheating!). Formula is in computed numeric field o on the same form.

Interesting aside: Ever since @For and @While were introduced into the Formula language in (I think) R6 by the great Damien Katz the only use I have found for them is code golfing. I have never used them in a production app.

There is no TIO available for formula so here is a screenshot taken on 02.10.2018:

enter image description here



1

K4, 40 bytes

Solution:

{+/1<.q.mod[d+!(."."/:|"."\:x)-d:.z.d]7}

Explanation:

Calculate the difference between the dates, use modulo 7 to ignore weekends, sum up.

{+/1<.q.mod[d+!(."."/:|"."\:x)-d:.z.d]7} / the solution
     .q.mod[                         ]7  / modulo with 7
                                 .z.d    / UTC date
                               d:        / save as d
                              -          / subtract from
               (             )           / do this together
                       "."\:x            / split input on "."
                      |                  / reverse
                 "."/:                   / join back with "."
                .                        / take the value
              !                          / range 0..the difference
            d+                           / add today's date to range
   1<                                    / is 1 less than the modulo (ie is this mon-fri)?
 +/                                      / sum up

Notes:

  • same byte alternative to the date parsing: "D"$,/|"."\:x

1

C (clang), 209 208 205 bytes

Compiler flags -DU=u=localtime(&b) -DW=tm_wday -DY=tm_year -DT=tm_yday (52 bytes).

#import<time.h>
i;f(char*a){long b;struct tm t,*u;time(&b);U;strptime(a,"%d.%m.%Y",&t);for(i=0;u->T^t.T|u->Y^t.Y;u->W&&u->W^6&&i++,b+=86400,U);return i;}

Try it online!

-1 byte thanks to @JonathanFrech


?i++:0 -> &&++i.
Jonathan Frech

0

q, 52 79 bytes

{x:"D"$"."sv reverse"."vs x;i:0;while[x-.z.d;$[2>x mod 7;x-:1;[i+:1;x-:1]]];:i}

in q, each date has an underlying integer value, based on how many days have passed since the start of the millenium. Applying 'mod 7' to this, you get unique values for each day of the week (0 for Saturday, 6 for Friday). So when 2 > x mod 7, don't increment the counter, to avoid counting weekends.

EDIT: Missed strict date format, editing

EDIT2: Included


1
Best I've come up with is {sum 1<mod[d+til("D"$x 10 vs 67893401)-d:.z.d]7} for 48 bytes without resorting to K verbs.
streetster

Using the list indices is a lot more elegant than reverse, and rather than using a loop, applying mod to the list. Great answer +1
Thaufeki
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.