Converter o tempo em uma string

17

Problema

Um dia, seu chefe vai até você e diz que precisa saber a hora. Ele ainda insiste depois que você aponta o relógio diretamente acima da cabeça e confessa que tem um caso grave de discalculia , o que faz com que ele nem consiga ver os números no relógio. Enquanto você ainda fica imaginando como alguém incapaz de ver números pode administrar uma empresa, ele diz para você "fazer algo a respeito", seja o que for.

Sua tarefa agora é criar um programa ou função que, dado um tempo de entrada com horas e minutos (os segundos são opcionais) (as horas são baseadas em 24), emita uma frase legível em inglês, que não contém números.

Não é necessário calcular os segundos.

Por exemplo, 08:45:15deve gerarquarter to nine o'clock AM

Casos de teste

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

Regras

Os números de saída podem ser na forma de quarenta e dois ou quarenta e dois, o que você preferir. As brechas padrão não são permitidas. Novas linhas à direita são permitidas, mas a frase deve estar em 1 linha.

A entrada pode estar em qualquer formato que você quer, por exemplo HH:MM:SS, HH,MM,SS, HHMMSS, HH/MM/SS, ou qualquer variante sem segundos, mas você deve fazer o formato de entrada claro em sua resposta. Não é necessário produzir em one minutevez deone minutes

por minutos que variam de 0 a 30 (0 e 30 incluídos) você deve usar paste para os outros você deve usarto

Como o tempo é relativo, o menor código em bytes vence.

Dennis van Gils
fonte
11
Parece um bom desafio, mas sugiro fortemente que remova os bônus. A menos que você saiba exatamente o que está fazendo, é uma coisa a evitar ao escrever desafios.
DenkerFev
11
Mais dois pontos (menores): por que importa como você escreve forty-fivequando os casos de teste afirmam claramente quarter tocomo o formato de entrada apropriado? (apenas altere para quarenta e dois;)) Além disso, a complexidade kolmogorov não é uma tag apropriada.
Sanchises
@sanchises editados. Entendi mal a tag kolmogorov e pensei que tinha a ver com problemas na saída de qualquer string, em vez de apenas uma determinada string.
Dennis van Gils 05/02
11
@ TimmyD O -70% era uma piada, eu não imaginava que alguém tentaria traduzir francês em código-golfe. No entanto, sinto que ter tamanho negativo é uma recompensa decente para um perfeito francês-Inglês tradutor
Dennis van Gils
Parece muito melhor, mas são necessários mais alguns esclarecimentos de formatação. Especificamente em relação a escolha entre "passado" e "para" - a partir dos exemplos, parece que você está querendo utilizar unicamente os números onepara twenty-nine, com quartera substituição fifteene halfque representa thirty, mas isso não é clara. Além disso, para perguntas futuras, recomendo vivamente a Sandbox para resolver os problemas antes de postar.
AdmBorkBork #

Respostas:

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

removido
fonte
11
Funciona bem, e ainda tem o Perl um batida de 4 bytes! Truque agradável com quin, dezoito etc btw.
Dennis van Gils 08/02
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]}}}

Basta chamar a macro \fcomo \f[hour]{minutes}, aqui estão alguns testes:

\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}
Prumo
fonte
Você sabe como e onde posso tentar isso? Tentei aracnóide e papeeria, mas eles não funcionaram.
Dennis van Gils
@DennisvanGils Tentei este pastebin.com/kdpSQHSb na papeeria e funcionou.
Bob
Tentou fazê-lo com o código pastebin e que funcionou, supondo que não funcionou porque eu não tinha\documentclass[a4paper,12pt]{article}
Dennis van Gils
3

Python 2, 498 bytes

A entrada vem como argumento de função. Primeira hora e depois minuto, ambos como número inteiro. O resultado é impresso na tela.

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)

Experimente online! (com casos de teste levemente estendidos)

Esse foi um golfe bastante divertido. Embora todos os ternários aninhados me deixassem um pouco louca ^^,
eu estava pensando em fazer isso em Pyth depois disso, mas não acho que sou capaz de fazer isso no momento (ou nunca).

Ungolfed:

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
fonte
Seu [x>12]deve ser [x>=12], 00:01 é PM, não sou
Dennis van Gils
11
@DennisvanGils Boa captura, obrigado! Corrigido. :) Nós alemães não são confortáveis com este AM inteira / PM-coisa que eu acho: P
Denker
Eu sou holandês, então eu tive que procurar por mim mesmo para ter certeza também.
Dennis van Gils 05/02
1

Perl 5, 367 361 385 bytes

Garbled

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

Casos formatados e de teste:

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
fonte
Isto parece dar one minutes to one o' clock nightcomo saída para 00:01, em vez de one minutes past twelve o'clock AMouone minutes past twelve night
Dennis van Gils
Você está certo. Eu adicionei casos de teste em torno das 12 vezes.
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 teste

$ 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

Experimente aqui .

Cole Cameron
fonte
Parece bem. Também interessante como 00 00dá a saída correta, enquanto 00:00one minutes past twelve o'clock AM, embora eu tenha certeza que tem algo a ver com a maneira como você analisa a entrada.
Dennis van Gils
Sim, ele espera dois números inteiros (horas e minutos). scanfprovavelmente não analisa '00: 00' , como se poderia 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%

Altere a segunda linha para set t=%1%time%padrão para dizer a hora atual, se nenhuma hora for fornecida.

Editar: salvou 22 bytes otimizando minhas set/adeclarações. Guardado 3 bytes graças a @ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ.

Quando escrevi minha versão original, cometi o erro de dizer a hora como realmente diria, ou seja, apenas horas exatas e meia-noite e meio-dia, em vez de doze e doze horas:

@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
fonte
Seus testes de 12:00 e 00:00 não funcionam, eles apenas ecoam midnighte em middayvez de twelve nighte twelve noon. Eu realmente gosto de como você usa extensões e nomes falsos no seu loop for btw.
Dennis van Gils 05/02
2
@DennisvanGils Provavelmente existem outros testes em que ele falha; Eu vou consertar isso mais tarde.
Neil
@DennisvanGils Acho que está funcionando agora e, convenientemente, também é mais curto!
Neil