Qeng Ho unidades de tiempo

40

En el excelente y fascinante libro de Vernor Vinge A Deepness in the Sky (que, por cierto, recomiendo encarecidamente 1 ), el Qeng Ho , una cultura que abarca varios sistemas estelares, no tiene noción de "días", "meses" " años ", etc., y por lo tanto tiene un sistema de cronometraje único que mide el tiempo completamente en segundos. Las unidades más utilizadas son Ksec (kilosegundo), Msec ( megasecond ) y Gsec (gigasecond). Aquí hay un gráfico útil de mi propia copia del libro (ya que no puedo encontrarlo en línea):

tabla práctica

Actualmente estás volando en el Pham Nuwen , y acabas de recibir un mensaje de un planeta extraño y desconocido llamado " Tierra ". 2 Usan unidades de tiempo diferentes a las suyas, y sus computadoras no reconocen las suyas. Como programador residente-arqueólogo de la nave, su trabajo consiste en parchear el código de manejo del tiempo para que reconozca las unidades de tiempo de la Tierra .

Naturalmente, dado que solo se queda sin resfriado durante unos pocos Ksecs, desea que su código sea lo más breve posible para que pueda escribirse rápidamente. Afortunadamente, como cultura comercial interestelar, el Qeng Ho tiene acceso a todos los lenguajes de programación inventados.

Entrada

La entrada será una sola cadena que contiene uno o más componentes separados por espacios . Un componente se define como un número entero> 0 y ≤ 255, a continuación, un espacio, y luego uno de second, minute, hour, day, week, month, year, decade, o century, posiblemente plural (con un añadido s, o centuriespara el último caso).

Aquí hay algunas entradas de ejemplo válidas:

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

Puede suponer lo siguiente acerca de la entrada:

  • La pluralización de unidades siempre estará de acuerdo con el número relevante.

  • Si hay múltiples componentes en la entrada, siempre estarán en orden descendente de longitud.

Esto es lo que significan las distintas unidades de entrada, a los efectos de este desafío:

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

Salida

Estas son las unidades Qeng Ho que su código debe admitir:

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

Use el siguiente algoritmo para determinar la salida de su código:

  • Primero, sume la cantidad total de tiempo que representa la entrada.

  • Encuentre la unidad Qeng Ho más grande que sea más corta o la misma cantidad de tiempo que la entrada; esencialmente, encuentre la unidad más grande de la que haya al menos una.

  • Convierta la cantidad total de tiempo dada en la entrada en esta unidad y envíe el resultado, redondeado a tres decimales.

Puede elegir cuál de los siguientes métodos usar: redondear hacia arriba, redondear hacia abajo, redondear desde cero o redondear hacia ∞ o -∞. Si el resultado redondeado termina 0, puede eliminar los ceros finales o conservar tantos como desee (o hacer ambos, dependiendo de la entrada).

Si el resultado redondeado es exactamente 1.000, debe usar la forma singular (second , Ksec, Msec, Gsec); de lo contrario, utiliza el plural ( seconds, Ksecs, Msecs, Gsecs).

En ciertos casos extremos, puede estar utilizando la unidad de, por ejemplo, Ksec, pero obtener un resultado redondeado de 1000,000 Ksecs. En este caso, simplemente puede generar en 1000.000 Ksecslugar de 1 Msec.

Siempre puede suponer que la entrada está en orden descendente de unidades (siglo, década, año, etc.); Además, el componente que viene después de cualquier unidad dada siempre será más corto (es decir, 1 decade 20 yearses una entrada no válida).

Casos de prueba

Nota: resultados marcados con un asterisco (* ) pueden variar en una cantidad insignificante debido a las diferencias de redondeo.

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

Reglas

  • Este es el , por lo que gana el código más corto en bytes.

1: solo si te gusta la ciencia ficción, por supuesto. En cuyo caso recomiendo leer A Fire Upon the Deep primero, que es (en mi opinión) aún más fantástico.

2: bueno, técnicamente "Old Earth" se menciona varias veces en A Deepness in the Sky , pero ...

Pomo de la puerta
fuente
El caso de prueba 9 parece incorrecto (vea mi respuesta)
edc65
1
Esta nave no conoce el tiempo de la Tierra, pero tiene una comprensión completa de todos los lenguajes de programación de la Tierra. Muy lógico. </sarcasm>
aplaude el
2
Dang, tenía una solución de Mathematica realmente corta usando el soporte de unidad incorporado, pero se interpreta 2 months 2 hourscomo "2 meses * 2 horas".
Campamento 2012
1
Hmm, noto que estos factores se parecen extrañamente a los de las funciones obsoletas de manejo del tiempo que nadie usa en muchos de estos lenguajes.
Random832

Respuestas:

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}

Gracias a ngn por recortar 13 bytes.

Debe tener ⎕IO←0 , que es el valor predeterminado en muchas APL.

Pruébalo en línea!

Adán
fuente
Si asigna 1E3 a un nombre (como z), en la primera instancia ha desperdiciado dos caracteres, en la segunda instancia ya ha guardado uno, y desde la tercera instancia en adelante está guardando dos caracteres. Tu no?
lstefano
@lstefano No, el primero costará 4: ⌊1E3⍟⌊(z←1E3)⍟y luego ahorrará 2 en cada uno de los siguientes 1E3z.
Adám
Sí, absolutamente correcto. Y dado que solo hay 3 de ellos, no hay ganancia. Perdón por el ruido.
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
fuente
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
pppery
fuente
Tiene sangría innecesaria en q=eval(i,d);f={};l=1línea, que rompe el código. Además, puede guardar 2 bytes usando 10.y en 73.lugar de 10.0y 73.0. Además, no hay necesidad de espacio después print.
aland
2

SpecBAS - 476 471 bytes

Porque nada dice "acobardarse ante nuestra superioridad tecnológica" mejor que los números de línea y las declaraciones 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
fuente
1

C # (en LinqPad como función), 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"));}

sin golf:

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

Mathematica 296 281 bytes

h: Después de dividir la cadena de entrada en una lista de magnitudes y unidades de cantidad, Capitalizey Pluralizeconvertir las unidades de entrada en las de Mathematica Quantity, de las cuales se deriva el número total de segundos.

dconvierte segundos a las unidades apropiadas. El finals se elimina si el tiempo corresponde a 1 unidad (de cualquier tipo).

Con pequeños ajustes en el código, este enfoque debería funcionar para la conversión de la entrada del lenguaje natural en cualquier sistema de medición, convencional o no.

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

Poner en forma de tabla:

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
fuente
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

Estoy razonablemente seguro de que me estoy perdiendo tantas oportunidades de golf aquí ... El precio de ser un principiante de golf, supongo.

Mi respuesta es una función que toma una cadena que contiene el tiempo de la Tierra como parámetro de entrada y devuelve el tiempo Qeng Ho.

PD: Olvidé estúpidamente la precisión de 3 dígitos ... lo que hace que el byte cuente.

PPS: las expresiones de nivel superior mejor elegidas redujeron 10 bytes ... y ahora debería ser preciso arrancar.

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

Prueba:

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

Salida:

ans =
6.69 Gseconds
brainkz
fuente