Convertir l'heure en chaîne

17

Problème

Un jour, votre patron s'approche de vous et vous dit qu'il a besoin de connaître l'heure. Il insiste toujours après que vous ayez pointé l'horloge directement au-dessus de votre tête, et avoue qu'il a un cas sévère de dyscalculie , ce qui l' empêche même de voir les chiffres sur une horloge. Alors que vous vous demandez toujours comment une personne incapable de voir les chiffres peut diriger une entreprise, il vous dit de "faire quelque chose", quoi que ce soit.

Votre tâche consiste maintenant à créer un programme ou une fonction qui, étant donné un temps d'entrée avec des heures et des minutes (les secondes sont facultatives) (les heures sont basées sur 24), génère une phrase anglaise lisible, qui ne contient pas de chiffres.

Il n'est pas nécessaire de sortir les secondes.

Par exemple, 08:45:15devrait sortirquarter to nine o'clock AM

Cas de test

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

Règles

La sortie des nombres peut être à la fois sous la forme de quarante-deux ou quarante-deux, selon ce que vous préférez. Les échappatoires standard ne sont pas autorisées. Les sauts de ligne sont autorisés, mais la phrase doit être sur 1 ligne.

L' entrée peut être dans un format que vous voulez, par exemple HH:MM:SS, HH,MM,SS, HHMMSS, HH/MM/SSou toute variante sans secondes, mais vous devez faire le format d'entrée clair dans votre réponse. Il n'est pas nécessaire de sortir one minuteau lieu deone minutes

pendant des minutes allant de 0 à 30 (0 et 30 inclus), vous devez utiliser past, et pour les autres, vous devez utiliserto

Parce que le temps est relatif, le code le plus court en octets gagne.

Dennis van Gils
la source
1
Cela ressemble à un beau défi, mais je suggère fortement de supprimer les bonus. À moins que vous sachiez exactement ce que vous faites, c'est une chose à éviter lors de la rédaction de défis.
Denker
1
Deux autres points (mineurs): pourquoi est-il important de savoir comment vous écrivez forty-fivelorsque les cas de test indiquent clairement quarter toque le format d'entrée approprié? (il suffit de le changer en quarante-deux;)) En outre, kolmogorov-complexité n'est pas une balise appropriée.
Sanchises
@sanchises édité. J'ai mal compris la balise kolmogorov et j'ai pensé que cela avait à voir avec des problèmes de sortie de n'importe quelle chaîne, au lieu d'une chaîne donnée uniquement.
Dennis van Gils
1
@TimmyD Le -70% était une blague, je n'imaginais pas que quelqu'un essaierait de traduire le français en code-golf. Cependant, je pense qu'avoir une taille négative est une récompense décente pour un parfait traducteur français-anglais
Dennis van Gils
Cela semble beaucoup mieux, mais quelques clarifications de mise en forme supplémentaires sont nécessaires. En ce qui concerne spécifiquement le choix entre "passé" et "à" - à partir des exemples, il semble que vous souhaitiez uniquement utiliser les nombres oneà twenty-nine, avec quarterremplacement fifteenet halfreprésentation thirty, mais ce n'est pas clair. De plus, pour les questions futures, je recommande vivement le bac à sable pour résoudre les problèmes avant de publier.
AdmBorkBork

Réponses:

2

Javascript, 384 381 octets

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

supprimé
la source
1
Fonctionne très bien, et a même le Perl un battement de 4 octets! Belle astuce avec fif, eigh etc btw.
Dennis van Gils
4

LaTeX, 466 octets

\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]}}}

Appelez simplement la macro \fcomme \f[hour]{minutes}, voici quelques tests:

\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}
Bob
la source
Savez-vous comment et où je peux essayer cela? J'ai essayé l' arachnoïde et la papeeria mais ça n'a pas marché.
Dennis van Gils
@DennisvanGils J'ai essayé ce pastebin.com/kdpSQHSb dans la papeeria et cela a fonctionné.
Bob
Je l'ai essayé avec le code pastebin et cela a fonctionné, devinant que cela n'a pas fonctionné parce que je n'avais pas\documentclass[a4paper,12pt]{article}
Dennis van Gils
3

Python 2, 498 octets

L'entrée est un argument de fonction. Première heure puis minute, toutes deux sous forme d'entier. Le résultat est imprimé à l'écran.

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)

Essayez-le en ligne! (avec des cas de test légèrement étendus)

C'était un golf assez amusant. Bien que tous ces ternaires imbriqués m'aient rendu un peu fou ^^
Je prévoyais de le faire en Pyth après cela, mais je ne pense pas que je suis mentalement capable de le faire pour le moment (ou jamais).

Non 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
la source
Tu [x>12]devrais être [x>=12], 12 h 01 est PM, pas AM
Dennis van Gils
1
@DennisvanGils Bonne prise, merci! A corrigé. :) Nous, les Allemands, ne sommes pas à l'aise avec toute cette chose AM / PM, je suppose: P
Denker
Je suis hollandais, donc j'ai dû le rechercher moi-même pour être sûr aussi.
Dennis van Gils
1

Perl 5, 367 361 385 octets

Brouillé

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

Cas formatés et tests:

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
la source
Cela semble donner one minutes to one o' clock nightcomme sortie pour 00:01, au lieu de one minutes past twelve o'clock AMouone minutes past twelve night
Dennis van Gils
Tu as raison. J'ai ajouté des cas de test environ 12 fois.
walpen
1

C, 478 octets

*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");}

Cas de test

$ 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

Essayez-le ici .

Cole Cameron
la source
Semble bien. Aussi intéressant de savoir comment 00 00donne la sortie correcte, tout en 00:00donne one minutes past twelve o'clock AM, bien que je sois sûr que cela a quelque chose à voir avec la façon dont vous analysez les entrées.
Dennis van Gils
Oui, il attend deux entiers (heures et minutes). scanfn'analyse probablement pas '00: 00 'comme on pourrait l'espérer :)
Cole Cameron
0

Lot, 779 774 752 749 octets

@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%

Remplacez la deuxième ligne par set t=%1%time%défaut pour dire l'heure actuelle si aucune heure n'est fournie.

Edit: économisé 22 octets en optimisant mes set/arelevés. Sauvegardé 3 octets grâce à @ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ.

Quand j'ai écrit ma version originale, j'ai fait l'erreur de dire l'heure comme je le dirais en fait, c'est-à-dire uniquement sur les heures exactes, et minuit et midi au lieu de douze nuits et midi:

@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
la source
Vos tests de 12h00 et de 00h00 ne fonctionnent pas, ils ne font qu'écho midnightet middayau lieu de twelve nightet twelve noon. J'aime vraiment la façon dont vous utilisez de fausses extensions et noms dans votre boucle for btw.
Dennis van Gils
2
@DennisvanGils Il y a probablement d'autres tests qui échouent; Je vais le réparer plus tard.
Neil
@DennisvanGils Je pense que ça marche maintenant, et c'est aussi plus court!
Neil