Qeng Ho đơn vị thời gian


40

Trong cuốn sách xuất sắc và hấp dẫn của Vernor Vinge, A Deepness in the Sky (nhân tiện, tôi đánh giá cao 1 ), Qeng Ho , một nền văn hóa trải dài trên nhiều hệ thống sao khác nhau, không có khái niệm về "ngày", "tháng", "" năm, "vv, và do đó có một hệ thống chấm công duy nhất đo thời gian hoàn toàn tính bằng giây. Các đơn vị được sử dụng phổ biến nhất là Ksec (kilosecond), Msec (megasecond) và Gsec (gigasecond). Đây là một biểu đồ tiện dụng từ bản sao của cuốn sách của tôi (vì tôi không thể tìm thấy nó trực tuyến):

biểu đồ tiện dụng

Bạn hiện đang bay trên Phạm Nuwen , và bạn vừa nhận được một tin nhắn từ một hành tinh lạ, chưa biết tên là " Trái đất ". 2 Họ sử dụng các đơn vị thời gian khác nhau so với bạn và máy tính của bạn không nhận ra chúng. Là nhà lập trình-khảo cổ học thường trú của con tàu, công việc của bạn là vá mã xử lý thời gian để nó nhận ra các đơn vị thời gian của Trái đất .

Đương nhiên, vì bạn chỉ bị cảm lạnh vì một vài Ksec khác, bạn muốn làm cho mã của mình càng ngắn càng tốt để có thể viết nhanh chóng. May mắn thay, như một văn hóa giao dịch giữa các vì sao, Qeng Ho có quyền truy cập vào mọi ngôn ngữ lập trình được phát minh.

Đầu vào

Đầu vào sẽ là một chuỗi chứa một hoặc nhiều thành phần được phân tách bằng dấu cách . Một thành phần được định nghĩa là một số nguyên> 0 và ≤ 255, sau đó là một không gian, và sau đó một trong những second, minute, hour, day, week, month, year, decade, hay century, có thể là số nhiều (với một bổ sung s, hoặc centuriesđối với trường hợp cuối cùng).

Dưới đây là một số ví dụ đầu vào hợp lệ:

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

Bạn có thể giả sử như sau về đầu vào:

  • Số nhiều của các đơn vị sẽ luôn luôn đồng ý với số lượng có liên quan.

  • Nếu có nhiều thành phần trong đầu vào, chúng sẽ luôn theo thứ tự chiều dài giảm dần.

Dưới đây là ý nghĩa của các đơn vị đầu vào khác nhau, cho mục đích của thách thức này:

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

Đầu ra

Dưới đây là các đơn vị Qeng Ho mà mã của bạn phải hỗ trợ:

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

Sử dụng thuật toán sau để xác định đầu ra mã của bạn:

  • Đầu tiên, cộng tổng thời gian mà đầu vào đại diện.

  • Tìm đơn vị Qeng Ho lớn nhất ngắn hơn hoặc cùng thời gian với đầu vào cơ bản, tìm đơn vị lớn nhất có ít nhất một trong số đó.

  • Chuyển đổi tổng thời gian đã cho trong đầu vào thành đơn vị này và xuất kết quả, làm tròn thành ba chữ số thập phân.

Bạn có thể lựa chọn phương pháp nào sau đây để sử dụng: làm tròn lên, làm tròn xuống, làm tròn từ số 0 hoặc làm tròn theo hướng hoặc -∞. Nếu kết quả làm tròn kết thúc 0, bạn có thể xóa các số 0 ở cuối hoặc giữ bao nhiêu tùy ý (hoặc thực hiện cả hai, tùy thuộc vào đầu vào).

Nếu kết quả được làm tròn là chính xác 1.000, bạn phải sử dụng hình thức số ít ( second, Ksec, Msec, Gsec); cách khác, sử dụng các hình thức số nhiều ( seconds, Ksecs, Msecs, Gsecs).

Trong một số trường hợp cạnh nhất định, bạn có thể đang sử dụng đơn vị của, ví dụ, Ksec, nhưng thu được kết quả làm tròn 1000.000 Ksec. Trong trường hợp này, bạn có thể chỉ cần xuất ra 1000.000 Ksecsthay vì 1 Msec.

Bạn luôn có thể cho rằng đầu vào theo thứ tự giảm dần của các đơn vị (thế kỷ, thập kỷ, năm, v.v.); hơn nữa, thành phần đi sau bất kỳ đơn vị nào sẽ luôn ngắn hơn (nghĩa là 1 decade 20 yearsđầu vào không hợp lệ).

Các trường hợp thử nghiệm

Lưu ý: kết quả được đánh dấu bằng dấu hoa thị ( *) có thể thay đổi theo số lượng không đáng kể do chênh lệch làm tròn.

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

Quy tắc

  • Đây là , vì vậy mã ngắn nhất tính bằng byte sẽ thắng.

1: chỉ khi bạn thích scifi cứng, tất nhiên. Trong trường hợp đó, tôi khuyên bạn nên đọc A Fire By the Deep trước, điều này (theo ý kiến ​​của tôi) thậm chí còn tuyệt vời hơn.

2: tốt, về mặt kỹ thuật "Trái đất cũ" được nhắc đến nhiều lần trong A Deepness in the Sky , nhưng ...


Trường hợp thử nghiệm 9 dường như không chính xác (xem câu trả lời của tôi)
edc65

1
Con tàu này không biết giờ Trái đất, nhưng có hiểu biết đầy đủ về tất cả các ngôn ngữ lập trình Trái đất. Rất logic. </ mỉa mai>
vỗ tay

2
Dang, tôi đã có một giải pháp Mathicala thực sự ngắn bằng cách sử dụng hỗ trợ đơn vị tích hợp, nhưng nó diễn giải 2 months 2 hourslà "2 tháng * 2 giờ."
2012rcampion

1
Hmm, tôi nhận thấy rằng các yếu tố này trông giống như những yếu tố trong các chức năng xử lý thời gian lỗi thời mà không ai sử dụng trong nhiều ngôn ngữ này.
Random832

Câu trả lời:


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}

Cảm ơn ngn đã cạo sạch 13 byte.

Phải có ⎕IO←0, đó là mặc định trong nhiều APL.

Hãy thử trực tuyến!


Nếu bạn gán 1E3 cho một tên (như z), trong trường hợp đầu tiên, bạn đã lãng phí hai ký tự, trong trường hợp thứ hai, bạn đã lưu một ký tự và từ phiên bản thứ ba trở đi, bạn đang lưu hai ký tự. Không bạn
lstefano

@lstefano Không, cái đầu tiên sẽ có giá 4: ⌊1E3⍟⌊(z←1E3)⍟và sau đó tiết kiệm 2 cho mỗi cái tiếp theo 1E3z.
Adám

Yup, hoàn toàn đúng. Và cho rằng chỉ có 3 trong số họ, không có lợi. Xin lỗi vì sự ồn ào.
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>


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

Bạn có thụt dòng không cần thiết trong q=eval(i,d);f={};l=1dòng, mà phá vỡ mã. Ngoài ra, bạn có thể lưu 2 byte bằng cách sử dụng 10.73.thay vì 10.073.0. Ngoài ra, không cần không gian sau print.
aland

2

SpecBAS - 476 471 byte

Bởi vì không có gì nói "thu mình trước ưu thế công nghệ của chúng tôi" tốt hơn số dòng và tuyên bố 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)

1

C # (trong LinqPad là Chức năng), 460 byte

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

vô dụng:

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

1

Toán học 296 281 byte

h: Sau khi chia chuỗi đầu vào thành một danh sách cường độ và đơn vị số lượng, CapitalizePluralizechuyển đổi các đơn vị đầu vào thành Mathicala Quantity, từ đó tổng số giây xuất phát.

dchuyển đổi giây thành các đơn vị thích hợp. Trận chung kết ssẽ bị xóa nếu thời gian tương ứng với 1 đơn vị (dưới bất kỳ hình thức nào).

Với các điều chỉnh nhỏ trong mã, phương pháp này sẽ hoạt động để chuyển đổi đầu vào ngôn ngữ tự nhiên thành bất kỳ hệ thống đo lường nào, thông thường hoặc không.

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@#&;

Đặt vào mẫu bảng:

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]

pic


0

Haskell, 567 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

Tôi chắc chắn rằng tôi đang bỏ lỡ rất nhiều cơ hội chơi gôn ở đây, Giá của việc trở thành người mới chơi golf tôi đoán.

Câu trả lời của tôi là một hàm lấy một chuỗi chứa thời gian Trái đất làm tham số đầu vào và trả về thời gian Qeng Ho.

PS: Tôi ngu ngốc quên mất độ chính xác 3 chữ số mà điều khiển số byte tăng lên.

PPS: Các biểu thức cấp cao nhất được chọn tốt hơn đã loại bỏ 10 byte byte và bây giờ nó phải chính xác để khởi động.


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

Kiểm tra:

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

Đầu ra:

ans =
6.69 Gseconds
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.