Qeng Ho unités de temps

40

Dans l'excellent et fascinant ouvrage de Vernor Vinge intitulé A Deepness in the Sky (que, d'ailleurs, je recommande vivement 1 ), le Qeng Ho , une culture qui couvre plusieurs systèmes stellaires, n'a aucune notion des "jours", des "mois", " années, "etc., et dispose donc d'un système de chronométrage unique qui mesure le temps entièrement en secondes. Les unités les plus couramment utilisées sont les unités Ksec (kiloseconde), Msec (mégaseconde) et Gsec (gigaseconde). Voici un tableau pratique tiré de ma propre copie du livre (car je ne le trouve pas en ligne):

tableau pratique

Vous volez actuellement sur le Pham Nuwen et vous venez de recevoir un message d'une planète inconnue et inconnue appelée " Terre ". 2 Ils utilisent des unités de temps différentes de celles que vous utilisez et vos ordinateurs ne les reconnaissent pas. En tant que programmeur-archéologue résident du navire, votre travail consiste à patcher le code de traitement du temps afin qu'il reconnaisse les unités de temps Terre .

Naturellement, étant donné que vous ne vous reposez plus que sur quelques Ksecs, vous voulez rendre votre code aussi court que possible pour qu'il puisse être écrit rapidement. Heureusement, en tant que culture commerciale interstellaire, le Qeng Ho a accès à tous les langages de programmation inventés.

Contribution

L'entrée sera une chaîne unique contenant un ou plusieurs composants séparés par des espaces . Un composant est défini comme étant un nombre entier> 0 et ≤ 255, puis un espace, puis l' un des second, minute, hour, day, week, month, year, decade, ou century, éventuellement pluriel (avec une ajouté s, ou centuriespour le dernier cas).

Voici quelques exemples d'entrées valides:

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

Vous pouvez supposer ce qui suit à propos de l'entrée:

  • La pluralisation des unités sera toujours en accord avec le nombre correspondant.

  • S'il y a plusieurs composants dans l'entrée, ils seront toujours dans l'ordre décroissant de longueur.

Voici ce que signifient les différentes unités d’entrée pour les besoins de ce défi:

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

Sortie

Voici les unités Qeng Ho que votre code doit prendre en charge:

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

Utilisez l'algorithme suivant pour déterminer la sortie de votre code:

  • Tout d’abord, additionnez la durée totale que représente l’entrée.

  • Recherchez l'unité Qeng Ho la plus grande qui est plus courte ou la même durée que l'entrée - en gros, recherchez l'unité la plus grande au moins une.

  • Convertissez la durée totale indiquée dans l'entrée dans cette unité et indiquez le résultat, arrondi à trois décimales.

Vous pouvez choisir l’une des méthodes suivantes: arrondir vers le haut, arrondir vers le bas, arrondir à zéro ou arrondir vers ∞ ou-. Si le résultat arrondi se termine 0, vous pouvez supprimer les zéros à la fin ou en conserver autant que vous le souhaitez (ou faire les deux, en fonction de l’entrée).

Si le résultat est arrondi exactement 1.000, vous devez utiliser le singulier ( second, Ksec, Msec, Gsec); sinon, utiliser la forme plurielle ( seconds, Ksecs, Msecs, Gsecs).

Dans certains cas extrêmes, vous pouvez utiliser l'unité de Ksec, par exemple, mais obtenir un résultat arrondi de 1000 000 Ksecs. Dans ce cas, vous pouvez simplement sortir 1000.000 Ksecsau lieu de 1 Msec.

Vous pouvez toujours supposer que l'entrée est dans l'ordre décroissant des unités (siècle, décennie, année, etc.); de plus, le composant qui vient après une unité donnée sera toujours plus court (c'est-à-dire, 1 decade 20 yearsune entrée invalide).

Cas de test

Remarque: les résultats marqués d'un astérisque ( *) peuvent varier légèrement en raison des différences d'arrondi.

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

Règles

  • C'est le , donc le code le plus court en octets gagne.

1: seulement si vous aimez la musique dure, bien sûr. Dans ce cas, je vous recommande de lire d'abord Fire On The Deep , qui est (à mon avis) encore plus fantastique.

2: eh bien, techniquement "Old Earth" est mentionné à plusieurs reprises dans A Deepness in the Sky , mais ...

Poignée de porte
la source
Le cas de test 9 semble incorrect (voir ma réponse)
edc65
1
Ce navire ne connaît pas le temps terrestre, mais a une compréhension complète de tous les langages de programmation de la Terre. Très logique </ sarcasm>
applaudir
2
Dang, j’avais une très courte solution Mathematica utilisant l’appareil intégré, mais elle s’interprète 2 months 2 hourscomme «2 mois * 2 heures».
2012rcampion
1
Hmm, je remarque que ces facteurs ressemblent étrangement à ceux des fonctions de gestion du temps obsolètes que personne n'utilise dans beaucoup de ces langues.
Random832

Réponses:

6

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

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

Merci à ngn d'avoir réduit de 13 octets.

Doit avoir ⎕IO←0, ce qui est le défaut dans beaucoup d'APL.

Essayez-le en ligne!

Adam
la source
Si vous attribuez un nom à 1E3 (comme z), vous avez perdu deux caractères dans le premier cas, vous en avez déjà enregistré un dans la deuxième et à partir du troisième exemple, vous enregistrez deux caractères. N'est-ce pas?
lstefano
@lstefano Non, le premier coûtera 4: ⌊1E3⍟⌊(z←1E3)⍟et économisera 2 sur chacun des suivants 1E3z.
Adám
Ouais, absolument raison. Et étant donné qu'il n'y a que 3 d'entre eux, aucun gain. Désolé pour le bruit.
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
la source
2

Python, 366 363 octets

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
poivré
la source
Vous avez une indentation inutile en q=eval(i,d);f={};l=1ligne, ce qui casse le code. En outre, vous pouvez économiser 2 octets en utilisant 10.et 73.au lieu de 10.0et 73.0. En outre, il n'y a pas besoin d'espace après print.
Aland
2

SpecBAS - 476 471 octets

Parce que rien ne dit mieux que nos numéros de ligne et nos déclarations GOTO: "Chaud devant notre supériorité technologique" :-)

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
la source
1

C # (dans LinqPad en tant que fonction), 460 octets

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
la source
1

Mathematica 296 281 octets

h: Après avoir décomposé la chaîne d'entrée en une liste de grandeurs et d'unités de quantité Capitalizeet Pluralizeconverti les unités d'entrée en unités Mathematica Quantity, à partir desquelles le nombre total de secondes est dérivé.

dconvertit les secondes en unités appropriées. La finale sest supprimée si le temps correspond à 1 unité (de tout type).

Avec des ajustements mineurs dans le code, cette approche devrait fonctionner pour la conversion de l'entrée en langage naturel dans n'importe quel système de mesure, qu'il soit conventionnel ou non.

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

Mettre sous forme de tableau:

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

DavidC
la source
0

Haskell, 565 555 octets

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

Je suis assez sûr que je manque de nombreuses occasions de jouer au golf ici… Le prix d'être un débutant au golf, je suppose.

Ma réponse est une fonction prenant une chaîne de caractères contenant l'heure de la Terre comme paramètre d'entrée et renvoyant l'heure de Qeng Ho.

PS: J'ai bêtement oublié la précision à 3 chiffres… qui accélère le décompte d'octets.

PPS: Des expressions de premier niveau mieux choisies ont été supprimées de 10 octets… et le démarrage devrait maintenant être précis.

Arjanen
la source
0

Matlab 315 octets

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

Tester:

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

Sortie:

ans =
6.69 Gseconds
Brainkz
la source