Перетворити час у рядок


17

Проблема

Одного разу ти бос підходить до тебе і каже тобі, що йому потрібно знати час. Він все ще наполягає, коли ви вказуєте на годинник безпосередньо над вашою головою, і зізнається, що у нього є важкий випадок дискалкулії , через який він навіть не може бачити цифри на годиннику. Поки ви все ще цікавитеся, як хтось, не бачивши номери, може керувати компанією, він говорить вам "зробити щось із цим", як би там не було.

Ваше завдання зараз - створити програму або функцію, яка, враховуючи час введення годин і хвилин (секунди необов’язкові) (години на основі 24), виводить читабельне англійське речення, яке не містить чисел.

Не потрібно витісняти секунди.

Наприклад, 08:45:15слід вивестиquarter to nine o'clock AM

Тестові справи

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

Правила

Виведення номерів може бути як у сорок двох, так і в сорок два, що вам більше подобається. Стандартні лазівки заборонені. Дозволені нові рядки, але речення має бути в 1 рядку.

Вхідні дані можуть бути в будь-якому форматі , який ви хочете, наприклад HH:MM:SS, HH,MM,SS, HHMMSS, HH/MM/SSабо будь-який варіант без секунд, але ви повинні зробити формат введення ясно в своїй відповіді. Він не потрібен для виведення one minuteзамістьone minutes

для хвилин, починаючи від 0 до 30 (включено 0 і 30), ви повинні використовувати past, а для інших - використовуватиto

Оскільки час відносний, виграє найкоротший код у байтах.


1
Це виглядає як приємний виклик, трохи настійно пропоную зняти бонуси. Якщо ви точно не знаєте, чим займаєтесь, цього потрібно уникати, коли пишете завдання.
Денкер

1
Ще два (другорядні) моменти: чому важливо, як ви пишете, forty-fiveколи в тестових випадках чітко quarter toзазначено відповідний формат введення? (просто поміняйте його на сорок два;)) Також колгорогоров-складність не є відповідним тегом.
Санчіз

@sanchises відредаговано. Я неправильно зрозумів тег kolmogorov і вважав, що це пов'язано з проблемами у виведенні будь-якого рядка, а не лише заданого рядка.
Денніс ван Гілс

1
@TimmyD -70% - це жарт, я не уявляв, що хтось спробує перекласти французьку мову на код-гольф. Однак я вважаю, що наявність негативного розміру - це гідна винагорода за ідеального французько-англійського перекладача
Денніс ван Гілс

Це виглядає набагато краще, але потрібно ще кілька уточнень форматування. В зокрема в відношенні вибору між «минулим» і «до» - із прикладів, це звучить , як ви , які бажають використовувати тільки цифри oneв twenty-nine, з quarterзаміною fifteenі halfпредставляючи thirty, але це не ясно. Також для майбутніх питань я щиро рекомендую « Пісочниці» відпрацювати передумки перед публікацією.
AdmBorkBork

Відповіді:


2

Javascript, 384 381 байт

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


1
Працює чудово, і навіть Perl один бив на 4 байти! Хороший трюк з п'ятьма, вісьмоми і т. Д.
Денніс ван Гілс

4

LaTeX, 466 байт

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

Просто зателефонуйте до макросу \fяк \f[hour]{minutes}ось деякі тести:

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

Ви знаєте, як і де я можу це спробувати? Я спробував павукоподібні та паперії, але вони не спрацювали.
Денніс ван Гілс

@DennisvanGils Я спробував це pastebin.com/kdpSQHSb в паперії, і він спрацював.
Боб

Спробував це з кодом пастебіна, і це спрацювало, гадаючи, що він не працює, тому що мене не було\documentclass[a4paper,12pt]{article}
Денніс ван Гілс

3

Python 2, 498 байт

Введення входить як аргумент функції. Перша година, а потім хвилина, як ціле число. Результат друкується на екрані.

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)

Спробуйте в Інтернеті! (з трохи розширеними тестовими вікнами)

Це був досить веселий гольф. Хоча всі ці вкладені тернари звели мене з розуму трохи ^^
Я планував робити це в Pyth після цього, але я не думаю, що в даний момент (або коли-небудь) я розумово не в змозі це зробити.

Безумовно:

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)

Ви [x>12]повинні бути [x>=12], 12:01 - вечора, а не AM
Денніс ван Гілс

1
@DennisvanGils Хороший улов, дякую! Виправлено це. :) Нам, німцям, не так зручно з цією AM / PM-річчю, я здогадуюсь: P
Denker

Я голландець, тому мені довелося переконатися і в цьому, щоб бути впевненим.
Денніс ван Гілс

1

Perl 5, 367 361 385 байт

Гарбуз

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

Форматовані та тестові приклади:

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

Здається, це дасть one minutes to one o' clock nightвихід на 00:01, замість one minutes past twelve o'clock AMабоone minutes past twelve night
Денніс ван Гілс

Ти маєш рацію. Я додав тестові випадки приблизно 12 разів.
пройти

1

C, 478 байт

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

Випробування

$ 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

Спробуйте тут .


Виглядає чудово. Також цікаво, як 00 00дає правильний вихід, а 00:00дає one minutes past twelve o'clock AM, хоча я впевнений, що це має щось спільне з тим, як ви аналізуєте вхід.
Денніс ван Гілс

Так, він очікує два цілих числа (години та хвилини). scanfМабуть, не розбирає '00: 00 ', як можна сподіватися :)
Коул Камерон

0

Пакетна, 779 774 752 749 байт

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

Змініть другий рядок на set t=%1%time%типовий, щоб сказати поточний час, якщо не вказано час.

Редагувати: збережено 22 байти, оптимізувавши мої set/aзаяви. Збережено 3 байти завдяки @ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ.

Коли я писав свою первісну версію, я помилився, сказавши час, як я насправді сказав би, тобто годину лише в точні години, і півночі та полудня замість дванадцяти ночі та дванадцяти полудня:

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

Ваші тести 12:00 та 00:00 не працюють, вони лише перегукуються midnightі middayзамість twelve nightі twelve noon. Мені дуже подобається, як ви використовуєте підроблені розширення та назви у своєму циклі btw.
Денніс ван Гілс

2
@DennisvanGils Мабуть інші тести, які він не дає; Я виправлю це пізніше.
Ніл

@DennisvanGils Я думаю, що це працює зараз, і це зручно і коротше!
Ніл
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.