เวลาทศนิยมของการแปลงวัน


15

บทนำ

เวลากำลังสับสน หกสิบวินาทีถึงหนึ่งนาที, หกสิบนาทีถึงหนึ่งชั่วโมง, ยี่สิบสี่ชั่วโมงต่อวัน (และไม่ต้องพูดถึงที่น่ารำคาญ am / pm!)

ทุกวันนี้ไม่มีที่ว่างเหลืออยู่สำหรับความงี่เง่าดังนั้นเราจึงตัดสินใจเลือกทางเลือกที่เหมาะสมเพียงอย่างเดียวคือวันทศนิยม! กล่าวคือในแต่ละวันจะถือว่า 1 หน่วยทั้งหมดและสิ่งที่สั้นกว่านั้นเขียนเป็นเศษส่วนทศนิยมของวันนั้น ตัวอย่างเช่น: "12:00:00" จะถูกเขียนเป็น "0.5" และ "01:23:45" อาจถูกเขียนเป็น "0.058159"

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

ท้าทาย

เขียนโปรแกรมในภาษาที่คุณเลือกซึ่งกำหนดเวลาที่ทันสมัยในรูปแบบ ISO-8601 ของ "hh: mm: ss" จะส่งคืนหน่วยเศษทศนิยมที่เทียบเท่า ในทำนองเดียวกันเมื่อได้รับเศษทศนิยมโปรแกรมควรส่งคืนเวลาในรูปแบบทันสมัยที่ระบุไว้ในตอนแรก

คุณสามารถกำหนดสมมติฐานต่อไปนี้:

  • อินพุตและเอาต์พุตเวลาที่ทันสมัยสามารถอยู่ในช่วง "00:00:00" ถึง "24:00:00"
  • อินพุตและเอาต์พุตเวลาทศนิยมสามารถอยู่ในช่วงตั้งแต่ "0" ถึง "1" และควรสามารถยอมรับ / ส่งออกได้อย่างน้อย 5 ตำแหน่งทศนิยม (เช่น "0.12345") ความแม่นยำมากขึ้นเป็นที่ยอมรับ
  • โปรแกรมควรทราบทิศทางการแปลงที่จะดำเนินการตามอินพุต
  • คุณไม่สามารถใช้ฟังก์ชัน / ไลบรารีที่เกี่ยวข้องกับเวลา

ผู้ชนะจะถูกกำหนดโดยรหัสที่สั้นที่สุดที่บรรลุเกณฑ์ พวกเขาจะถูกเลือกในหน่วยทศนิยมอย่างน้อย 7 วันหรือหาก / เมื่อมีการส่งที่เพียงพอ

ตัวอย่าง

ต่อไปนี้เป็นตัวอย่างโค้ด JavaScript ที่เขียนไม่ดีสำหรับใช้เป็นตัวอย่าง:

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

อืม ... 60 เกือบ 64 ฉันสงสัยว่าจะเป็นเช่นไรหากมี 64 วินาทีในหนึ่งนาทีและ 64 นาทีต่อชั่วโมง (และ 16 หรือ 32 ชั่วโมงต่อวัน)

1
เราต้องจัดการกับเผ่นวินาทีหรือไม่? ดังนั้น 23:59:60 คือ 1 วินาทีจากวันสิ้น 86401 ที่สอง?
Sparr

1
@ Sparr ไม่ต้องกังวลกับวินาทีกระโดด นี่คืออนาคตที่เราได้ตัดสินใจแล้วว่ามันไร้สาระสักวินาทีที่จะได้รับการพิจารณาว่าเป็นค่าสัมบูรณ์ขณะเดียวกันก็ผูกมันกับความเร็วสัมพัทธ์ของการหมุนของโลก;)
Mwr247

1
@MichaelT มันจะเป็นโปรแกรมเมอร์แห่งโลกแห่งความฝัน = P
Mwr247

1
@ Mwr247 yep DNS TTL มี (มี?) เขตข้อมูลที่เป็นnที่n2 ^ n วินาที ค่าของ '6' จึงมี TTL ประมาณ 1 นาที ค่า '12' มี TTL ประมาณ 1 ชั่วโมง '15' ประมาณ 8 ชั่วโมงเป็นต้น อนุญาตหนึ่งไบต์เพื่อกำหนดการหมดเวลาและให้การควบคุมที่เพียงพอสำหรับเวลาสั้นหรือยาว

คำตอบ:


6

CJam, 58 56 42 ไบต์

ฉันแน่ใจว่ามันยาวเกินไปและสามารถเล่นกอล์ฟได้มาก แต่ที่นี่จะเริ่มสำหรับ:

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

ลองออนไลน์ได้ที่นี่


เฮ้เรามีความคิดคล้าย ๆ กัน
aditsu ออกเพราะ SE นั้นชั่วร้าย

@aditsu โอ้! ไม่เห็นของคุณก่อนอัปเดตของฉันและจากนั้นก็รีบไปส่ง
เครื่องมือเพิ่มประสิทธิภาพ

คุณรู้ว่า .. รู้สึกอิสระที่จะใช้รหัสของฉัน: 86400q':/:d_,({60bd\/}{~*mo60bAfmd2/':*}?ฉันจะลบคำตอบของฉัน moเพื่อให้ 0.058159 แปรรูป 01:23:45
aditsu เลิกเพราะ SE เป็นความชั่วร้าย

3

Python 2, 159 150 141 + 2 = 143 Bytes

ทางออกที่ตรงไปตรงมาอาจสั้นกว่านี้มาก จะทำงานกับมัน

เพิ่มสองไบต์ลงในบัญชีสำหรับอินพุตที่ต้องใส่ใน "s นอกจากนี้ Sp3000 ยังชี้ให้เห็นปัญหาของการตีความเลขฐานแปด eval () และแสดงวิธีการย่อการจัดรูปแบบใช้แผนที่ () และลบการพิมพ์หนึ่งรายการ

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

ตรวจสอบ ideone ที่นี่


2

Javascript ( ES6 ), 116 110 ไบต์

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

แสดงความคิดเห็น:

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:00ผลิต1แต่สิ่งที่ตรงกันข้ามนั้นไม่เป็นความจริง
rink.attendant.6

@ rink.attendant.6 คงที่
ขีดล่าง

2

Python 3: 143 Bytes

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)

ไบต์เดียวกันนับเป็นวิธีการแก้ปัญหาหลาม 2 แต่ดูเหมือนว่าเราใช้วิธีการที่แตกต่างกันในวิชาคณิตศาสตร์


2

Julia, 152 143 142 ไบต์

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

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

สิ่งนี้จะสร้างฟังก์ชันที่ไม่มีชื่อที่ยอมรับสตริงหรือหมายเลขทศนิยม 64 บิตและส่งกลับตัวเลขหรือสตริงลอยตัว 64 บิตตามลำดับ f=x->...เรียกว่าให้มันชื่อเช่น

คำอธิบาย Ungolfed +:

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

ตัวอย่าง:

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 ไบต์

โปรแกรม C เต็มรูปแบบ รับอินพุตบน stdin และเอาต์พุตเมื่อ stdout

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 และแสดงความคิดเห็น:

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

การใช้งานที่ชัดเจนของ scanf และ f%
ผู้ใช้บางส่วน

D'โอ้! ฉันหมายถึง "ฉลาด"
ผู้ใช้บางคน

2

J, 85 ไบต์

ผล:

T '12: 00: 00 '
0.5

T 0.5
12 0 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.'

รวม 85


ยินดีต้อนรับสู่เว็บไซต์! ฉันแก้ไขโพสต์ของคุณเพื่อให้รหัสจะแสดงเป็นรหัส สำหรับการเชื่อมโยงออนไลน์ที่ดีที่สุดที่ฉันรู้คือติ้ว ฉันจะให้ลิงก์แก่คุณ แต่ฉันไม่มีประสบการณ์กับ J ดังนั้นฉันจึงไม่รู้วิธีที่เหมาะสมในการเรียกใช้ นอกจากนี้ดูเหมือนว่าจะเป็น 91 ไบต์เมื่อคุณรวมบรรทัดแรกและบรรทัดสุดท้าย ถูกต้องหรือไม่
DJMcMayhem

ขอบคุณสำหรับความช่วยเหลือของคุณ! โปรแกรม [a = ... to end.] คือ 77 ชื่อคือ 10 ตัวยุติคือ 1 ดังนั้นจึงทำให้ 88 ด้วยฟีดสามบรรทัดที่ทำให้ 91! ฉันจะทำงานกับมัน: o)
Richard Donovan

ตอนนี้ลงไปที่ 85 ไบต์หนึ่งซับ!
Richard Donovan

1

Javascript, 194 192 190 188 ไบต์

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 ไบต์

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

น่าเสียดายที่ไม่อนุญาตให้ใช้ฟังก์ชันที่เกี่ยวข้องกับเวลา (เช่น "วันที่" และ "toTimeString") มิฉะนั้นเป็นวิธีที่รัดกุมมากขึ้นในการทำ =)
Mwr247

@ Mwr247 โอ้ไม่เห็นว่าฉันจะแก้ไขนี้แล้ว
Downgoat

1

C, 156 152 ไบต์

ฉันคิดว่ามันจะเป็นเรื่องง่ายสำหรับซี แต่ก็ยังมีขนาดค่อนข้างใหญ่ :(

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

โปรแกรมทดสอบ:

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

เอาท์พุท:

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

1

PHP, 70 69 ไบต์

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

รับอินพุตจากอาร์กิวเมนต์บรรทัดคำสั่งพิมพ์ไปที่ STDOUT:

ถ้าใส่มีลำไส้ใหญ่, แปลงเป็นเวลายูนิกซ์และหารด้วย (วินาทีต่อวัน),
ค่าอื่นที่เป็นตัวเลข multply กับ (วินาทีต่อวัน) hh:mm:ssและรูปแบบเวลายูนิกซ์ไป



0

Excel, 178 ไบต์

=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)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.