Đếm ngược ngày làm việc


17

Tôi chỉ có ý tưởng thiên tài để làm cho cuộc sống công việc trở nên dễ dàng hơn - đếm ngược đến một ngày cụ thể chỉ tính ngày làm việc.


Nhiệm vụ cơ bản là tạo ra một bộ đếm ngược đến một ngày cụ thể chỉ bao gồm các ngày làm việc trong bộ đếm ngược.

Khi ngày làm việc được tính vào Thứ Hai , Thứ Ba , Thứ Tư , Thứ NămThứ Sáu .

Đầu vào phải là một ngày cụ thể theo định dạng chuẩn châu Âu "không chính thức" dd.MM.yyyyvà phải là ngày hôm nay hoặc một ngày trong tương lai.

Đầu ra chỉ nên là số ngày còn lại.

Vì nó là , mã ngắn nhất sẽ thắng.


Trường hợp thử nghiệm:

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

Nếu tôi bỏ lỡ một vài điều trong câu hỏi, xin vui lòng tha thứ cho tôi - đó là câu hỏi đầu tiên của tôi :)

BIÊN TẬP:

  • Bạn có thể sử dụng falselàm đầu ra thay vì 0 <- nhưng nó không đẹp
  • Không cần tôn trọng DST

9
Có bất kỳ lý do cụ thể đằng sau định dạng đầu vào châu Âu "không chính thức" này không ? Sự đồng thuận của chúng tôi là cho phép đầu vào linh hoạt bất cứ khi nào có thể.
Arnauld

6
Có thực sự có bất kỳ điểm nào trong việc thêm "thách thức bổ sung" của định dạng ngày khó xử lý không? Đó chỉ là những ngôn ngữ wrt không công bằng có định dạng ngày linh hoạt ...
Quintec

3
@Hille Tôi không nói nó "khó", nó chỉ là một rắc rối không cần thiết, đặc biệt là trong môn đánh gôn ... hãy lưu ý liên kết mà Arnauld đã đăng ở trên ... nói chung đầu vào linh hoạt là chuẩn mực ...
Quintec

6
Nhân tiện, bạn lưu ý rằng đây là thử thách đầu tiên của bạn; Tôi mời bạn sử dụng The Sandbox để sàng lọc trước khi đăng một thử thách lên main! Nếu không, công việc tốt, và tôi sẽ thích nhìn thấy nhiều hơn từ bạn!
Giuseppe

7
Không thực sự ấn tượng bởi định dạng đầu vào nghiêm ngặt nhưng khác hơn là một thách thức tốt.
ElPedro

Câu trả lời:


18

05AB1E , 130 128 133 131 124 123 byte

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

Tôi không nghĩ đến điều đó..

Đối với ngôn ngữ chơi gôn 05AB1E hoàn toàn không thành vấn đề cho dù đầu vào là .hay -. Tuy nhiên, 05AB1E không có bất kỳ nội dung nào cho các đối tượng hoặc tính toán Ngày. Nội dung duy nhất liên quan đến ngày mà nó có là năm / tháng / ngày / giờ / phút / giây / giây / giây.

Vì vậy, gần như tất cả các mã bạn thấy là các tính toán thủ công để chuyển sang ngày hôm sau và tính ngày trong tuần.

+5 byte do một phần tôi đã quên trong công thức của Zeller (năm 1 cho các tháng 1 và tháng 2) ..

Dùng thử trực tuyến hoặc Dùng thử trực tuyến với ngày tự xác định là 'hôm nay' .

Giải trình:

Bức tường văn bản đến.

Nói chung, mã theo mã giả sau:

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;là một phần của chương trình 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;và 3) Start an infinite loop:là hướng thẳng trong chương trình 05AB1E:

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

4) If(currentDate is NOT a Saturday and currentDate is NOT a Sunday):là phần khó đầu tiên với tính toán thủ công. Vì 05AB1E không có nội dung ngày, nên chúng tôi sẽ phải tính toán Ngày trong tuần theo cách thủ công.

Công thức chung để làm điều này là:

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

Trường hợp từ tháng 3 đến tháng 12:

  • qday của tháng ([1, 31])
  • m là 1-indexedmonth ([3, 12])
  • K là năm của thế kỷ (yearmod100 )
  • J là thế kỷ 0 được lập chỉ mục (year100)

Và trong các tháng 1 và 2:

  • qday của tháng ([1, 31])
  • m là 1-indexedmonth+12 ([13, 14])
  • K là năm của thế kỷ cho năm trước ((year1)mod100 )
  • J là thế kỷ 0 được lập chỉ mục cho năm trước (year1100)

Kết quả là vào ngày trong tuần h , trong đó 0 = Thứ Bảy, 1 = Chủ Nhật, ..., 6 = Thứ Sáu.
Nguồn: sự phù hợp của Zeller

Chúng ta có thể thấy điều này trong phần này của chương trình 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;là thẳng về phía trước một lần nữa:

     # 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 linelại phức tạp hơn, vì chúng ta phải thực hiện thủ công. Vì vậy, điều này sẽ được mở rộng thành mã giả sau đây:

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;

Nguồn:
Thuật toán để xác định xem một năm có phải là năm nhuận hay không. (EDIT: Không còn phù hợp nữa, vì tôi sử dụng một phương pháp thay thế để kiểm tra năm nhuận đã lưu 7 byte.)
Thuật toán xác định số ngày trong một tháng.

6a) Integer isLeapYear = ...;được thực hiện như thế này trong chương trình 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`

Cũng được sử dụng trong câu trả lời 05AB1E này của tôi , vì vậy có một số năm ví dụ được thêm vào để minh họa các bước.

6b) currentDate.month == 2 ?và 6c) 28 + isLeapYearđược thực hiện như thế này:

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) :và 6e) 31 - (currentDate.month - 1) % 7 % 2;được thực hiện như thế này:

ë           # 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):được thực hiện như thế này:

     # 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;được thực hiện như thế này:

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:và 6i) nextDate.day = 1;sau đó được thực hiện như thế này:

ë        # 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;và 6n) nextDate.year += 1;sau đó được thực hiện như thế này:

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

Và cuối cùng ở 8) If(currentDate == parsed input-string):và 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
Bạn là một người điên ... có một upvote.
admBorkBork

1
Chương trình 05AB1E dài nhất từ ​​trước đến nay?
Luis Mendo

2
@LuisMendo Đóng, nhưng tôi e rằng tôi có một câu trả lời 05AB1E thậm chí còn dài hơn và một câu hỏi quá gần .. ;) Tôi chắc chắn rằng tôi sẽ có thể đánh gôn vài byte ở đây và đơn giản hóa các phần của việc thực thi mã giả vào ngày hôm sau. Sẽ nhìn vào sáng mai, nhưng vừa trở về từ thể thao và sẽ đi ngủ sớm.
Kevin Cruijssen

11

Excel 24 byte

Giả sử đầu vào trong Ô A1

=NETWORKDAYS(NOW()+1,A1)

Sử dụng chức năng tích hợp. Thật không may, chức năng bao gồm cả ngày hôm nay và ngày kết thúc. OP đã làm rõ để không tính ngày hôm nay, vì vậy tôi thêm một vào NGAY để không tính ngày hôm nay.

Để giải quyết các nhận xét về định dạng số, một lần nữa, đây là tiêu chuẩn Excel: nhập mô tả hình ảnh ở đây


Mặc dù điều này hoạt động với các giá trị ngày, nhưng nó không nhận được đầu vào như đã nêu. Đó là (ít nhất là trong phiên bản Hoa Kỳ) 10.12.2018là một chuỗi khi được giữ trong một ô chứ không phải là một ngày. Các giải pháp rõ ràng nhưng dài để sửa chữa này sẽ được thay đổi A1để DATE(RIGHT(A1,4),MID(A1,4,2),LEFT(A1,2))trong giải pháp của bạn
Taylor Scott

thật không may, cộng đồng đã quyết định rằng các ngôn ngữ cần được chạy trong cài đặt mặc định của chúng là hợp lệ (một ngoại lệ mà tôi đã thấy với ngôn ngữ này - IE, nếu ngôn ngữ của bạn hỗ trợ cả tiếng Anh và tiếng Tây Ban Nha, bạn có thể dễ dàng sử dụng, nhưng điều này phải được lưu ý.) Hơn nữa, OP (@hille) đã không nói rằng định dạng là linh hoạt và trên thực tế đã nói hoàn toàn ngược lại (xem bình luận thứ hai về câu hỏi này)
Taylor Scott

2
Định dạng không chuẩn, dựa trên ngôn ngữ. Excel đọc định dạng từ HKCU\Control Panel\International\sDecimalchuỗi đăng ký. Trên bản cài đặt Windows US mặc định đó là MM / dd / yyyy. Ở hầu hết các nước EU, đây sẽ là mặc định.
Erik A

@luisMendo Vâng, điều đó có hiệu quả. Tôi đã không thấy bất kỳ làm rõ. Nếu nó không được tính vào ngày hôm trước, tôi có thể có = NETWORKDAYS (NOW (), A1-1). Tôi biết nó sẽ luôn là cùng một byte cho dù làm rõ điều gì.
Keeta - phục hồi Monica

Vui mừng khi làm việc. Tôi đã xóa downvote
Luis Mendo


8

Java 10, 233 232 226 byte

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

Ngày luôn nhắc nhở tôi rằng Java thực sự dài như thế nào ..

LƯU Ý: Hiện tại có hai câu trả lời Java ngắn hơn (dưới 175 byte), một câu trả lời sử dụng thông minh các phương thức không dùng từ các phiên bản Java trước đó của @LukeStevensmộtjava.time.LocalDate câu trả lời sử dụng từ Java 8 của @ OlivierGrégoire .

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

Giải trình:

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

Bạn có thể làm e=s.clone()
Quintec

1
Chúng ta cũng có thể (tôi giả sử) làm Calendar s=Calendar.getInstance(),e=s.getInstance(), điều không may cuối cùng lại có cùng độ dài.
Misha Lavrov

1
@MishaLavrov Ah, Cthực sự không cần thiết. Đó là từ một phần cũ của mã nơi tôi cũng đã sử dụng Cở một nơi khác. Có thể chơi golf 1 byte bằng cách sử dụng var s=Calendar.getInstance();var e=s.getInstance();cảm ơn. :)
Kevin Cruijssen

1
150 byte , sử dụng java.time.
Olivier Grégoire

1
Làm xong! Nó rất gần với byte cho câu trả lời khác, nhưng chưa đánh bại nó.
Olivier Grégoire

7

JavaScript (ES6), 116 103 byte

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

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

Làm sao?

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 byte

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

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

Tôi không muốn có bất kỳ định dạng đầu vào nào để các ngôn ngữ golf mã cụ thể có lợi thế lớn

Bạn đã thành công một nửa :-)

Giải trình

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

Nếu tôi hiểu đúng thách thức, bạn chỉ mất một ngày nhập và so sánh với ngày hôm nay. Ví dụ: 16.10.2018hôm nay (thứ hai 01-10-2018) sẽ có kết quả vào 11ngày mai 10, v.v.
Kevin Cruijssen

@KevinCruijssen Rất tiếc. Cảm ơn! Đã sửa ngay
Luis Mendo

1
Và với cùng số byte. :) Đẹp, +1 từ tôi.
Kevin Cruijssen

6

Ngôn ngữ Wolfram (Mathicala) , 64 56 byte

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

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

DayCount[x,y,"Weekday"]đếm số ngày trong tuần giữa xy.

Các đầu vào xycó thể là nhiều thứ, bao gồm một thứ ưa thích DateObjectnhư cái được trả về Todayhoặc một chuỗi ở định dạng (không may) mm.dd.yyyy.

Nỗ lực trước đây của tôi đã cố gắng biến dd.mm.yyyyđầu vào thành một DateObjectbằng cách cho Mathicala biết cách phân tích cú pháp; giải pháp mới chỉ đơn giản là sắp xếp lại chuỗi để đặt ngày và tháng theo thứ tự mà Mathicala mong đợi.

Điều đáng chú ý là giải pháp 28 byte DayCount[Today,#,"Weekday"]&không chỉ hoạt động hoàn hảo cho định dạng đầu vào theo tháng, mà còn xử lý chính xác các đầu vào ngày tháng không rõ ràng như 31.12.2018, không thể có nghĩa là "ngày thứ 12 của ngày 31 tháng". Vì vậy, nó chính xác hơn 60% thời gian :)



5

R, 72 ký tự

Một biến thể về câu trả lời được cung cấp bởi @ngm để tránh grepl lưu một vài ký tự và hoạt động ở các địa phương không phải tiếng Anh.

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


1
Ngắn hơn và tổng quát hơn quá. Câu trả lời tốt đẹp và chào mừng đến tị nạn.
ngm

1
Chào mừng đến với PPCG! bạn có thể thêm một liên kết TIO - thật dễ dàng và định dạng câu trả lời cho bạn :)
JayCe

5

Java (OpenJDK 8) , 174 166 165 byte

Với một chút cảm hứng từ câu trả lời của Kevin và một câu hỏi hay về API ngày không dùng nữa, tôi đã xoay sở để có được một giải pháp Java ngắn gọn hơn.

-8 byte nhờ phân tích cú pháp ngày regex sáng tạo của Kevin

-1 byte nhờ hoạt động bitwise thông minh của 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;}

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

Giải trình

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
Câu trả lời tốt đẹp! Sử dụng thông minh các varargs với d=d[0].splitvà không dùng .parsevới định dạng mặc MM/dd/yyyyđịnh. Một lỗi nhỏ trong bài viết của bạn, bạn có import java.text.*;thay vì import java.util.*;trong mã của bạn và // Required import for both Calendar and Datetrong lời giải thích của bạn (mặc dù bạn không sử dụng Calendar).
Kevin Cruijssen

@KevinCruijssen Không biết tại sao tôi java.textlại sửa nhưng bây giờ đã sửa! Cảm ơn!
Luke Stevens

1
Mặc dù tôi thích các d=d[0].splitvarargs, thay đổi đầu vào thành một Chuỗi thông thường, loại bỏ d=d[0].split("\\.");và thay đổi d[1]+"/"+d[0]+"/"+d[2]để d.replaceAll("(..).(..).","$2/$1/") tiết kiệm 7 byte .
Kevin Cruijssen

1
thêm 1 byte bằng cách thay đổi r+=new Date(s).getDay()%6<1?0:1,s+=864e5);thành s+=864e5)r+=new Date(s).getDay()%6<1?0:1;. :)
Kevin Cruijssen

1
-1 byte:r-=-new Date(s).getDay()%6>>-1;
Nevay

4

Đỏ , 72 byte

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

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

Lấy ngày ở định dạng dd-mm-yyyy, ví dụ: 31-10-2018 (cũng hoạt động với ngày 10 tháng 10 năm 2018)

Đầu vào nghiêm ngặt:

Màu đỏ , 97 byte

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]

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

Tặng kem:

Trả về danh sách các ngày / ngày trong tuần của ngày làm việc cho đến ngày đã cho:

Màu đỏ , 235 byte

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

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


Agh, không công bằng, trong python tôi cần phải dành khoảng 72 byte để xử lý định dạng IO này ...: P
Quintec

1
Thông thường các giải pháp Đỏ của tôi nằm trong số những giải pháp dài nhất, nhưng may mắn thay, Red xử lý rất tốt với ngày tháng :)
Galen Ivanov

1
90 byte để xử lý python ... Tôi đã hoàn thành, tôi thoát cho đến khi có định dạng đầu vào linh hoạt hơn: P
Quintec


3

Python 2 , 163 156 149 147 byte

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

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

-7 cảm ơn @mypetlion

-7 nhiều hơn nhờ có @ovs

+30 do định dạng đầu vào rất hạn chế mà tôi chỉ nhận thấy ngay trước khi tôi đăng mã trước đó của mình, ví dụ như (2018,11,1):-(


2
Không cần điều này : (0,1)[t.weekday()<5]. Booleans Python là một lớp con của intTrue, Falsecó thể được sử dụng trong các phép toán số học như 1,0. Thay thế nó c+=t.weekday()<5để lưu 7 byte.
mypetlion

1
149 byte như một lambda.
trứng

Cảm ơn @mypetlion. Tôi không nên bỏ qua cái đó
ElPedro

Cảm ơn @ovs. Lần thứ hai bạn đã giúp đỡ gần đây. Lần trước là rất ấn tượng -30. Đã cố gắng tìm ra cách để có được điều này vào lambda.
ElPedro

3

Java (JDK 10) , 171 byte

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

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

Tín dụng


1
Bạn có thể thay đổi (.*)\\.(.*)\\.(.*)thành (..).(..).(.*).
Kevin Cruijssen

replaceAllTuy nhiên, với kỹ thuật của bạn, câu trả lời của anh ta có thể được đánh bằng 7 byte, do đó, câu trả lời của bạn vẫn dài hơn một chút. ;)
Kevin Cruijssen

@KevinCruijssen Cảm ơn vì regex! Và không phải lo lắng: Tôi không ngại có câu trả lời dài hơn;)
Olivier Grégoire

3

JavaScript (Node.js) , 168 160 139 133 byte

Giảm 35 byte nhờ QuintecKevin 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;}

Hãy thử trực tuyế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 byte với lambda
Quintec

1
139 byte với điều kiện if được cải thiện
Quintec

1
Vì phương thức của bạn không đệ quy, bạn không cần thêm f=số đếm byte (và trên TIO, bạn có thể đặt nó vào tiêu đề), đó là lý do tại sao @Quintec tuyên bố đó là 139 byte thay vì 141 byte. Ngoài ra, bạn có thể thay đổi if((d.getDay()+1)%7>1)n++;để n+=-~d.getDay()%7>1;đến sân nó để 133 byte .
Kevin Cruijssen


1
Một vài lời khuyên để tham khảo trong tương lai.
Xù xì

3

Python3 & Numpy , 96 byte

Tôi không thể nhỏ hơn giải pháp làm sẵn nhàm chán ...

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

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


Phải vào Python 3;)
ElPedro

Dựa trên quá trình nhập của bạn, bạn không sử dụng Python 3 , mà là Python 3 với numpy .
Jonathan Frech

@JonathanFrech nên có trong tiêu đề? những người khác sử dụng python cũng đã sử dụng một thư viện vì python không có kiểu dữ liệu dựng sẵn cho ngày hoặc thời gian.
Aaron

1
Điều này phụ thuộc vào định nghĩa của bạn về dựng sẵn - các mô-đun như datetime là các mô-đun thư viện tiêu chuẩn và do đó tôi sẽ coi chúng là một phần của ngôn ngữ cốt lõi. Tuy nhiên, khi một người sử dụng các mô-đun của bên thứ ba như numpy , người ta sẽ nâng cao khả năng của ngôn ngữ và do đó tôi sẽ xem nó là ngôn ngữ khác.
Jonathan Frech

2

PowerShell , 107 99 byte

-8 byte nhờ mazzy

$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

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

Thực hiện một biểu thức chính -splittrên đầu vào $args, lưu trữ các giá trị vào $days, $months và $ytai tương ứng. Sau đó, nhập một forvòng lặp, khởi tạo $acho đến ngày hôm nay. Vòng lặp tiếp tục trong khi ess $alà ngày mục tiêu đầu vào của chúng tôi. Mỗi lần lặp chúng tôi sẽ thêm da vào và kiểm tra xem dòng điện (viết tắt ) có nằm trong phạm vi không (tức là từ thứ Hai đến thứ Sáu). Kết quả Boolean đó được tích lũy vào và một khi chúng ta thoát khỏi vòng lặp mà giá trị còn lại trên đường ống và đầu ra là ẩn.-lt1ys$aD*kDayOfWeek1..5$o


100 byte? $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
mê mẩn

1
@mazzy Thật vậy. Thêm vào đó, dấu chấm phẩy giữa for(...){...}$ocó thể được loại bỏ, vì vậy chúng tôi hiện dưới 100!
admBorkBork

2

Python 2 , 147 143 141 140 byte

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

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

Lấy một chuỗi, e, đại diện cho ngày kết thúc ở định dạng "dd.MM.YYYY". Tùy chọn cũng mất ngày bắt đầu, nhưng dự kiến ​​đây sẽ là datetime.date.

Ngày bắt đầu, s, được mặc định là ngày hôm nay dưới dạng đối tượng datetime.date để bỏ qua thời gian. Thời gian kết thúc được phân tích cú pháp thành một đối tượng datetime.datetime sau đó được chuyển đổi thành một ngày, vì các đối tượng datetime.date không có phương thức phân tích cú pháp và thời gian có thể được thêm vào / trừ từ ngày. Lặp lại qua từng ngày trong (bắt đầu, kết thúc] và cộng 1 vào tổng nếu số ngày trong tuần của nó là <5. ([0-4] là [Thứ Hai-Thứ Sáu], [5-6] là [Sat-Sun]).

Phân tích thời gian là tồi tệ nhất, các bạn.

EDIT: Thủ thuật đánh cắp bản đồ (int, thing) của ElPedro để lưu 4 byte.

EDIT 2: BOOGALOO ĐIỆN: Đã lưu 2 byte bằng cách biến nó thành một hàm ẩn danh. (Cảm ơn Aaron!)

EDIT 3: xrange -> phạm vi. (Cảm ơn một lần nữa Aaron!)


1
Không có gì! Câu trả lời hay :)
ElPedro

1
Đây là quy ước bạn có thể bỏ qua các f=biểu thức lambda ở đây
Aaron

1
"Phân tích thời gian là điều tồi tệ nhất, các bạn" Hahahaha cảm thấy nỗi đau của tôi, bạn đã thành công ở nơi tôi đã thất bại: P
Quintec

@Aaron Tôi không bao giờ chắc chắn nếu điều đó ổn với nhiều chức năng hoặc với báo cáo nhập khẩu, cảm ơn!
Triggernometry

1
Bạn cũng có thể sử dụng rangechứ không phải xrangenó vẫn hoạt động tốt.
Aaron

2

PHP, 66 byte

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

đầu ra trống cho 0; chèn +giữa echo$r để sửa chữa.

Chạy như ống với -nrhoặc thử trực tuyến .


60 byte với đầu ra unary:

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

1

PHP (với Carbon ), 107 byte

function a($d){return Carbon\Carbon::parse($d)->diffInDaysFiltered(function($e){return!$e->isWeekend();});}

1

Công thức ghi chú IBM / Lotus - 99 byte

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

Lấy đầu vào từ trường ngày / giờ i. Định dạng đầu vào của iđược đặt thành. tách để không cần chuyển đổi đầu vào. Ghi chú có thể lấy đầu vào ngày với bất kỳ dấu phân tách nào miễn là bạn nói với nó trước khi nó diễn ra (hy vọng đó không phải là gian lận!). Công thức là trong trường số được tính toán otrên cùng một hình thức.

Thú vị sang một bên: Kể từ đó @For@Whileđược đưa vào ngôn ngữ Công thức trong (tôi nghĩ) R6 bởi Damien Katz vĩ đại, cách sử dụng duy nhất tôi tìm thấy cho họ là chơi golf mã. Tôi chưa bao giờ sử dụng chúng trong một ứng dụng sản xuất.

Không có TIO cho công thức, vì vậy đây là ảnh chụp màn hình vào ngày 02.10.2018:

enter image description here



1

K4 , 40 byte

Giải pháp:

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

Giải trình:

Tính toán sự khác biệt giữa các ngày, sử dụng modulo 7 để bỏ qua các ngày cuối tuần, tổng hợp.

{+/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

Ghi chú:

  • cùng một byte thay thế cho phân tích ngày: "D"$,/|"."\:x

1

C (tiếng kêu) , 209 208 205 byte

Cờ trình biên dịch -DU=u=localtime(&b) -DW=tm_wday -DY=tm_year -DT=tm_yday(52 byte).

#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;}

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

-1 byte nhờ @JonathanFrech


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

0

q, 52 79 byte

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

trong q, mỗi ngày có một giá trị nguyên nằm bên dưới, dựa trên số ngày đã trôi qua kể từ khi bắt đầu thiên niên kỷ. Áp dụng 'mod 7' cho điều này, bạn sẽ nhận được các giá trị duy nhất cho mỗi ngày trong tuần (0 cho Thứ Bảy, 6 cho Thứ Sáu). Vì vậy, khi 2> x mod 7, không tăng bộ đếm, để tránh đếm ngày cuối tuần.

EDIT: Bỏ lỡ định dạng ngày nghiêm ngặt, chỉnh sửa

EDIT2: Đã bao gồm


1
Tốt nhất tôi nghĩ ra là {sum 1<mod[d+til("D"$x 10 vs 67893401)-d:.z.d]7}cho 48 byte mà không cần dùng đến động từ K.
streetster

Sử dụng các chỉ mục danh sách thanh lịch hơn nhiều so với đảo ngược và thay vì sử dụng vòng lặp, áp dụng mod vào danh sách. Câu trả lời tuyệt vời +1
Thaufeki
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.