Qeng Hoの時間単位


40

Vernor Vingeの素晴らしい魅力的な本A Deepness in the Sky (ちなみに1を強くお勧めします)では、さまざまな星系にまたがる文化であるQeng Hoは、「日」、「月」、「年など」など、独自の計時システムがあり、時間を完全に秒単位で測定します。最も一般的に使用される単位は、Ksec(キロ秒)、Msec (メガ秒)、およびGsec(ギガ秒)です。これは、自分の本のコピーからの便利なチャートです(オンラインで見つけることができないため)。

便利なチャート

現在、ファムヌウェンで飛行していますが、「地球」と呼ばれる未知の未知の惑星からメッセージを受信しました。2彼らはあなたとは異なる時間単位を使用し、コンピューターはそれらを認識しません。船の常駐のプログラマー考古学者としてのあなたの仕事は、地球の時間単位を認識するように時間処理コードを修正することです。

当然のことながら、あなたはさらに数キロ秒間コールドスリープ状態になっていないので、コードをできるだけ短くして、迅速に記述できるようにする必要があります。幸いなことに、恒星間の取引文化として、Qeng Hoは発明されたすべてのプログラミング言語にアクセスできます。

入力

入力は、1つ以上のスペースで区切られたコンポーネントを含む単一の文字列になり ます成分は、 > 0の整数として定義され、≤255は、空間、及びその後の一つであるsecondminutehourdayweekmonthyeardecade、又はcenturyおそらくは複数(添加とともに、sまたは centuries最後の場合)。

有効な入力例を次に示します。

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

入力について次のことを想定できます。

  • ユニットの複数化は、常に関連する数と一致します。

  • 入力に複数のコンポーネントがある場合、それらは常に長さの降順になります。

この課題のために、さまざまな入力ユニットの意味を以下に示します。

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

出力

コードでサポートする必要があるQeng Hoユニットは次のとおりです。

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

次のアルゴリズムを使用して、コードの出力を決定します。

  • 最初に、入力が表す合計時間を合計します。

  • 入力と同じか短い時間の最大のQeng Hoユニットを見つけます。基本的に、少なくとも1つある最大のユニットを見つけます。

  • 入力で指定された合計時間をこの単位に変換し、結果を小数点以下3桁に丸めて出力します。

使用する方法は、切り上げ、切り捨て、ゼロからの切り上げ、∞または-∞への丸めのいずれかを選択できます。丸められた結果がで終わる場合、0末尾のゼロを削除するか、必要な数だけ保持する(または入力に応じて両方を行う)ことができます。

丸められた結果が正確であれば1.000、あなたは単数形を使用する必要があります(secondKsecMsecGsec); そうでなければ、複数形を使用して(secondsKsecsMsecsGsecs)。

特定のケースでは、たとえばKsecの単位を使用している場合がありますが、1000.000 Ksecの丸められた結果が得られます。この場合、の1000.000 Ksecs代わりに単純に出力できます 1 Msec

入力は、単位の降順(世紀、10年、年など)であると常に仮定できます。さらに、特定のユニットの後に来るコンポーネントは常に短くなります(つまり、1 decade 20 years無効な入力です)。

テストケース

注:アスタリスク(*)でマークされた結果は、丸めの違いにより、ごくわずかな量だけ異なる場合があります。

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

ルール

  • これはであるため、バイト単位の最短コードが優先されます。

1:もちろん、ハードフィクションが好きな場合のみ。その場合最初にA Fire Upon the Deepを読むことをお勧めします。これは(私の意見では)さらに素晴らしいものです。

2:まあ、技術的に「古い地球」は空の深さで数回言及されていますが、...


テストケース9が間違っているようです(私の回答を参照)
edc65

1
この船は地球時間を知りませんが、すべての地球プログラミング言語を完全に理解しています。非常に論理的です。</ sarcasm>
拍手

2
ダン、組み込みのユニットサポートを使用して、非常に短いMathematicaソリューションがありましたが2 months 2 hours、「2か月* 2時間」と解釈されます。
-2012rcampion

1
うーん、これらの要素は、これらの言語の多くで誰も使用していない時代遅れの時間処理関数の要素と奇妙に似ていることに気づきます。
Random832

回答:


6

APL(Dyalog APL) 157 156 154 151 154 141 142バイト

{∊(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}

13バイトを削るngnに感謝します。

が必要⎕IO←0です。これは、多くのAPLでデフォルトです。

オンラインでお試しください!


1E3を名前(zなど)に割り当てると、最初のインスタンスでは2つの文字が無駄になり、2番目のインスタンスでは既に1つを保存し、3番目のインスタンスからは2つの文字が保存されます。そうじゃない?
-lstefano

@lstefanoいいえ、最初の費用は4です。⌊1E3⍟⌊(z←1E3)⍟次の各費用で2を節約します1E3z
アダム

うん、絶対に正しい。そして、それらが3つしかないことを考えると、利益はありません。騒音でごめんなさい。
-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バイト

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

q=eval(i,d);f={};l=1行に不必要なインデントがあるため、コードが壊れます。また、10.andの73.代わりに10.0and を使用して2バイトを節約できます73.0。また、後にスペースは必要ありませんprint
オーランド

2

SpecBAS- 476 471バイト

なぜなら、行番号とGOTOステートメントよりも「技術的優位性の前にcoく」と言うものは何もないからです:-)

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#(LinqPad in Function)、460バイト

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

なし:

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

Mathematica 296 281バイト

h:量の大きさと単位のリストに、入力文字列を分割した後、Capitalize及びPluralizeMathematicaに入力された単位を変換Quantity秒数の合計が誘導されるの、。

d秒を適切な単位に変換します。s時間が1ユニット(あらゆる種類)に対応する場合、ファイナルは削除されます。

コードに若干の調整を加えると、このアプローチは、自然言語入力を従来の測定システムにかかわらず、あらゆる測定システムに変換するために機能するはずです。

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

テーブル形式に入れます:

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]

写真


0

ハスケル、 565 555バイト

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

私はここでゴルフの機会をたくさん逃していると合理的に確信しています...私は推測するゴルフ初心者の価格。

私の答えは、地球時間を含む文字列を入力パラメーターとして取得し、Qeng Ho時間を返す関数です。

PS:私は愚かにも3桁の精度を忘れていました。これはバイトカウントアップを駆動します。

PPS:最適なトップレベルの式を選択すると、10バイト削り落とされました。これで、ブートするのが正確になりました。


0

Matlab 315バイト

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

テスト:

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

出力:

ans =
6.69 Gseconds
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.