Qeng Ho Zeiteinheiten

40

In Vernor Vinges exzellentem und faszinierendem Buch A Deepness in the Sky (das ich übrigens wärmstens empfehlen kann 1 ) kennt das Qeng Ho , eine Kultur, die verschiedene Sternensysteme umspannt, keine "Tage", "Monate". Jahre usw. und verfügt daher über ein einzigartiges Zeitnehmungssystem, das die Zeit vollständig in Sekunden misst. Die am häufigsten verwendeten Einheiten sind Ksec (Kilosekunde), Msec (Megasekunde) und Gsec (Gigasekunde). Hier ist eine handliche Tabelle aus meinem eigenen Exemplar des Buches (da ich es online nicht finden kann):

handliches Diagramm

Sie fliegen gerade mit der Pham Nuwen und haben gerade eine Nachricht von einem fremden, unbekannten Planeten namens " Erde " erhalten. 2 Sie verwenden andere Zeiteinheiten als Sie und Ihre Computer erkennen ihre nicht. Als Programmierer-Archäologe des Schiffes müssen Sie den Code für die Zeitverarbeitung so ändern, dass er die Zeiteinheiten der Erde erkennt .

Natürlich möchten Sie Ihren Code so kurz wie möglich halten, damit er schnell geschrieben werden kann, da Sie nur für ein paar weitere Ksecs außer Schlaf sind. Glücklicherweise hat der Qeng Ho als interstellare Handelskultur Zugang zu jeder erfundenen Programmiersprache.

Eingang

Die Eingabe ist eine einzelne Zeichenfolge, die eine oder mehrere durch Leerzeichen getrennte Komponenten enthält . Eine Komponente wird als ganze Zahl definiert> 0 und ≤ 255 ist , dann ein Raum, und dann einem von second, minute, hour, day, week, month, year, decade, oder century, möglicherweise mehr (mit einer zusätzlichen s, oder centuriesfür den letzten Fall ist ).

Hier sind einige gültige Beispieleingaben:

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

In Bezug auf die Eingabe können Sie Folgendes annehmen:

  • Die Pluralisierung von Einheiten wird immer mit der entsprechenden Anzahl übereinstimmen.

  • Wenn die Eingabe mehrere Komponenten enthält , werden diese immer in absteigender Reihenfolge der Länge angezeigt.

Im Folgenden finden Sie die Bedeutung der verschiedenen Eingabeeinheiten für diese Herausforderung:

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

Ausgabe

Hier sind die Qeng Ho-Einheiten, die Ihr Code unterstützen muss:

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

Verwenden Sie den folgenden Algorithmus, um die Ausgabe Ihres Codes zu bestimmen:

  • Addieren Sie zunächst die Gesamtzeit, die die Eingabe darstellt.

  • Ermitteln Sie die größte Qeng Ho-Einheit, die kürzer oder genauso lang wie die Eingabe ist. Ermitteln Sie im Wesentlichen die größte Einheit, von der es mindestens eine gibt.

  • Wandeln Sie die in der Eingabe angegebene Gesamtzeit in diese Einheit um und geben Sie das Ergebnis auf drei Dezimalstellen gerundet aus.

Sie haben möglicherweise die Wahl, welche der folgenden Methoden Sie verwenden möchten: Aufrunden, Abrunden, Abrunden von Null oder Runden in Richtung ∞ oder -∞. Wenn das gerundete Ergebnis endet 0, können Sie entweder nachfolgende Nullen entfernen oder so viele beibehalten, wie Sie möchten (oder je nach Eingabe beides).

Wenn das gerundete Ergebnis genau ist 1.000, müssen Sie die Singularform verwenden ( second, Ksec, Msec, Gsec); Andernfalls verwenden , um die Pluralform ( seconds, Ksecs, Msecs, Gsecs).

In bestimmten Randfällen verwenden Sie möglicherweise die Einheit Ksec, erhalten jedoch ein gerundetes Ergebnis von 1000.000 Ksecs. In diesem Fall können Sie einfach Ausgabe 1000.000 Ksecsstatt 1 Msec.

Sie können immer davon ausgehen, dass die Eingabe in absteigender Reihenfolge der Einheiten erfolgt (Jahrhundert, Jahrzehnt, Jahr usw.). Darüber hinaus ist die Komponente, die hinter einer bestimmten Einheit steht, immer kürzer (dh es 1 decade 20 yearshandelt sich um eine ungültige Eingabe).

Testfälle

Hinweis: Mit einem Stern ( *) gekennzeichnete Ergebnisse können aufgrund von Rundungsdifferenzen geringfügig abweichen.

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

Regeln

  • Das ist , also gewinnt der kürzeste Code in Bytes.

1: natürlich nur, wenn du hard scifi magst. In diesem Fall empfehle ich, zuerst A Fire Upon the Deep zu lesen , was meiner Meinung nach sogar noch fantastischer ist.

2: Nun, technisch gesehen wird "Alte Erde" in A Deepness in the Sky mehrmals erwähnt , aber ...

Türknauf
quelle
Testfall 9 scheint falsch (siehe meine Antwort)
edc65
1
Dieses Schiff kennt die Zeit der Erde nicht, hat jedoch ein umfassendes Verständnis für alle Programmiersprachen der Erde. Sehr logisch. </ sarcasm>
Uhr klatschen
2
Verdammt, ich hatte eine sehr kurze Mathematica-Lösung mit der integrierten Einheitenunterstützung, die jedoch 2 months 2 hoursals "2 Monate * 2 Stunden" interpretiert wird .
2012rcampion
1
Hmm, ich stelle fest, dass diese Faktoren seltsamerweise denen in den veralteten Funktionen für die Zeitsteuerung ähneln, die in vielen dieser Sprachen niemand verwendet.
Random832

Antworten:

6

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

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

Danke an ngn für die 13 Bytes.

Muss haben ⎕IO←0, was in vielen APLs Standard ist.

Probieren Sie es online!

Adam
quelle
Wenn Sie einem Namen 1E3 zuweisen (wie z), haben Sie in der ersten Instanz zwei Zeichen verschwendet, in der zweiten Instanz haben Sie bereits ein Zeichen gespeichert, und ab der dritten Instanz speichern Sie zwei Zeichen. Nicht wahr
Lstefano
@lstefano Nein, die erste kostet 4: ⌊1E3⍟⌊(z←1E3)⍟und spart dann 2 für jede der nächsten 1E3z.
Adám
Ja, absolut richtig. Und da es nur drei davon gibt, gibt es keinen Gewinn. Entschuldigung für den Lärm.
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
quelle
2

Python, 366 363 Bytes

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
Pfeffer
quelle
Sie haben unnötige Einrückungen in der q=eval(i,d);f={};l=1Zeile, die den Code beschädigen. Außerdem können Sie 2 Bytes sparen, indem Sie 10.und 73.anstelle von 10.0und verwenden 73.0. Außerdem wird nachher kein Platz mehr benötigt print.
Aland
2

SpecBAS - 476 471 Bytes

Denn nichts sagt besser als Zeilennummern und GOTO-Aussagen :-)

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
quelle
1

C # (in LinqPad als Funktion), 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
quelle
1

Mathematica 296 281 Bytes

h: Die Eingabezeichenfolge in eine Liste von Mengengrößen und Einheiten nach Aufbrechen Capitalizeund Pluralizewandeln die Eingabeeinheiten in Mathematica Quantitydie Gesamtzahl von Sekunden ist, von dem abgeleitet wird .

dkonvertiert Sekunden in die entsprechenden Einheiten. Das Finale swird entfernt, wenn die Zeit 1 Einheit (jeglicher Art) entspricht.

Mit geringfügigen Anpassungen im Code sollte dieser Ansatz für die Konvertierung von Eingaben in natürlicher Sprache in jedes konventionelle oder nicht konventionelle Messsystem funktionieren.

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

In Tabellenform bringen:

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]

Bild

DavidC
quelle
0

Haskell, 565 555 Bytes

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

Ich bin mir ziemlich sicher, dass ich hier so viele Möglichkeiten zum Golfen verpasse ... Der Preis, ein Golfanfänger zu sein, schätze ich.

Meine Antwort ist eine Funktion, die einen String mit der Erdzeit als Eingabeparameter verwendet und die Qeng Ho-Zeit zurückgibt.

PS: Ich habe dummerweise die 3-stellige Genauigkeit vergessen ... die die Byte-Zählung in die Höhe treibt.

PPS: Besser gewählte Ausdrücke der obersten Ebene, die um 10 Byte reduziert wurden ... und jetzt sollten sie beim Booten korrekt sein.

arjanen
quelle
0

Matlab 315 Bytes

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

Prüfung:

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

Ausgabe:

ans =
6.69 Gseconds
brainkz
quelle