Qeng Ho satuan waktu

40

Dalam buku Vernor Vinge yang sangat bagus dan mempesona A Deepness in the Sky (yang, omong-omong, saya sangat merekomendasikan 1 ), Qeng Ho , budaya yang mencakup berbagai sistem bintang, tidak memiliki gagasan tentang "hari," "bulan," " tahun, "dll., dan karenanya memiliki sistem ketepatan waktu yang unik yang mengukur waktu sepenuhnya dalam hitungan detik. Unit yang paling umum digunakan adalah Ksec (kilosecond), Msec (megasecond), dan Gsec (gigasecond). Berikut adalah bagan berguna dari salinan buku saya sendiri (karena saya tidak dapat menemukannya online):

grafik berguna

Anda saat ini terbang di Pham Nuwen , dan Anda baru saja menerima pesan dari planet aneh dan tidak dikenal yang disebut " Bumi ." 2 Mereka menggunakan unit waktu yang berbeda dari yang Anda lakukan, dan komputer Anda tidak mengenali mereka. Sebagai Programmer-Archaeologist dari kapal, tugas Anda adalah menambal kode penanganan waktu sehingga ia mengenali satuan waktu Bumi .

Tentu saja, karena Anda hanya kekurangan tidur selama beberapa Ksec, Anda ingin membuat kode sesingkat mungkin sehingga dapat ditulis dengan cepat. Untungnya, sebagai budaya perdagangan antarbintang, Qeng Ho memiliki akses ke setiap bahasa pemrograman yang diciptakan.

Memasukkan

Input akan berupa string tunggal yang mengandung satu atau lebih komponen yang dipisahkan ruang . Sebuah komponen didefinisikan sebagai angka integer> 0 dan ≤ 255, lalu spasi, dan kemudian salah satu dari second, minute, hour, day, week, month, year, decade, atau century, mungkin jamak (dengan menambahkan s, atau centuriesuntuk kasus terakhir).

Berikut adalah beberapa contoh input yang valid:

10 days 12 hours
1 year
184 centuries 1 second
9 weeks 6 days 2 hours 1 minute 20 seconds

Anda dapat mengasumsikan berikut tentang input:

  • Pluralisasi unit akan selalu setuju dengan nomor yang relevan.

  • Jika ada beberapa komponen dalam input, mereka akan selalu dalam urutan panjang.

Berikut adalah arti berbagai unit input, untuk keperluan tantangan ini:

unit     relative    absolute
---------------------------------------
second   1 second    1 second
minute   60 seconds  60 seconds
hour     60 minutes  3600 seconds
day      24 hours    86400 seconds
week     7 days      604800 seconds
month    30 days     2592000 seconds
year     365 days    31536000 seconds
decade   10 years    315360000 seconds
century  10 decades  3153600000 seconds

Keluaran

Berikut adalah unit Qeng Ho yang harus didukung kode Anda:

unit    relative      absolute
----------------------------------------
second  1 second      1 second
Ksec    1000 seconds  1000 seconds
Msec    1000 Ksecs    1000000 seconds
Gsec    1000 Msecs    1000000000 seconds

Gunakan algoritma berikut untuk menentukan output kode Anda:

  • Pertama, tambahkan jumlah total waktu yang diwakili oleh input.

  • Temukan unit Qeng Ho terbesar yang lebih pendek atau jumlah waktu yang sama dengan input — intinya, temukan unit terbesar yang setidaknya ada satu.

  • Konversi jumlah total waktu yang diberikan dalam input ke dalam unit ini, dan hasilkan hasilnya, dibulatkan menjadi tiga tempat desimal.

Anda dapat memilih metode mana yang akan digunakan: pembulatan ke atas, pembulatan ke bawah, pembulatan dari nol, atau pembulatan ke arah ∞ atau -∞. Jika hasil bulat berakhir 0, Anda bisa menghapus trailing nol atau menyimpan sebanyak yang Anda inginkan (atau melakukan keduanya, tergantung pada input).

Jika hasil bulat adalah persis 1.000, Anda harus menggunakan bentuk tunggal ( second, Ksec, Msec, Gsec); jika tidak, menggunakan bentuk jamak ( seconds, Ksecs, Msecs, Gsecs).

Dalam kasus tepi tertentu, Anda mungkin menggunakan unit, misalnya, Ksec, tetapi dapatkan hasil bulat 1000.000 Ksec. Dalam hal ini, Anda mungkin hanya keluaran 1000.000 Ksecsbukan 1 Msec.

Anda mungkin selalu menganggap bahwa input dalam urutan unit (abad, dekade, tahun, dll); lebih jauh lagi, komponen yang datang setelah unit tertentu akan selalu lebih pendek (yaitu, 1 decade 20 yearsinput tidak valid).

Uji kasus

Catatan: hasil yang ditandai dengan tanda bintang ( *) dapat bervariasi dengan jumlah yang dapat diabaikan karena perbedaan pembulatan.

input                                         output
-------------------------------------------------------------
1 hour                                        3.600 Ksecs
1 day                                         86.400 Ksecs
2 weeks                                       1.210 Msecs
1 year                                        31.536 Msecs
32 years                                      1.009 Gsecs   *
1 second                                      1.000 second
1 century 6 decades                           5.046 Gsecs   *
255 centuries                                 804.168 Gsecs
2 weeks 6 days 1 hour 19 minutes 4 seconds    1.733 Msecs
1 week 3 days 3 hours 7 minutes               875.220 Ksecs
1 week 4 days 13 hours 46 minutes 40 seconds  1.000 Msec
2 months 2 hours                              5.191 Msecs   *
16 minutes 39 seconds                         999.000 seconds

Aturan

  • Ini adalah , jadi kode terpendek dalam byte menang.

1: hanya jika Anda suka hard scifi, tentu saja. Dalam hal ini saya sarankan membaca A Fire Upon the Deep pertama, yang (menurut saya) bahkan lebih fantastis.

2: yah, secara teknis "Bumi Tua" disebutkan beberapa kali dalam A Deepness in the Sky , tapi ...

Gagang pintu
sumber
Test case 9 sepertinya salah (lihat jawaban saya)
edc65
1
Kapal ini tidak tahu waktu Bumi, tetapi memiliki pemahaman penuh tentang semua bahasa pemrograman Bumi. Sangat logis. </sarcasm>
bertepuk tangan
2
Dang, saya punya solusi Mathematica yang sangat singkat menggunakan dukungan unit built-in, tetapi ini diartikan 2 months 2 hourssebagai "2 bulan * 2 jam."
2012rcampion
1
Hmm, saya perhatikan bahwa faktor-faktor ini terlihat aneh seperti yang ada dalam fungsi penanganan waktu yang usang yang tidak digunakan siapa pun dalam banyak bahasa ini.
Random832

Jawaban:

6

APL (Dyalog APL) , 157 156 154 151 154 141 142 byte

{∊(3⍕N)' '((B/S⊃' KMG')'sec','ond'/⍨~B←T≥1E3),'s'/⍨1≠N←T÷1E3*S←⌊1E3⍟T←+/×/↑⍎¨'\d+ .a?i?'⎕S'&'⊢⍵⊣c←10×d←10×⊃y m w←365 30 7×da←24×h←×⍨mi←60×s←1}

Terima kasih kepada ngn untuk mencukur 13 byte.

Harus ada ⎕IO←0, yang merupakan standar di banyak APL.

Cobalah online!

Adm
sumber
Jika Anda menetapkan 1E3 ke sebuah nama (seperti z), pada instance pertama Anda telah menyia-nyiakan dua karakter, pada instance kedua Anda telah menyimpan satu, dan dari instance ketiga dan seterusnya Anda menyimpan dua karakter. Bukan?
lstefano
@ lstefano Tidak, yang pertama biayanya 4: ⌊1E3⍟⌊(z←1E3)⍟dan kemudian simpan 2 untuk masing-masing 1E3→ berikutnya z.
Adám
Yup, benar sekali. Dan mengingat bahwa hanya ada 3 dari mereka, tidak ada untungnya. Maaf atas kebisingannya.
lstefano
6

JavaScript (ES6) 255

f=s=>(s=s.replace(/(\d+) (..)/g,(_,n,u)=>t+={se:1,mi:60,ho:3600,da:86400,we:604800,mo:2592e3,ye:31536e3,de:31536e4,ce:31536e5}[u]*n,t=0),[a,b]=t>=1e9?[t/1e9,' Gsec']:t>=1e6?[t/1e6,' Msec']:t>999?[t/1e3,' Ksec']:[t,' second'],a.toFixed(3)+b+(a-1?'s':''))  

// test

console.log=x=>O.innerHTML+=x+'\n'

;[
 ['1 hour','3.600 Ksecs']
,['1 day','86.400 Ksecs']
,['2 weeks','1.210 Msecs']
,['1 year','31.536 Msecs']
,['32 years','1.009 Gsecs'] 
,['1 second','1.000 second']
,['1 century 6 decades','5.046 Gsecs']
,['255 centuries','804.168 Gsecs']
,['2 weeks 6 days 1 hour 19 minutes 4 seconds','1.733 Msecs']
,['1 week 3 days 3 hours 7 minutes','875.220 Ksecs']
,['1 week 4 days 13 hours 46 minutes 40 seconds', '1.000 Msec']
,['2 months 2 hours', '5.191 Msecs']
,['16 minutes 39 seconds', '999 seconds']
].forEach(t=>console.log(t[0]+' '+f(t[0])+' (Check:'+t[1]+')'))
<pre id=O></pre>

edc65
sumber
2

Python, 366 363 byte

d={};l=1;q=str.replace;i=q(raw_input(),"ie","y")
for u,t in zip('second minute hour day week month year decade century'.split(),(1,60,60,24,7,30./7,73./6,10,10)):l=t*l;d[u]=d[u+"s"]=l
while" "in i:
 i=q(q(i," ","*",1)," ","+",1)
q=eval(i,d);f={};l=1
for u in('second','Ksec','Msec','Gsec'):
 l*=1e3
 if q<l:q=q*1e3/l;print"%.3f %s%s"%(q,u,("s","")[q<1.001]);break
pppery
sumber
Anda memiliki lekukan yang tidak perlu pada q=eval(i,d);f={};l=1baris, yang memecah kode. Selain itu, Anda dapat menyimpan 2 byte dengan menggunakan 10.dan 73.bukannya 10.0dan 73.0. Juga, tidak perlu ruang setelah print.
aland
2

SpecBAS - 476 471 byte

Karena tidak ada yang mengatakan "meringkuk di depan keunggulan teknologi kami" lebih baik dari nomor baris dan pernyataan GOTO :-)

1 INPUT e$: DIM t$(SPLIT e$,NOT " "): DIM m=31536e5,31536e4,31536e3,2592e3,604800,86400,3600,60,1
2 LET q=0,n$=" cedeyemowedahomise"
3 FOR i=1 TO ARSIZE t$() STEP 2: LET t=VAL t$(i),u$=t$(i+1)( TO 2),p=POS(u$,n$)/2: INC q,t*m(p): NEXT i
4 IF q>=1e9 THEN LET r=q/1e9,r$=" G": GO TO 8
5 IF q>=1e6 THEN LET r=q/1e6,r$=" M": GO TO 8
6 IF q>999 THEN LET r=q/1e3,r$=" K": GO TO 8
7 IF q<1e3 THEN LET r=q,r$=" "
8 PRINT USING$("&.*0###",r);r$;"sec"+("ond" AND q<1e3)+("s" AND r>1)
Brian
sumber
1

C # (dalam LinqPad sebagai Fungsi), 460 Bytes

void Main(){var x=Console.ReadLine().Split(' ');long s=0,v,i=0;for(;i<x.Length;){v=long.Parse(x[i++]);var w=x[i++].Substring(0,2);s+=w=="ce"?v*3153600000:w=="de"?v*315360000:w=="ye"?v*31536000:w=="mo"?v*2592000:w=="we"?v*604800:w=="da"?v*86400:w=="ho"?v*3600:w=="mi"?v*60:v;}decimal k=1000,m=k*k,g=m*k,r=0;var o="sec";r=s/g>=1?s/g:s/m>=1?s/m:s/k>=1?s/k:s;o=s/g>=1?"G"+o:s/m>=1?"M"+o:s/k>=1?"K"+o:o+"ond";Console.WriteLine(Math.Round(r,3)+" "+o+(r==1?"":"s"));}

ungolfed:

void Main()
{
    var x=Console.ReadLine().Split(' ');
    long s=0,v,i=0;
    for(;i<x.Length;)
    {
        v=long.Parse(x[i++]);
        var w=x[i++].Substring(0,2);
        s+=w=="ce"?v*3153600000:w=="de"?v*315360000:w=="ye"?v*31536000:w=="mo"?v*2592000:w=="we"?v*604800:w=="da"?v*86400:w=="ho"?v*3600:w=="mi"?v*60:v;
    }
    decimal k=1000,m=k*k,g=m*k,r=0;
    var o="sec";
    r=s/g>=1?s/g:s/m>=1?s/m:s/k>=1?s/k:s;
    o=s/g>=1?"G"+o:s/m>=1?"M"+o:s/k>=1?"K"+o:o+"ond";
    Console.WriteLine(Math.Round(r,3)+" "+o+(r==1?"":"s"));
}
Stephan Schinkel
sumber
1

Mathematica 296 281 byte

h: Setelah memecah string input menjadi daftar besaran dan unit kuantitas, Capitalizedan Pluralizemengonversi unit input ke dalam Mathematica Quantity, dari mana total jumlah detik diturunkan.

dmengkonversi detik ke unit yang sesuai. Final sdihapus jika waktunya sesuai dengan 1 unit (dalam bentuk apa pun).

Dengan sedikit penyesuaian dalam kode, pendekatan ini harus bekerja untuk konversi input bahasa alami ke sistem pengukuran apa pun, konvensional atau tidak.

h=Tr[UnitConvert[Quantity@@{ToExpression@#,Capitalize@Pluralize@#2},"Seconds"]&@@@Partition[StringSplit@#,2]][[1]]&;
d=ToString[N@#/(c=10^{9,6,3,0})[[p=Position[l=NumberDecompose[#,c],x_/;x>0][[1,1]]]]]<>StringDrop[{" Gsecs"," Msecs"," Ksecs"," seconds"}[[p]],-Boole[Tr[l]==1]]&
z=d@h@#&;

Dimasukkan ke dalam bentuk tabel:

z1[n_]:={n,z@n}

Grid[z1 /@ {"1 hour", "2 day", "2 weeks", "1 year", "32 years", 
   "1 second", "1 century 6 decades", "255 centuries", 
   "2 weeks 6 days 1 hour 7 minutes", 
   "1 week 3 days 3 hours 46 minutes 40 seconds", 
   "1 week 4 days 13 hours 46 minutes 40 seconds", "2 months 2 hours",
    "16 minutes 39 seconds"}, Alignment -> Right]

foto

DavidC
sumber
0

Haskell, 565 555 byte

import Data.List
import Numeric
import Data.Bool
i=isPrefixOf
s x=showFFloat(Just 3)x""
r=read
f=fromIntegral
b=bool"s"""
c=b.(=="1.000")
h(c:u:l)
 |i"s"u=(r c)+h l
 |i"mi"u=(r c*60)+h l
 |i"h"u=(r c*3600)+h l
 |i"da"u=(r c*86400)+h l
 |i"w"u=(r c*604800)+h l
 |i"mo"u=(r c*2592000)+h l
 |i"y"u=(r c*31536000)+h l
 |i"de"u=(r c*315360000)+h l
 |True=(r c*3153600000)+h l
h _=0
q i
 |v<-s((f i)/10^9),i>=10^9=v++" Gsec"++c v
 |v<-s((f i)/10^6),i>=10^6=v++" Msec"++c v
 |v<-s((f i)/1000),i>=1000=v++" ksec"++c v
 |True=show i++" second"++b(i==1)
t=q.h.words

Saya cukup yakin saya kehilangan begitu banyak peluang golf di sini ... Harga menjadi pemula golf kurasa.

Jawaban saya adalah fungsi mengambil string yang berisi waktu Bumi sebagai parameter input dan mengembalikan waktu Qeng Ho.

PS: Saya dengan bodohnya lupa tentang ketepatan 3 digit ... yang membuat jumlah byte bertambah.

PPS: Ekspresi tingkat atas yang dipilih lebih baik mencukur 10 byte ... dan sekarang harus akurat untuk boot.

arjanen
sumber
0

Matlab 315 byte

K='cedeyemowedahomiseconds';Q=' KMGT';for j=1:9;y(j)=double(~isempty(strfind(S,K(2*j-1:2*j))));end
y(y==1)=sscanf(S,repmat('%d %*s ',1,9));y=86400*sum(datenum([sum(y(1:3)*10.^[2;1;0]),y(4),y(5:6)*[7;1],y(7:9)]));z=floor(log10(y)/3);y=num2str(y/10^(3*z)+1e-4);[y(1:4),' ',Q(z+1),K(17:23-(y(1:4)=='1.00'))]

Uji:

S = '2 centuries 1 decade 2 years 3 months 3 weeks 4 days 1 hour 44 minutes 58 seconds';

Keluaran:

ans =
6.69 Gseconds
brainkz
sumber