แปลงเวลาเป็นสตริง


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
ดูเหมือนว่าจะเป็นการท้าทายที่ดี แต่ฉันขอแนะนำให้นำโบนัสออก หากคุณไม่ทราบว่ากำลังทำอะไรอยู่สิ่ง
Denker

1
อีกสองจุด (เล็กน้อย): ทำไมมันถึงสำคัญว่าคุณเขียนforty-fiveเมื่อกรณีทดสอบชัดเจนquarter toว่าเป็นรูปแบบอินพุตที่เหมาะสม (เพียงเปลี่ยนเป็นสี่สิบสอง)) นอกจากนี้kolmogorov-complexไม่ใช่แท็กที่เหมาะสม
Sanchises

@sanchises แก้ไขแล้ว ฉันเข้าใจผิดแท็ก kolmogorov และคิดว่ามันเกี่ยวข้องกับปัญหาในการแสดงผลสตริงใด ๆ แทนที่จะเป็นสตริงที่กำหนดเท่านั้น
Dennis van Gils

1
@ TimmyD -70% คนหนึ่งเป็นเรื่องตลกฉันไม่คิดว่าจะมีใครพยายามแปลภาษาฝรั่งเศสในรหัสกอล์ฟ อย่างไรก็ตามฉันรู้สึกว่าการมีขนาดที่ไม่ดีเป็นรางวัลที่เหมาะสมสำหรับนักแปลภาษาฝรั่งเศส - ภาษาอังกฤษที่สมบูรณ์แบบ
Dennis van Gils

ดูดีขึ้นมาก แต่ต้องการการจัดรูปแบบเพิ่มเติมอีกเล็กน้อย โดยเฉพาะเกี่ยวกับการเลือกระหว่าง "ที่ผ่านมา" และ "ไป" - จากตัวอย่างก็เสียงเหมือนคุณกำลังต้องการที่จะใช้เพียงตัวเลขoneที่จะtwenty-nineมีquarterการเปลี่ยนfifteenและhalfเป็นตัวแทนthirtyแต่ที่ไม่ชัดเจน นอกจากนี้สำหรับคำถามในอนาคตฉันขอแนะนำให้Sandboxหาข้อผิดพลาดก่อนโพสต์
AdmBorkBork

คำตอบ:


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


1
ใช้งานได้ดีและยังมี Perl หนึ่งจังหวะ 4 ไบต์! เคล็ดลับดีกับห้า, eigh ฯลฯ btw
Dennis van Gils

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}

คุณรู้วิธีและสถานที่ที่ฉันสามารถลองสิ่งนี้หรือไม่? ฉันลองอารานีนอยด์และปาเปเรียแต่พวกเขาไม่ทำงาน
Dennis van Gils

@DennisvanGils ฉันลองนี้pastebin.com/kdpSQHSbใน papeeria แล้วก็ใช้งานได้
บ๊อบ

พยายามใช้รหัส pastebin และใช้งานได้คาดเดาว่ามันจะไม่ทำงานเพราะฉันไม่มี\documentclass[a4paper,12pt]{article}
Dennis van Gils

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 หลังจากนี้ แต่ฉันไม่คิดว่าฉันจะสามารถทำสิ่งนี้ได้ในขณะนี้ (หรือตลอดกาล)

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)

คุณ[x>12]ควรจะ[x>=12], 12:01 PM คือไม่ AM
เดนนิสแวน Gils

1
@DennisvanGils ดีมากขอบคุณ! ซ่อมมัน. :) พวกเราชาวเยอรมันไม่ค่อยพอใจกับสิ่งนี้ทั้ง AM / PM - ฉันคิดว่า: P
Denker

ฉันเป็นคนดัตช์ดังนั้นฉันต้องหาตัวเองให้แน่ใจด้วย
Dennis van Gils

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เป็นผลผลิตสำหรับ 0:01 แทนone minutes past twelve o'clock AMหรือone minutes past twelve night
เดนนิสแวน Gils

คุณถูก. ฉันได้เพิ่มกรณีทดสอบประมาณ 12 ครั้ง
walpen

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แม้ว่าฉันจะแน่ใจว่ามีบางอย่างเกี่ยวกับวิธีการวิเคราะห์คำที่คุณป้อนเข้า
Dennis van Gils

ใช่คาดว่าจะเป็นจำนวนเต็มสองจำนวน (ชั่วโมงและนาที) 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ฉันชอบวิธีที่คุณใช้ส่วนขยายและชื่อปลอมใน for btw ของคุณแบบวนซ้ำ
Dennis van Gils

2
@DennisvanGils อาจมีการทดสอบอื่น ๆ ที่ล้มเหลว ฉันจะแก้ไขมันในภายหลัง
Neil

@DennisvanGils ฉันคิดว่ามันใช้งานได้ในขณะนี้และมันก็สั้นลงด้วย!
Neil
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.