Ubah Waktu menjadi String

17

Masalah

Suatu hari, bos Anda mendatangi Anda dan memberi tahu Anda bahwa dia perlu tahu waktu. Dia masih bersikeras setelah Anda menunjuk jam tepat di atas kepala Anda, dan mengaku memiliki kasus parah dyscalculia , yang menyebabkan dia bahkan tidak dapat melihat angka pada jam. Sementara Anda masih bertanya-tanya bagaimana seseorang yang tidak dapat melihat angka dapat menjalankan perusahaan, dia memberi tahu Anda untuk "melakukan sesuatu tentang hal itu", apa pun itu.

Tugas Anda sekarang adalah membuat program atau fungsi yang, diberi waktu input dengan jam dan menit (detik opsional) (jam berbasis 24), menghasilkan kalimat bahasa Inggris yang dapat dibaca, yang tidak mengandung angka.

Tidak perlu mengganti detik.

Misalnya 08:45:15harus outputquarter to nine o'clock AM

Uji kasus

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

Aturan

Angka-angka keluaran dapat berupa empat puluh dua atau empat puluh dua, mana yang paling Anda sukai. Tidak ada celah standar. Mengejar baris baru diperbolehkan, tetapi hukumannya harus di 1 baris.

Masukan bisa dalam format yang Anda inginkan, misalnya HH:MM:SS, HH,MM,SS, HHMMSS, HH/MM/SS, atau varian tanpa detik, tetapi Anda harus membuat format masukan jelas dalam jawaban Anda. Itu tidak diperlukan untuk output, one minutebukanone minutes

untuk menit mulai dari 0 hingga 30 (termasuk 0 dan 30) Anda harus menggunakan past, dan untuk yang lain Anda harus menggunakanto

Karena waktu relatif, kode terpendek dalam byte menang.

Dennis van Gils
sumber
1
Ini sepertinya tantangan yang bagus, saya sangat menyarankan untuk menghapus bonus. Kecuali Anda tahu persis apa yang Anda lakukan, itu adalah satu hal yang harus dihindari ketika menulis tantangan.
Denker
1
Dua poin (minor) lagi: mengapa penting bagaimana Anda menulis forty-fiveketika kasus uji dengan jelas menyatakan quarter tosebagai format input yang sesuai? (cukup ubah ke empat puluh dua;)) Juga, kolmogorov-kompleksitas bukanlah tag yang sesuai.
Sanchises
@sanchises diedit. Saya salah paham tentang tag kolmogorov, dan berpikir itu ada hubungannya dengan masalah dalam menghasilkan string, bukan hanya string yang diberikan.
Dennis van Gils
1
@ TimmyD The -70% adalah lelucon, saya tidak membayangkan ada orang yang mencoba menerjemahkan bahasa Prancis dalam kode-golf. Namun, saya merasa memiliki ukuran negatif adalah hadiah yang layak untuk penerjemah bahasa Prancis-Inggris yang sempurna
Dennis van Gils
Itu terlihat jauh lebih baik, tetapi beberapa klarifikasi format diperlukan. Secara khusus mengenai memilih antara "masa lalu" dan "untuk" - dari contoh-contoh, kedengarannya seperti Anda ingin hanya memanfaatkan angka oneuntuk twenty-nine, dengan quartermenggantikan fifteendan halfmewakili thirty, tapi itu tidak jelas. Juga, untuk pertanyaan di masa mendatang, saya sungguh-sungguh merekomendasikan Sandbox untuk menyelesaikan kekusutan sebelum memposting.
AdmBorkBork

Jawaban:

2

Javascript, 384 381 byte

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

dihapus
sumber
1
Bekerja dengan baik, dan bahkan memiliki Perl satu kali dikalahkan oleh 4 byte! Trik yang bagus dengan fif, eigh dll btw.
Dennis van Gils
4

LaTeX, 466 byte

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

Panggil saja makro \f sebagai \f[hour]{minutes}, di sini beberapa tes:

\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
sumber
Apakah Anda tahu bagaimana dan di mana saya bisa mencoba ini? Saya mencoba arachnoid dan papeeria tetapi mereka tidak berhasil.
Dennis van Gils
@DennisvanGils Saya mencoba pastebin.com/kdpSQHSb ini di papeeria dan berhasil.
Bob
Sudah mencobanya dengan kode pastebin dan itu berhasil, menebak itu tidak berhasil karena saya tidak punya\documentclass[a4paper,12pt]{article}
Dennis van Gils
3

Python 2, 498 byte

Input muncul sebagai argumen fungsi. Jam pertama dan kemudian menit, keduanya sebagai bilangan bulat. Hasilnya akan dicetak ke layar.

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)

Cobalah online! (dengan testcards sedikit diperpanjang)

Itu golf yang sangat menyenangkan. Meskipun semua terner yang bersarang membuat saya sedikit gila ^^
Saya berencana melakukan ini di Pyth setelah ini, tetapi saya tidak berpikir bahwa saya secara mental dapat melakukan ini pada saat ini (atau pernah).

Tidak Disatukan:

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
sumber
Anda [x>12]seharusnya [x>=12], 12:01 adalah PM, bukan AM
Dennis van Gils
1
@ DennisvanGils Tangkapan yang bagus, terima kasih! Memperbaikinya. :) Kami orang Jerman tidak nyaman dengan semua hal ini pada pagi / malam - saya kira: P
Denker
Saya Belanda, jadi saya harus mencarinya sendiri juga untuk memastikan.
Dennis van Gils
1

Perl 5, 367 361 385 Bytes

Rusak

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

Kasus yang diformat dan diuji:

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
sumber
Ini tampaknya memberikan one minutes to one o' clock nightoutput untuk 00:01, bukan one minutes past twelve o'clock AMatauone minutes past twelve night
Dennis van Gils
Kamu benar. Saya telah menambahkan test case sekitar 12 kali.
walpen
1

C, 478 byte

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

Uji Kasus

$ 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

Coba di sini .

Cole Cameron
sumber
Terlihat baik. Menarik juga bagaimana 00 00memberikan output yang benar, sementara 00:00memberi one minutes past twelve o'clock AM, meskipun saya yakin itu ada hubungannya dengan bagaimana Anda mengurai input.
Dennis van Gils
Ya, ia mengharapkan dua bilangan bulat (jam dan menit). scanfmungkin tidak menguraikan '00: 00 'seperti yang mungkin diharapkan :)
Cole Cameron
0

Batch, 779 774 752 749 byte

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

Ubah baris kedua set t=%1%time%ke default untuk mengatakan waktu saat ini jika tidak ada waktu yang disediakan.

Sunting: Disimpan 22 byte dengan mengoptimalkan set/apernyataan saya . Disimpan 3 byte berkat @ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ.

Ketika saya menulis versi asli saya, saya membuat kesalahan dengan mengatakan waktu sebagaimana saya benar-benar mengatakannya, yaitu jam hanya pada jam yang tepat, dan tengah malam dan tengah hari, bukan dua belas malam dan dua belas siang:

@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
sumber
Tes 12:00 dan 00:00 Anda tidak berfungsi, itu hanya akan bergema midnightdan middaybukannya twelve nightdan twelve noon. Saya sangat suka bagaimana Anda menggunakan ekstensi dan nama palsu di untuk btw loop Anda.
Dennis van Gils
2
@ DennisvanGils Mungkin ada tes lain yang gagal; Saya akan memperbaikinya nanti.
Neil
@ DennisvanGils Saya pikir ini berfungsi sekarang, dan mudahnya juga lebih pendek!
Neil