Một năm phân số


8

Kỳ nghỉ PPCG của tôi đã kết thúc: D

Giới thiệu

Thời gian phân số là the year + (the value (minute of year) / number of minutes in the year).

Tính toán ví dụ

Bạn nên cho rằng tháng hai luôn có 28 ngày và năm luôn dài 365 ngày.

Giả sử chúng ta muốn chuyển đổi thời gian: 17:34 3rd March 2013thành thời gian phân số. Đầu tiên, bạn tìm thấy có bao nhiêu phút trong năm 2013: 525600 phút . Hãy gọi nó là x.

Tiếp theo, bạn muốn tìm hiểu đã có bao nhiêu phút kể từ đầu năm 2013. Một vài tính toán nhanh sẽ cho bạn biết rằng câu trả lời là 88894 phút:

Đã có 61 ngày kể từ đầu năm, gấp 1440 lần (số phút trong một ngày) bằng 87840 phút. Trong 17 giờ là 1020 phút (17 * 60). Bây giờ, chúng ta có thể thêm 87840, 1020 và 34 phút để bằng 88894 phút.

Hãy gọi nó là y.

Cuối cùng, bạn chia ycho xvà thêm năm, kết quả là 2013.16912(đến 5 chữ số thập phân).

Đầu vào

Ngày và thời gian sẽ được cung cấp dưới dạng một chuỗi. Chuỗi sẽ có định dạng sau:

YYYY-MM-DD hh:mm 

Thời gian sẽ luôn ở định dạng 24 giờ và năm sẽ luôn nằm trong phạm vi 1900-2050.

Ví dụ

Input:  2016-08-06 23:48
Output: 2016.59723

Input:  2013-03-03 17:34
Output: 2013.16912

Input:  1914-11-11 11:11
Output: 1914.86155

Nếu bạn đang kiếm tiền thưởng, hãy ping tôi trong phần bình luận hoặc trong The Nineteenth Byte .

Thử thách

Tính ngày và thời gian đã cho dưới dạng năm phân số.

Cung cấp tất cả đầu ra cho năm vị trí thập phân (bạn có thể làm tròn bằng bất cứ cách nào bạn muốn: sàn, trần hoặc làm tròn thực sự). Mã ngắn nhất sẽ thắng.

Tiền thưởng

Tôi đang cung cấp một tiền thưởng 100 rep cho chương trình ngắn nhất cũng chấp nhận ngày ở định dạng năm phân số và trả về thời gian ở YYYY-MM-DD hh:mmđịnh dạng. Về bản chất, chương trình (hoặc chức năng) của bạn phải hành động theo cách sau:

f('1914-11-11 11:11') => 1914.86155
f('1914.86155')       => 1914-11-11 11:11
  1. t-clausen.dk - 154 byte
  2. Neil - 183 byte

Bảng xếp hạng


Có lẽ lấy ngày và thời gian làm đầu vào sẽ cho phép các trường hợp thử nghiệm và kiểm tra dễ dàng hơn?
Luis Mendo

Tôi hơi bối rối về việc liệu điều này có tính đến những năm nhuận được đưa ra hay không For this, assume February has 28 days and the year is 365 days long., nhưng cũng vậy... using the Gregorian calendar.
Lemon phá hủy

@DeststallibleWateriwi Không, nó không tính đến năm nhuận
Beta Decay

chúng ta có thể cho hơn năm chữ số thập phân không?
Lemon phá hủy

@DeststallibleWateriwi No
Beta Decay

Câu trả lời:


1

TSQL, 63 byte

Đây là phiên bản ngắn hơn câu trả lời ban đầu của tôi, bởi vì câu trả lời đầu tiên của tôi bao gồm tính toán cho năm nhuận.

DECLARE @ DATETIME ='2016-08-06 23:48'

PRINT LEFT(YEAR(@)+DATEDIFF(mi,0,STUFF(@,1,4,1900))/525600.,10)

Vĩ cầm

Các sql sau đây có thể xử lý cả hai loại đầu vào

TSQL, 154 byte

DECLARE @ VARCHAR(16) ='1914-11-11 11:11'--can be replaced with '1914.86155'

PRINT IIF(isdate(@)=1,LEFT(YEAR(@)+DATEDIFF(mi,0,STUFF(@,1,4,1900))/525600.,10),LEFT(@,4)+RIGHT(CONVERT(CHAR(16),DATEADD(mi,1*RIGHT(@,5)*5.256,0),20),12))

Fiddle kết hợp 1

Kết hợp Fiddle 2


5

JavaScript (ES6), 84 byte

f=
s=>(Date.parse(1970+s.slice(4).replace(/ /,'T')+'Z')/31536e6+parseInt(s)).toFixed(5)
;
<input placeholder=Input oninput=o.value=f(this.value)><input placeholder=Output id=o>

Giả sử không có năm nhuận hoặc DST là bắt buộc, tôi thay thế năm đó bằng năm 1970, Date.parsetrả lại trực tiếp thời gian bù theo mili giây, trong đó có 31536000000vào năm 1970 (hoặc thực sự là bất kỳ năm không có bước nhảy vọt nào khác). Tất cả những gì tôi cần làm sau đó là thêm lại năm và làm tròn đến 5 chữ số thập phân. Chỉnh sửa: Chuyển đổi hai chiều trong 183 178 byte:

f=
s=>/:/.test(s,m=31536e6)?(Date.parse(1970+s.slice(4).replace(/ /,'T')+'Z')/m+parseInt(s)).toFixed(5):s.slice(0,4)+new Date(s.slice(4)*m+3e4).toJSON().slice(4,16).replace(/T/,' ')
;
<input placeholder=Input oninput=o.value=f(this.value)><input placeholder=Output id=o>

Giả sử các chuỗi chứa :định dạng thời gian, được xử lý như trên, nếu không, sẽ chuyển sang năm mili giây, thêm nửa phút cho mục đích làm tròn, chuyển đổi thành một ngày vào năm 1970, trích xuất tháng, ngày, giờ và phút và tiền tố năm gốc.


@ αγ Có, slà đối số của hàm.
Neil

Điều này không cung cấp đầu ra không hợp lệ, bởi vì thách thức rõ ràng yêu cầu tháng hai chỉ có 28 ngày và tổng cộng 365 ngày mỗi năm?
admBorkBork

@TimmyD đôi khi tháng hai có 29 ngày. Giả sử không có nghĩa là không được phép xử lý các năm nhuận một cách chính xác
t-clausen.dk

@ t-clausen.dk Xin lỗi, ý tôi là không nên xử lý năm nhuận
Beta Decay

@ αγ Bây giờ không sử dụng năm nhuận hay DST, và cũng có phiên bản đảo ngược. Điều đó có thỏa đáng không?
Neil

2

Matlab, 132 115 byte

 d=input('');m=cumsum([-1 '# #"#"##"#"'-4]);year(d)+fix((((m(month(d))+day(d))*24+hour(d))*60+minute(d))/5.256)/10^5

Vòng về 0.

Hmmm ... Điều đó khá dài.
Đó là sử dụng một số nội dung, nhưng không phải là hữu ích - vì năm nhuận.

Phân tích chuỗi trực tiếp cung cấp thêm 2 byte giải pháp:

d=sscanf(input(''),'%d%[- :]');m=cumsum([-1 '# #"#"##"#"'-4]);d(1)+fix((((m(d(3))+d(5))*24+d(7))*60+d(9))/5.256)/10^5

Các phiên bản Matlab mới hơn có thể có một số chức năng phân chia tốt hơn, nhưng tôi đang chạy trên 2012a.

Một số byte được lưu nhờ @Luis Mendo


Bạn có thể định nghĩa mảng với [-1 '# #"#"##"#"'-4]để lưu một vài byte. Là yearchức năng tiêu chuẩn vv? Nếu bạn đang sử dụng hộp công cụ, bạn nên chỉ ra nó trong tiêu đề, ví dụ: "Matlab với hộp công cụ tài chính"
Luis Mendo

@LuisMendo Tôi không quen với chú #thích và thậm chí không bao giờ gặp phải nó. Tôi có thể đọc thêm về nó ở đâu (tìm kiếm nhanh trên Google không giúp được gì)? Tôi nghĩ rằng yearvv là các chức năng tiêu chuẩn, nhưng tôi không biết nếu chúng hoạt động giống nhau bên ngoài hộp công cụ (tài liệu) .
pyjama

Đó không phải là ký hiệu đặc biệt. Đây chỉ là một chuỗi với các ký tự có mã ASCII phù hợp để tạo ra các số được yêu cầu. Về các chức năng, tôi không biết, cảm ơn vì đã làm rõ. Matlab 15b dường như không có chúng
Luis Mendo

Ồ, thật thông minh.
pyjama

1

PowerShell v3 +, 131 byte

$t=date $args[0];$a=1440*!!(date "2-29-$($t.year)");"{0:F5}"-f((($t.DayOfYear-1)*1440+$t.TimeOfDay.TotalMinutes-$a)/525600+$t.Year)

Đưa đầu vào $args[0]và chuyển đổi nó Get-Dateđể lưu trữ vào .NET[datetime] định dạng , lưu trữ vào $t. Tính toán xem ngày 29 tháng 2 có tồn tại hay không và $achúng tôi sẽ trừ đi số phút đáng giá của ngày đó (nếu có).

Sau đó, chúng tôi sử dụng -ftoán tử ormat với thông số chuỗi cố định gồm 5 chữ số thập phân để chạy qua phép tính. Sử dụng tích hợp để tính toán .DayOfYear.TotalMinutesđầu vào đã cho, trừ đi $anếu đó là năm nhuận, chia cho525600 tổng số phút và thêm vào đầu vào .Year.

Sẽ khiếu nại (bằng lời nói) với STDERR nếu ngày 29 tháng 2 không tồn tại (xem ví dụ bên dưới), nhưng vì STDERR bị bỏ qua theo mặc định, chúng tôi không lo lắng về điều đó. Ngoài ra, lưu ý rằng PowerShell làm tròn ngân hàng theo mặc định.

Ví dụ

PS C:\Tools\Scripts\golfing> .\fractional-year.ps1 '2016-08-06 23:48'
2016.59724

PS C:\Tools\Scripts\golfing> .\fractional-year.ps1 '2013-03-03 17:34'
Get-Date : Cannot bind parameter 'Date'. Cannot convert value "2-29-2013" to type "System.DateTime". Error: "String was not recognized as a valid DateTime."
At C:\Tools\Scripts\golfing\fractional-year.ps1:7 char:36
+   $t=date $args[0];$a=1440*!!(date "2-29-$($t.year)");"{0:F5}"-f((($t.DayOfYear- ...
+                                    ~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Get-Date], ParameterBindingException
    + FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.GetDateCommand

2013.16913

PS C:\Tools\Scripts\golfing> .\fractional-year.ps1 '1914-11-11 11:11'
Get-Date : Cannot bind parameter 'Date'. Cannot convert value "2-29-1914" to type "System.DateTime". Error: "String was not recognized as a valid DateTime."
At C:\Tools\Scripts\golfing\fractional-year.ps1:7 char:36
+   $t=date $args[0];$a=1440*!!(date "2-29-$($t.year)");"{0:F5}"-f((($t.DayOfYear- ...
+                                    ~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Get-Date], ParameterBindingException
    + FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.GetDateCommand

1914.86155

Luân phiên, với năm nhuận, 119 byte

"{0:F5}"-f((($t=date $args[0]).DayOfYear-1+$t.TimeOfDay.TotalMinutes/1440)/(date "12-31-$($t.year)").DayOfYear+$t.Year)

Nếu chúng tôi làm theo các cài đặt lịch, chúng tôi có thể loại bỏ hàng tá byte vì chúng tôi sẽ không cần phải tính đến $amã gốc ở trên. Điều này cho phép chúng tôi tự di chuyển $tvào biểu thức và chúng tôi sẽ tính toán rõ ràng .DayOfYearcho ngày 31 tháng 12. Mặt khác, theo phương pháp tương tự.


0

Python 3, 163 173 byte

Nhiều byte hơn vì định dạng đầu ra

không sử dụng bất kỳ nội dung ngày nào, như câu trả lời java.

def s(x):z=x[5:10].split("-");v=x[10:].split(":");return int(x[:4])+(sum(([-1,31,28]+[31,30,31,30,31]*2)[:int(z[0])],int(z[1]))*1440+int(v[0])*60+int(v[1]))/525600

dễ đọc hơn một chút

def s(x):
    date=x[5:10].split("-");time=x[10:].split(":")
    return int(x[:4])+(sum(([-1,31,28]+[31,30,31,30,31]*2)[:int(date[0])],int(date[1]))*1440+int(time[0])*60+int(time[1]))/525600

0

Perl 6 ,  107 105  102 byte

{$/=.comb(/\d+/);($0+(sum(|flat(-1,31,28,(31,30,31,30,31)xx 2)[^$1],$2)*1440+$3*60+$4)/525600).fmt: '%.5f'}
{$/=.comb(/\d+/);fmt $0+(sum(|flat(-1,31,28,(31,30,31,30,31)xx 2)[^$1],$2)*1440+$3*60+$4)/525600: '%.5f'}

{$/=.comb(/\d+/);fmt $0+(flat($2-1,31,28,(31,30,31,30,31)xx 2)[^$1].sum*1440+$3*60+$4)/525600: '%.5f'}
{$/=.comb(/\d+/);round $0+(flat($2-1,31,28,(31,30,31,30,31)xx 2)[^$1].sum*1440+$3*60+$4)/525600,.1⁵}

Giải trình:

{
  $/ = .comb(/\d+/); # grab a list of only the digits
  # 「$0」 is short for 「$/[0]」

  fmt

    $0 # year
    +
    (
      flat(
        $2 -1,                     #    days
        31,28,(31,30,31,30,31)xx 2 # -+ months
      )[^$1].sum * 1440            # /
      + $3 * 60                    #    hours
      + $4                         #    minutes
    )
    /
    525600

  : '%.5f' # the 「:」 is used here as 「fmt」 is a method not a subroutine
}

Kiểm tra:

#! /usr/bin/env perl6
use v6.c;
use Test;

# returns Str
my &fractional-year-a = {$/=.comb(/\d+/);fmt $0+(sum(flat($2-1,31,28,(31,30,31,30,31)xx 2)[^$1])*1440+$3*60+$4)/525600: '%.5f'}
# returns Rat
my &fractional-year-b = {$/=.comb(/\d+/);round $0+(sum(flat($2-1,31,28,(31,30,31,30,31)xx 2)[^$1])*1440+$3*60+$4)/525600,.1⁵}

my @tests = (
  '2016-08-06 23:48' => 2016.59723,
  '2013-03-03 17:34' => 2013.16912,
  '1914-11-11 11:11' => 1914.86155,
);

plan +@tests * 2;

for @tests -> $_ ( :key($input), :value($expected) ) {
  is-approx +fractional-year-a($input), +$expected, 1e-5, "a $input => $expected";
  is-approx +fractional-year-b($input), +$expected, 1e-5, "b $input => $expected";
}
1..6
ok 1 - a 2016-08-06 23:48 => 2016.59723
ok 2 - b 2016-08-06 23:48 => 2016.59723
ok 3 - a 2013-03-03 17:34 => 2013.16912
ok 4 - b 2013-03-03 17:34 => 2013.16912
ok 5 - a 1914-11-11 11:11 => 1914.86155
ok 6 - b 1914-11-11 11:11 => 1914.86155
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.