Ondalık Gün Saati Dönüşümü


15

Giriş

Zaman kafa karıştırıcı. Altmış saniyeden bir dakikaya, altmış dakikadan bir saate, yirmi dört saatten bir güne (ve bu sinir bozucu am / pm'den bahsetmiyorum!).

Bugünlerde böyle bir saçmalık için yer yok, bu yüzden tek mantıklı alternatifi kabul etmeye karar verdik: ondalık günler! Yani, her gün 1 tam birim olarak kabul edilir ve daha kısa olan her şey o günün ondalık kısmı olarak yazılır. Yani, örneğin: "12:00:00", "0.5" ve "01:23:45", "0.058159" olarak yazılabilir.

Yeni sisteme alışmak zaman alacağından, aralarında her iki yönde de dönüşüm sağlayabilecek bir program yazmakla görevlendirildiniz.

Meydan okuma

ISO-8601 formatında "ss: dd: ss" biçiminde modern bir zaman verilen, seçtiğiniz dilde bir program yazarak eşdeğer ondalık kesir birimini döndürür. Benzer şekilde, ondalık kesir verildiğinde, program başlangıçta belirtilen modern biçimde zamanı döndürmelidir.

Aşağıdaki varsayımları yapabilirsiniz:

  • Modern zaman girişi ve çıkışı "00:00:00" ile "24:00:00" arasında değişebilir
  • Ondalık zaman girişi ve çıkışı "0" ile "1" arasında değişebilir ve en az 5 ondalık basamağa ("0.12345" gibi) kadar kabul / çıkış yapabilmelidir. Daha fazla hassasiyet kabul edilebilir
  • Program girdiye göre hangi dönüşüm yönünün gerçekleştirileceğini bilmelidir
  • Zamana bağlı işlevleri / kütüphaneleri kullanamazsınız

Kazanan, kriterleri yerine getiren en kısa kodla belirlenir. Bunlar, en az 7 ondalık gün biriminde veya yeterli sayıda gönderildiyse / gönderildiyse seçilecektir.

Örnekler

Örnek olarak kullanılacak (n bilerek) kötü yazılmış bir JavaScript kodu parçası:

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 neredeyse 64. Bir dakikada 64 saniye ve bir saatte 64 dakika (ve günde 16 veya 32 saat) olsaydı zamanın nasıl olacağını merak ediyorum.

1
Artık saniye ile başa çıkmak zorunda mıyız? yani 23:59:60 86401 ikinci günün sonundan 1 saniye?
Sparr

1
@Sparr Artık saniye için endişelenmenize gerek yok. Bu, bir saniye boyunca mutlak bir değer olarak kabul edilmesinin ve aynı zamanda dünyanın dönme hızının göreceli hızına bağlanması için aptalca olduğuna karar verdik;)
Mwr247

1
@MichaelT Bir programcı rüya dünya olurdu = P
Mwr247

1
@ Mwr247 evet. DNS TTL (vardı?) Olmasıdır bir alan nnereye n2 ^ n saniyedir. Yani '6' değeri yaklaşık 1 dakikalık bir TTL'ye sahipti. '12' değerinin TTL değeri yaklaşık 1 saattir. '15' 8 saat kadar sürdü. Bir baytın zaman aşımını tanımlamasına ve kısa veya uzun süreler için yeterli kontrol sağlamasına izin verdi.

Yanıtlar:


6

CJam, 58 56 42 bayt

Bu çok uzun ve çok golf olabilir eminim. Ama işte yeni başlayanlar için:

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

Buradan çevrimiçi deneyin


Heh, benzer fikirlerimiz var
aditsu istifa çünkü SE EVIL

@aditsu Oh !. Benimkini güncellemeden önce seninkini görmedim ve sonra gidip gelmek için acele etti.
Doktor

Biliyor musun .. kodumu kullanmaktan çekinmeyin:, 86400q':/:d_,({60bd\/}{~*mo60bAfmd2/':*}?cevabımı siliyorum. moO 0.058159 dönüştürür 01:23:45 etmek böyledir
aditsu GD KÖTÜ çünkü çıkın

3

Piton 2, 159 , 150 141 + 2 = 143 bayt

Basit çözüm, muhtemelen çok daha kısa olabilir. Üzerinde çalışacak.

"S içine girilmesi gereken girdiyi hesaba katmak için iki bayt eklendi. Ayrıca, Sp3000 eval () sekizlik yorumlama ile ilgili bir sorun gösterdi ve biçimlendirmeyi kısaltmak, map () kullanmak ve bir baskıyı kaldırmak için bir yol gösterdi.

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

Burada ideone üzerinde kontrol edin.


2

JavaScript ( ES6 ), 116 110 bayt

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

Yorumlananlar:

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üretir, 1ancak tersi doğru değildir
rink.attendant.6

@ rink.attendant.6 sabit
nderscore

2

Python 3: 143 Bayt

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)

Python 2 çözümü ile aynı bayt sayımı, ancak matematiğe farklı yaklaşımlar uyguladık.


2

Julia 152 143 142 bayt

Peki, golf uğruna yaklaşımımı daha az "Julian" olarak güncelledim. Daha iyi (daha az özlü) bir yaklaşım için düzeltme geçmişine bakın.

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

Bu, bir dizeyi veya 64 bit kayan nokta sayısını kabul eden ve sırasıyla 64 bit kayan nokta sayısı veya dize döndüren adsız bir işlev oluşturur. Bunu aramak için bir ad verin, örn f=x->....

Ungolfed + açıklaması:

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

Örnekler:

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 bayt

Tam C programı. Stdin ile girdi alır ve stdout ile çıktı alır.

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 ve yorum yaptı:

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 ve% f'nin çok net kullanımı
bazı kullanıcılar

D'oh! "Zeki" demek istedim.
bazı kullanıcılar

2

J, 85 bayt

Sonuçlar:

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.'

Toplam 85


Siteye Hoşgeldiniz! Kodunuzu kod olarak gösterilecek şekilde yayınınızı düzenledim. Çevrimiçi bir bağlantıya gelince, bildiğim en iyi bağlantı TIO . Sana bir bağlantı verirdim, ama J konusunda deneyimli değilim, bu yüzden onu çağırmanın doğru yolunu bilmiyorum. Ayrıca, ilk ve son satırları eklediğinizde bu 91 bayt gibi görünüyor. Bu doğru mu?
James

Yardımın için teşekkürler! Program [a = ... sona erecek.] 77'dir. Başlık 10'dur. Sonlandırıcı 1'dir, bu yüzden 88 olur. 91 yapan üç satır beslemesiyle! Üzerinde çalışacağım: o)
Richard Donovan

Şimdi 85 baytlık tek astarlı!
Richard Donovan

1

JavaScript, 194 192 190 188 bayt

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 bayt

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

Ne yazık ki, zamanla ilgili işlevlere ("Tarih" ve "toTimeString" gibi) bu sorunda izin verilmez. Aksi takdirde, bunu yapmanın çok daha kısa bir yoludur =)
Mwr247

@ Mwr247 oh görmedim, o zaman bunu düzelteceğim
düzelteceğim Downgoat

1

C, 156152 bayt

C için kolay olacağını düşündüm ama yine de oldukça büyüktü. :(

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

Test programı:

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

Çıktı:

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

1

PHP, 70 69 bayt

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

komut satırı bağımsız değişkeninden girdi alır, STDOUT'a yazdırır:

Giriş iki nokta üst üste içeriyorsa, unix saatine dönüştürün ve (gün başına saniye)
değerine bölün , aksi halde (günde saniye) ile çok sayı değerini girin ve unix saatini biçimlendirin hh:mm:ss.


1

Perl, 109 108 101 + 6 ( -plaF:Bayrak) = 107 bayt

$_=$#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

Kullanımı:

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

Ideone üzerinde deneyin.


0

Excel, 178 bayt

=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)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.