Chuyển đổi thời gian thập phân trong ngày


15

Giới thiệu

Thời gian thật khó hiểu. Sáu mươi giây đến một phút, sáu mươi phút đến một giờ, hai mươi bốn giờ đến một ngày (và không đề cập đến đó là sáng / chiều!).

Ngày nay không có chỗ cho sự điên cuồng như vậy, vì vậy chúng tôi đã quyết định áp dụng phương án thay thế hợp lý duy nhất: ngày thập phân! Điều đó có nghĩa là, mỗi ngày được coi là 1 đơn vị, và bất cứ điều gì ngắn hơn được viết dưới dạng một phần thập phân của ngày đó. Vì vậy, ví dụ: "12:00:00" sẽ được viết là "0,5" và "01:23:45" có thể được viết là "0,058159".

Bởi vì sẽ mất thời gian để làm quen với hệ thống mới, bạn có nhiệm vụ viết một chương trình có thể chuyển đổi giữa chúng theo cả hai hướng.

Thử thách

Viết chương trình bằng ngôn ngữ bạn chọn, trong thời gian hiện đại ở định dạng ISO-8601 là "hh: mm: ss", sẽ trả về đơn vị phân số thập phân tương đương. Tương tự, với một phần thập phân, chương trình sẽ trả về thời gian ở định dạng hiện đại được chỉ định ban đầu.

Bạn có thể đưa ra các giả định sau:

  • Đầu vào và đầu ra thời gian hiện đại có thể dao động từ "00:00:00" đến "24:00:00"
  • Đầu vào và đầu ra thời gian thập phân có thể nằm trong khoảng từ "0" đến "1" và có thể chấp nhận / đầu ra tối thiểu 5 vị trí thập phân (chẳng hạn như "0.12345"). Độ chính xác cao hơn là chấp nhận được
  • Chương trình sẽ có thể biết hướng chuyển đổi nào sẽ thực hiện dựa trên đầu vào
  • Bạn không thể sử dụng các chức năng / thư viện liên quan đến thời gian

Người chiến thắng sẽ được xác định bởi mã ngắn nhất hoàn thành các tiêu chí. Chúng sẽ được chọn trong ít nhất 7 đơn vị ngày thập phân hoặc nếu / khi đã có đủ số lần gửi.

Ví dụ

Đây là một đoạn mã JavaScript được viết kém (cố ý) được sử dụng làm ví dụ:

function decimalDay(hms) {
    var x, h, m, s;
    if (typeof hms === 'string' && hms.indexOf(':') > -1) {
        x = hms.split(':');
        return (x[0] * 3600 + x[1] * 60 + x[2] * 1) / 86400;
    }
    h = Math.floor(hms * 24) % 24;
    m = Math.floor(hms * 1440) % 60;
    s = Math.floor(hms * 86400) % 60;
    return (h > 9 ? '' : '0') + h + ':' + (m > 9 ? '' : '0') + m + ':' + (s > 9 ? '' : '0') + s;
}
decimalDay('02:57:46'); // 0.12344907407407407
decimalDay('23:42:12'); // 0.9876388888888888
decimalDay(0.5); // 12:00:00
decimalDay(0.05816); // 01:23:45

Hmm ... 60 là gần 64. Tôi tự hỏi thời gian sẽ như thế nào nếu có 64 giây trong một phút và 64 phút trong một giờ (và 16 hoặc 32 giờ trong một ngày).

1
Chúng ta có phải xử lý giây nhuận không? vậy 23:59:60 là 1 giây từ cuối ngày thứ 86401?
Sparr

1
@Sparr Không cần phải lo lắng về giây nhuận. Đây là tương lai, nơi chúng tôi đã quyết định rằng thật ngớ ngẩn trong một giây được coi là một giá trị tuyệt đối đồng thời buộc nó vào tốc độ tương đối của vòng quay của trái đất;)
Mwr247

1
@MichaelT Đó là một thế giới mơ ước của các lập trình viên = P
Mwr247

1
@ Mwr247 vâng. DNS TTL đã (có?) Một lĩnh vực đó là nnơi nlà 2 ^ n giây. Vì vậy, giá trị '6' có chỉ số TTL khoảng 1 phút. Giá trị '12' có TTL khoảng 1 giờ. "15" là khoảng 8 giờ và cứ thế. Nó cho phép một byte để xác định thời gian chờ và cung cấp cho bạn đủ quyền kiểm soát trong thời gian ngắn hoặc dài.

Câu trả lời:


6

CJam, 58 56 42 byte

Tôi chắc chắn rằng điều này là quá dài và có thể được chơi golf rất nhiều. Nhưng ở đây dành cho người mới bắt đầu:

86400q':/:d_,({60bd\/}{~*i60b{s2Ue[}%':*}?

Dùng thử trực tuyến tại đây


Heh, chúng tôi có ý tưởng tương tự
aditsu

@aditsu ơi! Không thấy của bạn trước khi cập nhật của tôi và sau đó vội vàng đi lại.
Tối ưu hóa

Bạn biết những gì .. cứ thoải mái sử dụng mã của tôi : 86400q':/:d_,({60bd\/}{~*mo60bAfmd2/':*}?, Tôi đang xóa câu trả lời của mình. Chính movì vậy mà 0,058159 chuyển đổi thành 01:23:45
aditsu

3

Python 2, 159 150 141 + 2 = 143 byte

Giải pháp đơn giản, có lẽ có thể ngắn hơn nhiều. Sẽ làm việc trên nó.

Đã thêm hai byte vào tài khoản cho đầu vào cần được đính kèm trong "Ngoài ra, Sp3000 đã chỉ ra một vấn đề với các octals diễn giải eval () và chỉ ra cách rút ngắn định dạng, sử dụng map () và xóa một bản in.

n=input();i=float;d=864e2
if':'in n:a,b,c=map(i,n.split(':'));o=a/24+b/1440+c/d
else:n=i(n);o=(':%02d'*3%(n*24,n*1440%60,n*d%60))[1:]
print o

Kiểm tra nó trên ideone ở đây.


2

Javascript ( ES6 ), 116 110 byte

f=x=>x[0]?([h,m,s]=x.split(':'),+s+m*60+h*3600)/86400:[24,60,60].map(y=>('0'+~~(x*=y)%60).slice(-2)).join(':')


// for snippet demo:
i=prompt();
i=i==+i?+i:i; // convert decimal string to number type
alert(f(i))

Đã bình luận:

f=x=>
    x[0] ? // if x is a string (has a defined property at '0')
        ([h, m, s] = x.split(':'), // split into hours, minutes, seconds
        +s + m*60 + h*3600) // calculate number of seconds
        / 86400 // divide by seconds in a day
    : // else
        [24, 60, 60]. // array of hours, minutes, seconds
        map(y=> // map each with function
            ('0' + // prepend with string zero
                ~~(x *= y) // multiply x by y and floor it
                % 60 // get remainder
            ).slice(-2) // get last 2 digits
        ).join(':') // join resulting array with colons

24:00:00tạo ra 1nhưng điều ngược lại là không đúng
rink.attguard.6

@ rink.attguard.6 đã sửa
nderscore

2

Python 3: 143 byte

i,k,l,m=input(),60,86400,float
if'.'in i:i=m(i)*l;m=(3*':%02d'%(i/k/k,i/k%k,i%k))[1:]
else:a,b,c=map(m,i.split(':'));m=(a*k*k+b*k+c)/l
print(m)

Cùng một số byte với giải pháp python 2 nhưng có vẻ như chúng ta đã thực hiện các cách tiếp cận khác nhau đối với toán học.


2

Julia, 152 143 142 byte

Chà, tôi đã cập nhật cách tiếp cận của mình để bớt "Julian", như họ nói, vì lợi ích của việc chơi golf. Để biết cách tiếp cận tốt hơn (dù ít súc tích hơn), hãy xem lịch sử sửa đổi.

x->(t=[3600,60,1];d=86400;typeof(x)<:String?dot(int(split(x,":")),t)/d:(x*=d;o="";for i=t q,x=x÷i,x%i;o*=lpad(int(q),2,0)*":"end;o[1:end-1]))

Điều này tạo ra một hàm không tên chấp nhận một chuỗi hoặc số dấu phẩy động 64 bit và trả về một số hoặc dấu phẩy động 64 bit tương ứng. Để gọi nó, đặt tên cho nó, vd f=x->....

Ungolfed + giải thích:

function f(x)
    # Construct a vector of the number of seconds in an hour,
    # minute, and second
    t = [3600, 60, 1]

    # Store the number of seconds in 24 hours
    d = 86400

    # Does the type of x inherit from the type String?
    if typeof(x) <: String
        # Compute the total number of observed seconds as the
        # dot product of the time split into a vector with the
        # number of seconds in an hour, minute, and second
        s = dot(int(split(x, ":")), t)

        # Get the proportion of the day by dividing this by
        # the number of seconds in 24 hours
        s / d
    else
        # Convert x to the number of observed seconds
        x *= d

        # Initialize an output string
        o = ""

        # Loop over the number of seconds in each time unit
        for i in t
            # Set q to be the quotient and x to be the remainder
            # from x divided by i
            q, x = divrem(x, i)

            # Append q to o, padded with zeroes as necessary
            o *= lpad(int(q), 2, 0) * ":"
        end

        # o has a trailing :, so return everything up to that
        o[1:end-1]
    end
end

Ví dụ:

julia> f("23:42:12")
0.9876388888888888

julia> f(0.9876388888888888)
"23:42:12"

julia> f(f("23:42:12"))
"23:42:12"

2

C, 137 byte

Chương trình C đầy đủ. Đưa đầu vào vào stdin và đầu ra trên thiết bị xuất chuẩn.

main(c){float a,b;scanf("%f:%f:%d",&a,&b,&c)<3?c=a*86400,printf("%02d:%02d:%02d",c/3600,c/60%60,c%60):printf("%f",a/24+b/1440+c/86400.);}

Ungolfed và bình luận:

int main() {
    // b is float to save a . on 1440
    float a,b;
    // c is int to implicitly cast floats
    int c;

    // If the input is hh:mm:ss it gets splitted into a, b, c
    // Three arguments are filled, so ret = 3
    // If the input is a float, it gets stored in a
    // scanf stops at the first semicolon and only fills a, so ret = 1
    int ret = scanf("%f:%f:%d", &a, &b, &c);

    if(ret < 3) {
        // Got a float, convert to time
        // c = number of seconds from 00:00:00
        c = a * 86400;
        printf("%02d:%02d:%02d", c/3600, c/60 % 60, c%60);
    }
    else {
        // a = hh, b = mm, c = ss
        // In one day there are:
        // 24 hours
        // 1440 minutes
        // 86400 seconds
        printf("%f", a/24 + b/1440 + c/86400.);
    }
}

Việc sử dụng scanf và% f rất rõ ràng
một số người dùng

Ôi! Tôi có nghĩa là "thông minh".
một số người dùng

2

J, 85 byte

Các kết quả:

T '12: 00: 00 '
0,5

T 0,5
12 0 0

T '12: 34: 56 '
0,524259

T 0,524259
12 34 56

T=:3 :'a=.86400 if.1=#y do.>.(24 60 60#:y*a)else.a%~+/3600 60 1*".y#~#:192 24 3 end.'

Tổng số 85


Chào mừng đến với trang web! Tôi đã chỉnh sửa bài viết của bạn để mã sẽ được hiển thị dưới dạng mã. Đối với một liên kết trực tuyến, thứ tốt nhất tôi biết là TIO . Tôi sẽ cung cấp cho bạn một liên kết, nhưng tôi không có kinh nghiệm với J, vì vậy tôi không biết cách nào để gọi nó đúng. Ngoài ra, đây có vẻ là 91 byte khi bạn bao gồm các dòng đầu tiên và cuối cùng. Điều này có đúng không?
DJMcMayhem

Cảm ơn bạn đã giúp đỡ! Chương trình [a = ... to end.] Is 77. Tiêu đề là 10. Terminator là 1, do đó tạo ra 88. Với ba nguồn cấp dữ liệu tạo ra 91! Tôi sẽ làm việc với nó: o)
Richard Donovan

Bây giờ xuống đến một byte 85 byte!
Richard Donovan

1

Javascript, 194 192 190 188 byte

function(z){if(isNaN(z)){x=z.split(':');return x[0]/24+x[1]/1440+x[2]/86400}h=(z*24)|0;h%=24;m=(z*1440)|0;m%=60;s=(z*86400)|0;s%=60;return""+(h>9?'':0)+h+':'+(m>9?'':0)+m+':'+(s>9?'':0)+s}

1

JavaScript ES6, 98 130 byte

s=>s==+s?'246060'.replace(/../g,l=>':'+('0'+~~(s*=+l)%60).slice(-2)).slice(1):s.split`:`.reduce((a,b)=>+b+(+a)*60)*1/864e2;f(0.5);

Thật không may, các chức năng liên quan đến thời gian (như "Ngày" và "toTimeString") không được phép trong thử thách này.
Mặt

@ Mwr247 oh không thấy điều đó, tôi sẽ sửa nó sau đó
Downgoat

1

C, 156 152 byte

Tôi nghĩ rằng nó sẽ dễ dàng cho C. Nhưng cuối cùng vẫn khá lớn. :

n,m=60;d(char*s){strchr(s,58)?printf("%f",(float)(atoi(s)*m*m+atoi(s+3)*m+atoi(s+6))/m/m/24):printf("%02d:%02d:%02d",(n=atof(s)*m*m*24)/m/m,n/m%m,n%m);}

Chương trình kiểm tra:

#include <stdio.h>
#include <stdlib.h>

int n,m=60;
d(char*s)
{
    strchr(s,':') ? 
        printf("%f",(float)(atoi(s)*m*m+atoi(s+3)*m+atoi(s+6))/m/m/24):
        printf("%02d:%02d:%02d",(n=atof(s)*m*m*24)/m/m,n/m%m,n%m);
}

int main()
{
    d("01:23:45");
    printf("\n");
    d("02:57:46");
    printf("\n");
    d("23:42:12");
    printf("\n");
    d("12:00:00");
    printf("\n");
    d("0.5");
    printf("\n");
    d("0.05816");
    printf("\n");
    d("0");
    printf("\n");
    d("1");
    printf("\n");
    return 0;
}

Đầu ra:

0.058160
0.123449
0.987639
0.500000
12:00:00
01:23:45
00:00:00
24:00:00

1

PHP, 70 69 byte

<?=strpos($t=$argv[1],58)?strtotime($t)/86400:date("H:i:s",$t*86400);

lấy đầu vào từ đối số dòng lệnh, in ra STDOUT:

Nếu đầu vào chứa dấu hai chấm, hãy chuyển đổi thành thời gian unix và chia cho (giây mỗi ngày),
khác giá trị số đa số với (giây mỗi ngày) và định dạng thời gian unix thành hh:mm:ss.


1

Perl, 109 108 101 + 6 ( -plaF:cờ) = 107 byte

$_=$#F?($F[0]*60+$F[1]+$F[2]/60)/1440:sprintf"%02d:%02d:%02d",$h=$_*24,$m=($h-int$h)*60,($m-int$m)*60

Sử dụng:

perl -plaF: -e '$_=$#F?($F[0]*60+$F[1]+$F[2]/60)/1440:sprintf"%02d:%02d:%02d",$h=$_*24,$m=($h-int$h)*60,($m-int$m)*60' <<< 01:23:45

Hãy thử nó trên Ideone.


0

Excel, 178 byte

=IF(LEFT(A1,2)="0.",TEXT(FLOOR(A1*24,1),"00")&":"&TEXT(MOD(FLOOR(A1*1440,1),60),"00")&":"&TEXT(MOD(FLOOR(A1*86400,1),60),"00"),((LEFT(A1,2)*60+MID(A1,4,2))*60+RIGHT(A1,2))/86400)
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.