Convertir el tiempo en una cadena

17

Problema

Un día, tu jefe se te acerca y te dice que necesita saber la hora. Todavía insiste después de que usted señala el reloj directamente sobre su cabeza, y confiesa que tiene un caso grave de discalculia , lo que hace que ni siquiera pueda ver los números en un reloj. Si bien todavía te preguntas cómo alguien que no puede ver los números puede administrar una empresa, te dice que "hagas algo al respecto", sea lo que sea.

Su tarea ahora es crear un programa o función que, dado un tiempo de entrada con horas y minutos (los segundos son opcionales) (las horas están basadas en 24), genera una oración legible en inglés que no contiene números.

No es necesario superar los segundos.

Por ejemplo, 08:45:15debería dar salidaquarter to nine o'clock AM

Casos de prueba

00:00:00 > twelve night
12:00:00 > twelve noon
06:00:00 > six o'clock AM
18:00:00 > six o'clock PM
06:15:00 > quarter past six o'clock AM
18:45:00 > quarter to seven o'clock PM
11:30:00 > half past eleven o'clock AM
13:22:00 > twentytwo minutes past one o'clock PM
17:43:00 > seventeen minutes to six o'clock PM
00:09:00 > nine minutes past twelve o'clock AM

Reglas

Los números de salida pueden tener la forma de cuarenta y dos o cuarenta y dos, lo que más le guste. Las lagunas estándar no están permitidas. Se permiten nuevas líneas al final, pero la oración debe estar en 1 línea.

La entrada puede estar en cualquier formato que desee, por ejemplo HH:MM:SS, HH,MM,SS, HHMMSS, HH/MM/SS, o cualquier variante sin segundos, pero se debe hacer el formato de entrada claro en su respuesta. No es necesario dar salida en one minutelugar deone minutes

para los minutos que van del 0 al 30 (0 y 30 incluidos) debe usar past, y para los demás debe usarto

Como el tiempo es relativo, gana el código más corto en bytes.

Dennis van Gils
fuente
1
Esto parece un buen desafío, pero sugiero eliminar los bonos. A menos que sepa exactamente lo que está haciendo, eso es algo que debe evitar al escribir desafíos.
Denker
1
Dos puntos más (menores): ¿por qué importa cómo se escribe forty-fivecuando los casos de prueba indican claramente quarter toel formato de entrada apropiado? (simplemente cámbielo a cuarenta y dos;)) Además, la complejidad de kolmogorov no es una etiqueta apropiada.
Sanchises
@sanchises editados. No entendí bien la etiqueta kolmogorov, y pensé que tenía que ver con problemas en la salida de cualquier cadena, en lugar de solo una cadena dada.
Dennis van Gils
1
@TimmyD El -70% era una broma, no imaginé que alguien trataría de traducir francés en code-golf. Sin embargo, creo que tener un tamaño negativo es una recompensa decente para un traductor francés-inglés perfecto
Dennis van Gils
Eso se ve mucho mejor, pero se necesitan algunas aclaraciones de formato más. Específicamente en relación con la elección entre "pasado" y "a" - de los ejemplos, parece que usted está queriendo sólo para utilizar los números onea twenty-nine, con quarterla sustitución fifteeny halfque representa thirty, pero eso no es clara. Además, para futuras preguntas, recomiendo encarecidamente el Sandbox para resolver los problemas antes de publicar.
AdmBorkBork

Respuestas:

2

Javascript, 384 381 bytes

(h,m)=>(o='one,two,three,four,five,six,seven,eight,nine,ten,eleven,twelve,thir,,fif,,,eigh,'.split`,`,o=o.map((x,i)=>i>11?(x||o[i-10])+'teen':x),(a=m>30,t=12,m?(m-30?m%15?((m=a?59-m:m)>=(b=a?19:20)?'twenty'+((m%=b)?o[a?m:m-1]:''):o[a?m:m-1])+' minutes':'quarter':'half')+(a?' to ':' past '):'')+(h%t|m?o[(a?h:(h?h-1:11))%t]+` o'clock ${h>t?'P':'A'}M`:o[11]+(h-t?' night':' noon')))

remoto
fuente
1
Funciona bien, ¡e incluso tiene un ritmo Perl de 4 bytes! Buen truco con quince, ocho, etc. por cierto.
Dennis van Gils
4

LaTeX, 466 bytes

\usepackage{fmtcount,etoolbox}\def\x{\the\numexpr}\def\n[#1]{\numberstringnum{#1}}\def\h[#1]{\ifnumequal{#1}{0}{twelve night}{\ifnumequal{#1}{12}{twelve noon}{\ifnumless{#1}{13}{\n[#1] o'clock AM}{\n[\x#1-12\relax] o'clock PM}}}}\def\m[#1]{\ifnumequal{#1}{15}{quarter}{\ifnumequal{#1}{30}{half}{\n[#1] minutes}}}\newcounter{c}\def\f[#1]#2{\ifnumequal{#2}{0}{\h[#1]}{\ifnumless{#2}{31}{\m[#2] past \h[#1]}{\setcounter{c}{\x60-#2\relax}\m[\thec] to \h[\x#1+1\relax]}}}

Simplemente llame a la macro \fcomo \f[hour]{minutes}, aquí algunas pruebas:

\begin{document}

\noindent
\textbf{Test cases:} \\ \\
00:00 = \f[00]{00} \\
12:00 = \f[12]{00} \\
06:00 = \f[6]{00} \\
18:00 = \f[18]{00} \\
06:15 = \f[6]{15} \\
18:45 = \f[18]{45} \\
11:30 = \f[11]{30} \\
13:22 = \f[13]{22} \\
17:43 = \f[17]{43} \\

\noindent
\textbf{More test cases:} \\ \\
00:13 = \f[00]{13} \\
12:12 = \f[12]{12} \\
12:15 = \f[12]{15} \\
11:45 = \f[11]{45} \\
11:41 = \f[11]{41} \\

\end{document}
Beto
fuente
¿Sabes cómo y dónde puedo probar esto? Probé la aracnoides y papeeria pero no lo hicieron el trabajo.
Dennis van Gils
@DennisvanGils Probé este pastebin.com/kdpSQHSb en papeeria y funcionó.
Bob
Lo probé con el código pastebin y funcionó, suponiendo que no funcionó porque yo no tenía\documentclass[a4paper,12pt]{article}
Dennis van Gils
3

Python 2, 498 bytes

La entrada viene como argumento de función. Primera hora y luego minuto, ambos como entero. El resultado se imprime en la pantalla.

def g(h,m):
 a=lambda x:"twelve one two three four five six seven eigth nine ten eleven".split()[x%12];b=lambda x:a(x)+" o'clock "+["AM","PM"][x>=12]
 if m:
    z=m if m<30else 60-m;print(a(z)if z<13else("twenty"+(a(z-20)if z-20else"")if z>19else"thirteen fourteen fifteen sixteen seventeen eighteen nineteen".split()[z-13])if m%15else"quarter"if m-30else"half")+(" minutes"if m-30and m%15else"")+[" past "+b(h)," to "+b(h+1)][m>30]
 else:print"twelve "+("noon"if h else "night")if h in[0,12]else b(h)

Pruébalo en línea! (con casos de prueba ligeramente extendidos)

Ese fue un golf bastante divertido. Aunque todos esos ternarios anidados me volvieron un poco loco ^^
Estaba planeando hacer esto en Pyth después de esto, pero no creo que sea mentalmente capaz de hacer esto en este momento (o nunca).

Sin golf:

def ungolfed(h,m):
    toStr=lambda x:"twelve one two three four five six seven eigth nine ten eleven".split()[x%12]
    hour=lambda x:toStr(x)+" o'clock "+["AM","PM"][x>=12]
    minute=lambda x:"twenty"+(toStr(x-20)if x-20else"")if x>19else"thirteen fourteen fifteen sixteen seventeen eighteen nineteen".split()[x-13]

    if m:
        s=""
        if m==30:
            s+="half"
        else:
            if m%15==0:
                s+="quarter"
            else:
                z=m if m<30 else 60-m
                if z<13:
                    s+=toStr(z)
                else:
                    s+=minute(z)
        print s+(" minutes"if m-30and m%15else "")+[" past "+hour(h)," to "+hour(h+1)][m>30]
    else:
        if h in[0,12]:
            print"twelve "+("noon"if h else "night")
        else:
            print hour(h)
Denker
fuente
Debes [x>12]ser [x>=12], las 12:01 son PM, no AM
Dennis van Gils
1
@DennisvanGils Buena captura, gracias! Arreglado. :) Los alemanes no estamos tan cómodos con todo este asunto de AM / PM, supongo: P
Denker
Soy holandés, así que también tuve que buscarlo para estar seguro.
Dennis van Gils
1

Perl 5, 367 361 385 Bytes

Confuso

use integer;$_=<>;~/(\d+):(\d+)/;@b=(one,two,three,four,five,six,seven,eight,nine,ten,eleven,twelve); @x=(@b,thirteen,(map{/fi/?quarter:$_.teen}@b[3..8]),(map{twenty.$_}'',@b[0..8]),half);@y=map{/^q|h/?$_:$_.' minutes'}@x;$s=1-$2/31;$y=abs((-29,0)[$s]+$2%31)-1;$h=$1-$s;print((+-$2?@y[$y].' '.(to,past)[$s].' ':'').@b[$h++%12]." o' clock ".($h%12?(AM,PM)[$h/12]:(night,noon)[$h/12%2]))

Formateado y casos de prueba:

use integer;
map{
    # capture (implicit $_)
    ~/(\d+):(\d+)/;
    # bare words
    @b=(one,two,three,four,five,six,seven,eight,nine,ten,eleven,twelve);
    # construct up to 30
    @x=(@b,thirteen,
       (map{/fi/?quarter:$_.teen}@b[3..8]),
       (map{twenty.$_}'',@b[0..8]),half);
    # quarter/half business
    @y=map{/^q|h/?$_:$_.' minutes'}@x;
    # whether we are to/past
    $s=1-$2/31;
    # num minutes wrapped around
    $y=abs((-29,0)[$s]+$2%31)-1;
    # num hours
    $h=$1-$s;
    #print('$s='.$s."\th=".$h."\th%12=".($h%12)."\n");
    print($_.' > ');
    #minute component
    print((+-$2
          ?@y[$y].' '.(to,past)[$s].' '
          :'')
        # hours
        .@b[$h++%12]
        ." o' clock "
        # Night/Noon
        .($h%12
          ?(AM,PM)[$h/12]
          :(night,noon)[$h/12%2]));
    print "\n"
}
('00:00:00',
 '00:01:00',
 '11:59:00',
 '12:00:00',
 '12:01:00',
 '06:00:00', 
 '18:00:00', 
 '06:15:00', 
 '18:45:00', 
 '11:30:00', 
 '13:22:00', 
 '17:43:00',
 '23:59:59')
Walpen
fuente
Esto parece dar one minutes to one o' clock nightcomo salida para 00:01, en lugar de one minutes past twelve o'clock AMoone minutes past twelve night
Dennis van Gils
Tienes razón. He agregado casos de prueba alrededor de las 12 veces.
walpen
1

C, 478 bytes

*w(i){char*p,*n[]={"","one","two","three","four","five","six","seven","eight","nine","ten","eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen","eighteen","nineteen"};return i>19?asprintf(&p,"twenty%s",n[i%20]),p:n[i];}main(m,h){scanf("%d%d",&h,&m);m>30?h++:0;printf("%s%s%s%s%s %s\n",m%15?m>30?w(60-m):w(m):m^30?m?"quarter":"":"half",m%15?" minutes":"",m?m>30?" to ":" past ":"",w((h+11)%12+1),h%12||m?" o'clock":"",h%12||m?h>11?"PM":"AM":h?"noon":"night");}

Casos de prueba

$ echo "0 0" | ./a.out
twelve night
$ echo "12 0" | ./a.out
twelve noon
$ echo "6 0" | ./a.out
six o'clock AM
$ echo "18 0" | ./a.out
six o'clock PM
$ echo "6 15" | ./a.out
quarter past six o'clock AM
$ echo "18 45" | ./a.out
quarter to seven o'clock PM
$ echo "11 30" | ./a.out
half past eleven o'clock AM
$ echo "13 22" | ./a.out
twentytwo minutes past one o'clock PM
$ echo "17 43" | ./a.out
seventeen minutes to six o'clock PM
$ echo "0 9" | ./a.out
nine minutes past twelve o'clock AM

Pruébalo aquí .

Cole Cameron
fuente
Se ve bien. También es interesante cómo 00 00da la salida correcta, mientras que 00:00da one minutes past twelve o'clock AM, aunque estoy seguro de que tiene algo que ver con cómo analiza la entrada.
Dennis van Gils
Sí, espera dos enteros (horas y minutos). scanfprobablemente no analiza '00: 00 'como cabría esperar :)
Cole Cameron
0

Lote, 779 774 752 749 bytes

@echo off
set t=%1
set/ah=%t:~0,2%,m=%t:~3,2%
set p=past
if %m% gtr 30 set p=to&set/am=60-m,h+=1
for %%a in ("one minute.1" quarter.15 half.30)do if %%~xa==.%m% set o=%%~na&goto g
set o=
if %m% gtr 20 set o=twenty-&set/am-=20
for %%a in (one.1 two.2 three.3 four.4 five.5 six.6 seven.7 eight.8 nine.9 ten.10 eleven.11 twelve.12 thirten.13 fourteen.14 sixteen.16 seventeen.17 eighteen.18 nineteen.19 twenty.20)do if %%~xa==.%m% set o=%o%%%~na minutes
:g
if not %m%==0 set o=%o% %p% 
set a= AM
if %h% gtr 12 set a= PM&set/ah%%=12
if %h%==0 (echo %o%twelve night)else if %h%==12 (echo %o%twelve noon)else for %%a in (one.1 two.2 three.3 four.4 five.5 six.6 seven.7 eight.8 nine.9 ten.10 eleven.11)do if %%~xa==.%h% echo %o%%%~na o'clock%a%

Cambie la segunda línea a set t=%1%time%predeterminada para decir la hora actual si no se proporciona la hora.

Editar: ahorré 22 bytes al optimizar mis set/adeclaraciones. Guardado 3 bytes gracias a @ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ.

Cuando escribí mi versión original, cometí el error de decir la hora como realmente la diría, es decir, en punto solo a las horas exactas, y a la medianoche y al mediodía en lugar de las doce de la noche y las doce del mediodía:

@echo off
set t=%1
set/a h=%t:~0,2%
set/a m=%t:~3,2%
set p=past
if %m% gtr 30 set p=to&set/a m=60-m&set/a h=h+1
for %%a in ("one minute.1" quarter.15 half.30) do if %%~xa==.%m% set o=%%~na&goto g
set o=
if %m% gtr 20 set o=twenty-&set/a m=%m%-20
for %%a in (one.1 two.2 three.3 four.4 five.5 six.6 seven.7 eight.8 nine.9 ten.10 eleven.11 twelve.12 thirten.13 fourteen.14 sixteen.16 seventeen.17 eighteen.18 nineteen.19 twenty.20) do if %%~xa==.%m% set o=%o%%%~na minutes
:g
set o=%o% %p% 
set a= AM
if %h% gtr 12 set a= PM&set/a h=h%%12
if %m%==0 set a= o'clock%a%&set o=
if %h%==0 (echo %o%midnight)else if %h%==12 (echo %o%midday)else for %%a in (one.1 two.2 three.3 four.4 five.5 six.6 seven.7 eight.8 nine.9 ten.10 eleven.11) do if %%~xa==.%h% echo %o%%%~na%a%
Neil
fuente
Sus pruebas de 12:00 y 00:00 no funcionan, solo hacen eco midnighty en middaylugar de twelve nighty twelve noon. Realmente me gusta cómo usas extensiones y nombres falsos en tu bucle for por cierto.
Dennis van Gils
2
@DennisvanGils Probablemente hay otras pruebas que falla; Lo arreglaré más tarde.
Neil
@DennisvanGils ¡Creo que está funcionando ahora, y convenientemente también es más corto!
Neil