Đếm thời gian


17

Lấy cảm hứng từ một kịch bản đời thực, mà tôi đã yêu cầu một câu trả lời ở đây: /superuser/1312212/wr-a-formula-to-count-how-many-times-each-date- xuất hiện trong một tập hợp của ngày

Đưa ra một mảng các khoảng thời gian (hoặc các cặp startdate-enddate), xuất ra một số lượng bao nhiêu lần mỗi ngày, cho tất cả các ngày trong tổng phạm vi.

Ví dụ:

  #      Start      End
  1    2001-01-01 2001-01-01
  2    2001-01-01 2001-01-03
  3    2001-01-01 2001-01-02
  4    2001-01-03 2001-01-03
  5    2001-01-05 2001-01-05

Cho các dữ liệu trên, kết quả sẽ như sau:

2001-01-01: 3 (Records 1,2,3)
2001-01-02: 2 (Records 2,3)
2001-01-03: 2 (Records 2,4)
2001-01-04: 0
2001-01-05: 1 (Record 5)

Bạn chỉ cần xuất số đếm cho mỗi ngày (theo thứ tự, được sắp xếp cũ nhất - mới nhất); không phải hồ sơ mà họ xuất hiện trong.

Bạn có thể giả sử rằng mỗi lần chỉ chứa ngày, không phải ngày; và vì vậy cả ngày luôn được đại diện.

Tôi / O

Đầu vào có thể là bất kỳ định dạng nào đại diện cho một tập hợp thời gian - vì vậy, một tập hợp các cặp thời gian hoặc một tập hợp các đối tượng (dựng sẵn) có chứa ngày bắt đầu và ngày kết thúc. Thời gian ngày được giới hạn trong khoảng từ 1901 đến 2099, như thường lệ đối với các thách thức PPCG.

Bạn có thể giả sử đầu vào được sắp xếp trước theo cách bạn muốn (chỉ định trong câu trả lời của bạn). Ngày đầu vào được bao gồm (vì vậy phạm vi bao gồm toàn bộ ngày bắt đầu và ngày kết thúc).

Bạn cũng có thể giả sử rằng, trong hai ngày trong bất kỳ phạm vi cụ thể nào, ngày đầu tiên sẽ cũ hơn hoặc bằng ngày thứ hai (nghĩa là bạn sẽ không có phạm vi ngày âm).

Đầu ra là một mảng chứa số đếm cho mỗi ngày, từ cũ nhất đến mới nhất trong đầu vào khi được sắp xếp theo Ngày bắt đầu.

Vì vậy, đầu ra cho ví dụ trên sẽ là {3,2,2,0,1}

Có thể một số ngày không được bao gồm trong bất kỳ phạm vi thời gian nào, trong trường hợp đó 0 là đầu ra cho ngày đó.

Tiêu chí chiến thắng

Đây là mã golf, vì vậy byte thấp nhất sẽ thắng. Loại trừ thông thường được áp dụng

Ví dụ thuật toán giả

For each time range in input
    If start is older than current oldest, update current oldest
    If end is newer than current newest, update current newest
End For
For each day in range oldest..newest
   For each time range
       If timerange contains day
            add 1 to count for day
End For
Output count array

Các thuật toán khác để có được kết quả tương tự là tốt.


3
Là một mảng các số nguyên được yêu cầu, hoặc chúng tôi được phép trả lại một cái gì đó khác, nói một từ điển với các khóa như mỗi ngày? Nếu chúng ta được phép trả lại một từ điển, thì chúng ta có thể bỏ qua những ngày không có trong bất kỳ khoảng thời gian nào không?
JungHwan Min

1
chúng ta có thể lấy đầu vào làm hai danh sách, một danh sách có ngày bắt đầu và danh sách còn lại có ngày kết thúc tương ứng không?
Giuseppe

Vâng, tất cả những điều đó đều ổn, ngoại trừ bỏ qua một ngày - Tôi nói rõ ràng rằng 0 nên là đầu ra trong trường hợp đó
simonalexander2005

3
Tôi có thể hỏi tại sao 0nên có trong một từ điển? Nó chỉ xuất hiện để buộc người dùng phải lặp từ min(input)để max(input), mà dường như không thêm bất cứ điều gì đến cốt lõi của sự thách thức (timespans máy tính).
JungHwan Min

2
@JungHwanMin Tôi đoán nó không thay đổi nó; nhưng vì tôi rõ ràng đã có nó trong thông số kỹ thuật khi tôi đăng nó, tôi không muốn làm
hỏng

Câu trả lời:


3

APL (Dyalog Unicode) , SBCS 32 byte

Chương trình đầy đủ. Nhắc stdin cho danh sách các cặp Số ngày Quốc tế (như những gì Excel và MATLAB sử dụng). Cả danh sách và cặp có thể được cung cấp theo bất kỳ thứ tự nào, ví dụ (Kết thúc, Bắt đầu). In danh sách đếm đến thiết bị xuất chuẩn.

¯1+⊢∘≢⌸(R,⊢)∊(R←⌊/,⌊/+∘⍳⌈/-⌊/)¨⎕Hãy thử trực tuyến!

Nếu điều này không hợp lệ, một danh sách các cặp (YMD) có thể được chuyển đổi thêm 21 byte, tổng cộng là 53:

¯1+⊢∘≢⌸(R,⊢)∊(R⌊/,⌊/+∘⍳⌈/-⌊/)¨{2⎕NQ#'DateToIDN'⍵}¨¨⎕Hãy thử trực tuyến!


 giao diện điều khiển nhanh chóng cho đầu vào được đánh giá

(...  áp dụng các chức năng ngầm sau đây để mỗi cặp

⌊/ mức tối thiểu (giảm tối thiểu), tức là ngày bắt đầu

⌈/- mức tối đa (tức là ngày kết thúc) trừ đi

⌊/+∘⍳ ngày bắt đầu cộng với phạm vi từ 1 đến đó

⌊/, ngày bắt đầu trước đó

R← gán chức năng này cho R(cho R ange)

ε nlist (flatten) danh sách các dãy thành một danh sách duy nhất

(... ) áp dụng các chức năng ngầm sau đó:

R,⊢ kết quả của việc áp dụng R(tức là phạm vi ngày) theo sau là đối số
  (điều này đảm bảo rằng mỗi ngày trong phạm vi được thể hiện ít nhất một lần và ngày xuất hiện theo thứ tự được sắp xếp)

...  cho mỗi cặp duy nhất (ngày, chỉ số lần xuất hiện trong dữ liệu), làm:

⊢∘≢ bỏ qua ngày thực tế có lợi cho kiểm đếm của các chỉ số

¯1+ thêm -1 vào các số đo đó (vì chúng tôi đã đặt trước một trong mỗi ngày trong phạm vi)


9

JavaScript (ES6), 85 byte

Lấy đầu vào là một danh sách các Datecặp. Dự kiến ​​danh sách sẽ được sắp xếp theo ngày bắt đầu. Trả về một mảng các số nguyên.

f=(a,d=+a[0][0])=>[a.map(([a,b])=>n+=!(r|=d<b,d<a|d>b),r=n=0)|n,...r?f(a,d+864e5):[]]

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

hoặc 84 byte nếu chúng ta có thể lấy dấu thời gian JS làm đầu vào (như được đề xuất bởi @Shaggy)



Lưu một byte bằng cách lấy các giá trị nguyên thủy làm đầu vào: TIO
Shaggy

7

JavaScript, 75 73 byte

Lấy đầu vào là một mảng được sắp xếp các mảng của các cặp nguyên thủy ngày, xuất ra một đối tượng trong đó các khóa là nguyên hàm của mỗi ngày và các giá trị đếm của các ngày đó trong phạm vi.

a=>a.map(g=([x,y])=>y<a[0][0]||g([x,y-864e5],o[y]=~~o[y]+(x<=y)),o={})&&o

Thử nó


Tôi đã làm việc trên phiên bản 60 byte này cho đến khi được xác nhận rằng những ngày không xuất hiện trong bất kỳ phạm vi nào phải được đưa vào để vội vàng cập nhật nó vào giải pháp ở trên.

a=>a.map(g=([x,y])=>x>y||g([x+864e5,y],o[x]=-~o[x]),o={})&&o

Dùng thử trực tuyến (hoặc với ngày có thể đọc được của con người trong đầu ra )


Dường như ES6 xác định một thứ tự khóa cho các đối tượng JS ( stackoverflow.com/a/31102605/8127 ), thứ tự chèn cơ bản cho các chuỗi ký tự và chuỗi ký hiệu (và Nodejs của TIO dường như tuân theo điều đó: tinyurl.com/ybjqtd89 ). Và nói chung, ý kiến ​​của tôi là một chi tiết triển khai (chính là đối tượng ở đây) không nên ra lệnh giải thích các quy tắc thách thức, nhưng tôi sẽ chờ bài Meta.
- Phục hồi Monica

6

Octave , 63 byte

@(x)histc(t=[cellfun(@(c)c(1):c(2),x,'un',0){:}],min(t):max(t))

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

Bây giờ thật là xấu xí!

Giải trình:

Lấy đầu vào là một mảng ô của datenumcác phần tử (nghĩa là một chuỗi được "2001-01-01"chuyển đổi thành giá trị số, trông như thế này:

{[d("2001-01-01") d("2001-01-01")]
[d("2001-01-01") d("2001-01-03")]
[d("2001-01-01") d("2001-01-02")]
[d("2001-01-03") d("2001-01-03")]
[d("2001-01-05") d("2001-01-05")]};

nơi d()là chức năng datenum. Sau đó chúng tôi sử dụng cellfunđể tạo các ô có phạm vi từ cột đầu tiên đến cột thứ hai cho mỗi hàng đó. Chúng tôi ghép các phạm vi này theo chiều ngang, để chúng tôi có một vectơ ngang dài với tất cả các ngày.

Sau đó, chúng tôi tạo ra một biểu đồ sử dụng histccác giá trị này, với các thùng được đưa ra bởi phạm vi giữa ngày thấp nhất và ngày cao nhất.


5

R , 75 byte

function(x,u=min(x):max(x))rowSums(outer(u,x[,1],">=")&outer(u,x[,2],"<="))

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

Đầu vào là một ma trận có cột đầu tiên là Bắt đầu và cột thứ hai là Kết thúc. Giả sử Bắt đầu <= Kết thúc nhưng không yêu cầu ngày bắt đầu được sắp xếp.


Điều này theo như tôi đã có thể cố gắng sao chép câu trả lời Octave của Stewie Griffin ... tôi đang làm gì sai?
JayCe

đó là vì cách R thực hiện các thùng của nó hist; bạn có thể làm c(-25668,min(x):max(x))-25568trước đó 1900nhưng điều này kết thúc dài hơn câu trả lời được đề xuất của bạn. Điều đó đang được nói, có một cách tốt hơn để tạo ra ngày hơnapply ; Tôi có một cái ở mức 68 byte và tôi không tìm thấy thời gian để tự đăng nó.
Giuseppe

Ah, không, thực sự, sử dụng (min(x)-1):max(x)và nó sẽ hoạt động như mong đợi; sau đó nếu bạn có thể tìm thấy applycách để tạo ngày, bạn có thể lấy số này thành 63 byte và buộc câu trả lời Octave.
Giuseppe

@Giuseppe Bạn nên đăng nó dưới dạng câu trả lời riêng :)
JayCe

đã đăng :-) Tôi phải thừa nhận, tôi đã sử dụng tablefactortrước đó là cách sử dụng ban đầu của tôi Mapvới 68 byte, nhưng histlà một cách tiếp cận gọn gàng mà tôi luôn quên, có lẽ vì thật khó chịu khi đặt các thùng đúng cách (như chúng ta đã thấy )
Giuseppe

4

Màu đỏ , 174 byte

func[b][m: copy #()foreach[s e]b[c: s
until[m/(c): either none = v: m/(c)[1][v + 1]e < c: c + 1]]c: first sort b
until[print[either none = v: m/(c)[0][v]](last b)< c: c + 1]]

Khá dài và thực hiện theo nghĩa đen.

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

Có thể đọc được

f: func [ b ] [
    m: copy #()
    foreach [ s e ] b [
        c: s
        until [
            m/(c): either none = v: m/(c) [ 1 ] [ v + 1 ]   
            e < c: c + 1
        ]      
    ]
    c: first sort b
    until[
        print [ either none = v: m/(c) [ 0 ] [ v ] ]
        ( last b ) < c: c + 1
    ]      
]

4

Groovy, 142 byte

{a={Date.parse('yyyy-mm-dd',it)};b=it.collect{a(it[0])..a(it[1])};b.collect{c->b.collect{it}.flatten().unique().collect{it in c?1:0}.sum()}}

Hay nói, là một tài tài của, qua, qua, qua một khác, qua giữ, qua, qua một tài khác, qua, khác qua, qua, khi khác mới mới đăng,, mới mới đăng, mới đăng, mới đăng, mới đăng, mới cam mới, mới đăng, mới đăng, mới đăng ký đăng cam

Định dạng:

 {                                   // Begin Closure
    a={Date.parse('yyyy-mm-dd',it)}; // Create closure for parsing dates, store in a().
    b=it.collect{                    // For each input date pair...
        a(it[0])..a(it[1])           // Parse and create date-range.
    };
    b.collect{                       // For each date range...
        c->
        b.collect{                   // For each individual date for that range...
           it
        }.flatten().unique().collect{ // Collect unique dates.
            it in c?1:0
        }.sum()                      // Occurrence count.
    }
}

4

Python 2 , 114 87 93 byte

-27 byte nhờ Jonathan Allan
+6 byte nhờ vào chủ nhật

Lấy đầu vào là danh sách các cặp đối tượng datetime.
Giả sử rằng cặp đầu tiên bắt đầu với ngày thấp nhất.

def F(I):
 d=I[0][0]
 while d<=max(sum(I,[])):print sum(a<=d<=b for a,b in I);d+=type(d-d)(1)

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


dayslà đối số mặc định cho timedelta.
Jonathan Allan

... trong thực tế, tôi nghĩ bạn có thể thả from datetime import*và thay thế d+=timedelta(days=1)bằng d+=type(d-d)(1)kể từ khi đầu vào là đã dates. 87 byte
Jonathan Allan

1
Điều này dường như cho rằng bắt đầu của phạm vi đầu tiên là ngày thấp nhất VÀ kết thúc của phạm vi cuối cùng là cao nhất - nhưng tôi nghĩ điều đó đôi khi không thể xảy ra ngay cả khi OP cho phép chúng tôi lấy đầu vào được sắp xếp. Ví dụ. nếu đầu vào là [(2001-01-01, 2001-01-05), (2001-01-02, 2001-01-03)]. Trừ khi OP cho phép chúng tôi phân tách và sắp xếp lại các phạm vi này trong quá trình tiền xử lý (có vẻ như không thể), đầu vào này không thể được xử lý theo mã này một cách chính xác.
- Phục hồi Monica

@sundar Vâng, tôi thấy những gì bạn đang nói về. Tôi đã cập nhật giải pháp để xử lý việc này. Cảm ơn!
Xác chết

3

Ngôn ngữ Wolfram (Mathicala) , 62 byte

Lookup[d=DayRange;Counts[Join@@d@@@#],#[[1,1]]~d~#[[-1,1]],0]&

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

+35 byte vì OP chỉ định rằng 0 phải được đưa vào đầu ra.

Nếu bỏ qua một mục trong từ điển được cho phép, 27 byte

Counts[Join@@DayRange@@@#]&

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

Việc xây dựng trong DayRangechấp nhận hai DateObjects (hoặc một chuỗi tương đương) và kết quả đầu ra một danh sách các Datesgiữa những ngày này (bao gồm).


3

R , 65 63 byte

function(x)hist(unlist(Map(`:`,x[,1],x[,2])),min(x-1):max(x))$c

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

Đây là sự hợp tác giữa JayCe và tôi, đưa ra câu trả lời của Stewie Griffin cho R.

Để trích dẫn JayCe:

Đầu vào là một ma trận có cột đầu tiên là Bắt đầu và cột thứ hai là Kết thúc. Giả sử Bắt đầu <= Kết thúc nhưng không yêu cầu ngày bắt đầu được sắp xếp.

Có thể, $clà không cần thiết nhưng nó không hoàn toàn theo tinh thần của thử thách nên tôi đã đưa nó vào.


1
Tối thiểu (x-1) cho 2 byte?
JayCe

^ Ý tôi là thế này
JayCe

@JayCe vâng, tốt đẹp! Tôi định quay lại chuyện này sớm hơn nhưng tôi quên mất.
Giuseppe

3

Powershell, 122 121 118 113 byte

filter d{0..($_[-1]-($s=$_[0])).Days|%{$s.AddDays($_)}}$c=@{};$args|d|%{++$c.$_};,($c.Keys.Date|sort)|d|%{+$c.$_}

lưu nó như là count-timespan.ps1. Kịch bản thử nghiệm:

.\count-timespan.ps1 `
    @([datetime]"2001-01-01", [datetime]"2001-01-01")`
    @([datetime]"2001-01-01", [datetime]"2001-01-03")`
    @([datetime]"2001-01-01", [datetime]"2001-01-02")`
    @([datetime]"2001-01-03", [datetime]"2001-01-03")`
    @([datetime]"2001-01-05", [datetime]"2001-01-05")

Giải trình

filter d{                           # define a function with a pipe argument (it's expected that argument is an array of dates)
    0..($_[-1]-($s=$_[0])).Days|%{  # for each integer from 0 to the Days
                                    # where Days is a number of days between last and first elements of the range
                                    # (let $s stores a start of the range)
        $s.AddDays($_)              # output to the pipe a date = first date + number of the current iteration
    }                               # filter returns all dates for each range
}                                   # dates started from first element and ended to last element
$c=@{}                              # define hashtable @{key=date; value=count}
$args|d|%{++$c.$_}                  # count each date in a array of arrays of a date
,($c.Keys.Date|sort)|d|%{+$c.$_}    # call the filter via pipe with the array of sorted dates from hashtable keys

# Trace:
# call d @(2001-01-01, 2001-01-01) @(2001-01-01, 2001-01-03) @(2001-01-01, 2001-01-02) @(2001-01-03, 2001-01-03) @(2001-01-05, 2001-01-05)
# [pipe]=@(2001-01-01, 2001-01-01, 2001-01-02, 2001-01-03, 2001-01-01, 2001-01-02, 2001-01-03, 2001-01-05)
# $c=@{2001-01-03=2; 2001-01-01=3; 2001-01-05=1; 2001-01-02=2}
# call d @(2001-01-01, 2001-01-02, 2001-01-03, 2001-01-05)
# [pipe]=@(2001-01-01, 2001-01-02, 2001-01-03, 2001-01-04, 2001-01-05)
# [output]=@(3, 2, 2, 0, 1)

Cảm ơn! $cnt.Keys.Datetất nhiên.
mê mẩn

-3 byte: được functionthay thế bằng scriptblock. mã đánh gôn và vô danh được thử nghiệm.
mazzy

-5 byte: được scriptblockthay thế trên filter. Cuộc gọi của a filternhỏ gọn hơn.
mê mẩn

3

J, 43 byte

(],.[:+/@,"2="{~)&:((>./(]+i.@>:@-)<./)"1),

đầu vào là danh sách các cặp số nguyên, trong đó mỗi số nguyên là phần bù từ bất kỳ 0 ngày chung tùy ý.

vô dụng

(] ,. [: +/@,"2 ="{~)&:((>./ (] + i.@>:@-) <./)"1) ,

giải trình

cấu trúc là:

(A)&:(B) C
  • C tạo ra một cái móc cung cấp cho động từ chính A&:Bở đầu vào bên trái và đầu vào được làm phẳng ở bên phải
  • B aka ((>./ (] + i.@>:@-) <./)"1)lấy tối thiểu và tối đa của một danh sách và trả về phạm vi kết quả, và hành động với thứ hạng 1. do đó, nó đưa ra tổng phạm vi ở bên phải và các phạm vi riêng lẻ ở bên trái.
  • Sau đó, A sử dụng =với thứ hạng "0 _(nghĩa là thứ hạng {) để đếm số lần mỗi đầu vào xuất hiện trong bất kỳ phạm vi nào. cuối cùng nó kéo hàng năm với những tính đó.

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


2

JavaScript (Node.js) , 80 byte

(a,u=[])=>a.map(g=([p,q])=>p>q||g([p,q-864e5],u[z=(q-a[0][0])/864e5]=-~u[z]))&&u

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

undefinedcó nghĩa là không; Yếu tố đầu tiên nên bắt đầu sớm nhất

(a,u=[])=>a.map(g=([p,q])=>p>q||g([p,q-1],u[z=(q-a[0][0])/864e5]=-~u[z]))&&u ngắn hơn nếu bạn chỉ nhìn thấy các phần tử và sử dụng nhiều ngăn xếp hơn


6
Bạn nên yêu cầu xác nhận rằng thay thế một giá trị khác 0là chấp nhận được.
Xù xì

1

Ruby , 70 byte

->s{f,=s.min;(p s.count{|a,b|(f-a)*(f-b)<=0};f+=86400)until f>s[0][1]}

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

Đầu vào:

Mảng các cặp ngày, được sắp xếp theo ngày kết thúc giảm dần.


1

R (70)

function(x)(function(.)tabulate(.-min(.)+1))(unlist(Map(seq,x$S,x$E,"d")))

Giả sử khung dữ liệu xcó hai cột ( StartEndhoặc có thể SE) có ngày (lớp Date).

Dùng thử trực tuyến


Xin chào, bạn có thể bao gồm các liên kết TIO (xem các câu trả lời khác) với một ví dụ đầu vào / đầu ra không? Nó không gian lận để bao gồm một gói, nhưng library(magrittr)cần được bao gồm trong số byte.
JayCe

Ngoài ra, theo đệ trình đồng thuận cần phải có đầy đủ chức năng hoặc chương trình, không phải đoạn trích, vì vậy nếu bạn đi với một hàm có đối số duy nhất là xcâu trả lời của bạn bắt đầu bằng function(x)và sau đó là phần thân của hàm.
JayCe

1

Julia 0,6 , 77 byte

M->[println(sum(dM[r,1]:M[r,2]for r1:size(M,1)))for dM[1]:max(M...)]

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

Lấy cảm hứng từ giải pháp Python của @ DeadPossum .

Lấy đầu vào dưới dạng ma trận, trong đó mỗi hàng có hai ngày: ngày bắt đầu và ngày kết thúc của phạm vi đầu vào. Giả sử đầu vào có ngày đầu tiên sớm nhất và mỗi hàng có ngày bắt đầu trước, nhưng giả sử không có sự sắp xếp nào vượt quá giữa các hàng khác nhau.


Giải pháp cũ hơn:

Julia 0,6 , 124 byte

R->(t=Dict();[[dkeys(t)?t[d]+=1:t[d]=1 for dg]for gR];[dkeys(t)?t[d]:0 for dmin(keys(t)...):max(keys(t)...)])

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

Chấp nhận đầu vào như một mảng của phạm vi ngày. Không giả định bất kỳ sự sắp xếp giữa các phạm vi khác nhau trong mảng.

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.