Imprimir un reloj de palabras

59

Desde que vi el primero hace unos años, siempre me subyugó este tipo de reloj de palabras en el que el tiempo se deletrea con palabras que se iluminan o no en una oración significativa.

Un reloj de palabras

El texto que se muestra en ese reloj es el siguiente.

IT IS HALF TEN
QUARTER TWENTY
FIVE MINUTES TO
PAST TWO THREE
ONE FOUR FIVE
SIX SEVEN EIGHT
NINE TEN ELEVEN
TWELVE O'CLOCK

Su tarea es escribir un reloj que funcione. Las palabras se iluminan si y solo si son relevantes para imprimir la hora actual. De lo contrario, están encendidos. Las palabras se "iluminan" al imprimirse y se "iluminan" al ser reemplazadas por varios espacios que son la longitud de la palabra.

Ejemplo: si la hora actual es 17:23, el texto impreso debe ser exactamente el siguiente:

IT IS 
        TWENTY
FIVE MINUTES
PAST
         FIVE

Reglas

  1. El tiempo impreso es la variante 12h, pero sin AM / PM.
  2. El redondeo se realiza en base a minutos solamente (los segundos son totalmente irrelevantes). El redondeo se realiza al múltiplo más cercano de 5. Entonces, por ejemplo, aunque 17:52:38 realmente es más cercano a 17:55, pero dado que los segundos son irrelevantes, 17:52 se redondea a 17:50, y el texto impreso es "ES DIEZ MINUTOS A SEIS" (con espacios relevantes). Entonces, si XXes un múltiplo de cinco, XXse utilizará desde HH: (XX-2): 00 hasta HH: (XX + 2): 59. La palabra MINUTESdebe aparecer si FIVE, TENo TWENTYse iluminan en la sección minutos (antes de "A" o "pasado").
  3. Todas las palabras irrelevantes se reemplazan por tantos espacios como sea necesario para mantener el texto donde se encuentra en la plantilla de arriba. Los espacios finales pueden recortarse. Deben mantenerse los espacios relevantes para mantener el texto en la posición esperada.
  4. Las líneas finales también se pueden recortar. Las líneas vacías relevantes aún deben aparecer. Ejemplo:

    IT IS      TEN
    
         MINUTES
    PAST TWO
    
  5. No encienda TENen la primera línea o FIVEen la tercera línea cuando estos valores se refieren a las horas.

  6. Puede aceptar una entrada. Si acepta una entrada, la entrada será el momento de imprimir en cualquier formato válido que desee (cadena, lista de enteros, hora nativa, escriba su soporte de idioma, ...), pero no se permiten parámetros si no están relacionados a la hora de imprimir. Si no admite ninguna entrada, debe usar la hora actual. Si admite ambos, eso es mejor, pero no hay bonificación;)
  7. Su código puede ser un programa, una función, un lambda pero no un fragmento.
  8. Si su idioma admite la impresión de alguna manera, debe imprimir el resultado (en un archivo, en la salida estándar, no me importa). Si su idioma no admite la impresión de ninguna manera, se le permite simplemente "devolver" el texto esperado. El resultado puede ser todo en mayúsculas o todas en minúsculas, no una mezcla de ambos.
  9. Se aplican lagunas estándar.
  10. Este es el código de golf, por lo que gana el código más corto.
  11. En la medida de lo posible, proporcione un enlace a un intérprete en línea de su idioma.

Casos de prueba

Input:  <no input> (the current local time is 19:20)
Output:     
IT IS
        TWENTY
     MINUTES
PAST 

    SEVEN

Input: 13:15
Output: (empty line is being printed)
IT IS
QUARTER

PAST
ONE

Input: 13:58
Output: (rounding)
IT IS


     TWO



       O'CLOCK

Input: 14:30
Output: (half is always a edge-case)
IT IS HALF


PAST TWO

Input: 15:35
Output: (light up "TO")
IT IS
        TWENTY
FIVE MINUTES TO

    FOUR

Input: 10:00
Output: (do not use the TEN or FIVE on the first line when referring to the hours)
IT IS





    TEN
      O'CLOCK

Input: 12:00
Output: (O'CLOCK and a lot of empty lines)
IT IS






TWELVE O'CLOCK
Olivier Grégoire
fuente
8
Gran desafío, me gusta mucho!
Timtech

Respuestas:

14

PHP, 387 384 353 352 342 323 310 306 298 293 291 bytes

¡Gracias @Christoph por jugar al golf junto con sus excelentes hallazgos!
Al menos 45 bytes están en su cuenta; 16 o más inspirados por él.

¡Un equipo de Marvel!

IT IS <?foreach([HALF,TEN,QUARTER,TWENTY,FIVE,MINUTES,TO,PAST,TWO,THREE,ONE,FOUR,FIVE,SIX,SEVEN,EIGHT,NINE,TEN,ELEVEN,TWELVE,"O'CLOCK"]as$w)echo strstr([w,ghj,dhj,ej,fhj,fghj,cj,fghi,fhi,ei,dhi,ghi][$m=date(i)/5+.5].mklnopqrstuvm[date(h)-($m<7)],99+$i)?$w:$w^$w^"       ","
  "[$i++%3^$i<3];

recorre los datos y comprueba si el índice actual está en una cadena generada que contiene los índices de las palabras a iluminar (asignadas a letras); agrega salto de línea o espacio según el índice.

Puede generar avisos si no utiliza el valor predeterminado para error_reporting(22519).

Pruébelo en línea.

Descompostura

IT IS <?
foreach([HALF,TEN,QUARTER,TWENTY,FIVE,MINUTES,TO,PAST,  // loop through words
TWO,THREE,ONE,FOUR,FIVE,SIX,SEVEN,EIGHT,NINE,TEN,ELEVEN,TWELVE,"O'CLOCK"]as$w)
    echo strstr(                    // search word index in ...
        [w,ghj,dhj,ej,fhj,fghj,cj,fghi,fhi,ei,dhi,ghi][$m=date(i)/5+.5] // minutes & co
        .mklnopqrstuvm[date(h)-($m<7)]                          // hours (-1 if minutes<33)
    ,99+$i                          // (map 0..20 to c..w)
    )?$w:$w^$w^"       ",           // if found, print string, else print spaces
    "\n  "[$i++%3^$i<3];            // if $i in [3,5,8,...], print newline, else space

Golfs :

  • $x/5+.5|0es dos bytes más corto que round($x/5).
  • Dos llamadas de date(h)son un byte más corto que asignar el dateresultado a una variable.
  • Usando una sola tarea, se eliminó la variable en la que se almacenaron los índices de iluminación.
  • Una cadena para los índices de iluminación en lugar de una matriz guardada alrededor de 30 bytes .
  • $w<Aes tres bytes más corto que $w=="\n": ¡asegúrese de que no haya espacio después de un delimitador!
  • abs guardado 8 bytes en la palabra minutos.
  • Gracias @Christoph: al pasar de números a letras para el mapa, los separadores quedaron obsoletos y se permitió una cadena más en lugar de una matriz; guardado 23 + 8 bytes .
    El uso de guión bajo como el primer índice permitió incluirlo en las alternativas "es"; e hizo obsoleta la cotización de las horas.
  • Duplicar el 1valor en el mapa de horas hizo que el módulo quedara obsoleto y que con el golf adicional ahorrara 10 bytes. Inspirado por @Christoph.
  • Calcular los saltos de línea y los espacios en lugar de codificarlos recortó 19 bytes .
  • La lógica de bits en cadenas ahorra 7 bytes: str_pad("",strlen($w))-> $w^$w^" ". (Christoph)
  • Si strtrel segundo parámetro no es una cadena, se interpretará como un código ascii. ahorra 5 bytes.
Titus
fuente
¡Esto esta muy bien! Intenté esta implementación en Java cuando me aseguré de que la pregunta fuera solucionable, ¡pero terminó siendo tan complicada que me di por vencida y usé un enfoque más largo pero más directo! Así que felicidades por tener éxito donde fallé;)
Olivier Grégoire
1
Paliza del resto: $i++%3^($i<3)a $i++%3^$i<3. Estoy oficialmente completamente perdido ahora. Me tomaré un descanso hasta que alguien nos iguale. Fue realmente divertido. ¡Gracias Titus por tu trabajo en equipo!
Christoph
1
@ Christoph Eres ... EXCELENTE parece una palabra pequeña. \ o /
Titus el
18

TI-Basic, 335 334 bytes

Bastante perfecto, ya que las calculadoras TI-84 tienen pantallas de letras 8x16, y esto es 8x15. La fecha se toma como entrada para admitir cálculos anteriores a TI-84, que no tienen relojes internos. Sin argumentos, Inputobtiene entrada por defecto en Xy Y, similar a Prompt X,Y. Así que haga Xhoras (cualquier cosa >=0funcionará correctamente) y tenga Yminutos.

Input 
ClrHome
int(Y/5-5.6
Output(1,1,"IT IS
If Ans=~6
Output(8,8,"O'CLOCK
If 2=abs(3-abs(Ans
Output(3,1,"FIVE
If 4=abs(Ans
Output(1,12,"TEN
If 3=abs(Ans
Output(2,1,"QUARTER
If 2=abs(Ans
Output(2,8,"TWENTY
If sum(abs(Ans)={1,2,4,5
Output(3,5,"MINUTES
If not(Ans
Output(1,7,"HALF
If Ans<1 and Ans+6
Output(4,1,"PAST
If Ans>0
Output(3,14,"TO
12fPart(12(^~1)(X+(Y>32->A
If not(Ans
12->A
{21,6,10,25,30,41,45,51,61,66,70,81
.05Ans(A
Output(int(4+Ans),20fPart(Ans),sub("ONE   TWO   THREE FOUR  FIVE  SIX   SEVEN EIGHT NINE  TEN   ELEVENTWELVE",6A-5,6

Nota 1: para TI-84 + puede reemplazar Inputcon algo como getTime:Ans(1->X:getTime:Ans(2->Y. Además, int(Y/5-5.6es equivalente a round(Y/5,0)-6. Y no, en este caso int(no se podría intercambiar iPart(.

Nota 2: Esto imprime la entrada bien, pero por razones estéticas probablemente desee Pauseal final del programa evitar el Donemensaje al finalizar el programa.

Editar: el recuento de bytes se redujo porque está tokenizado (ver nota en la revisión anterior), también se corrigió un error gracias a @Neil. En tercer lugar, solucioné un error que encontré que habría costado 2 bytes, pero la optimización en realidad ahorró 1 byte en general, y también me di cuenta de que estoy recibiendo información para que no necesite llamar getTime(¿duh?) Por último, para cualquiera que quiera confirmar este recuento de bytes, el único token de dos bytes es sub(.

Timtech
fuente
Me parece que después de emitir O'CLOCKel código también se emitirá PAST...
Neil
2
Cuento 545 bytes, ¿podrías iluminarme?
Christoph
2
@Christoph encontró la meta publicación relacionada: meta.codegolf.stackexchange.com/a/4764/29637
Christoph
1
@ OlivierGrégoire En realidad, no está relacionado con esa línea anterior en absoluto. Lo que está haciendo es convertir el tiempo de 24 horas a 12 horas y también a la hora más cercana (por ejemplo, redondear con minutos contabilizados). Básicamente, en un lenguaje normal se vería algo así x+(y>32) mod 12si la comparación arroja 1 o 0 como en TI-Basic.
Timtech
1
Entonces @ Christoph parece que respondiste tu propia pregunta con ese enlace, ¿todavía quieres que te explique? Si desea ver dónde hice el cambio de puntuación ASCII a tokenizado, consulte la revisión # 4.
Timtech
11

JavaScript (ES6), 291 303 295 bytes

Toma la entrada como dos enteros con sintaxis curry (h)(m)

h=>m=>console.log(`IT IS HALF TEN
QUARTER TWENTY
FIVE MINUTES TO
PAST TWO THREE
ONE FOUR FIVE
SIX SEVEN EIGHT
NINE TEN ELEVEN
TWELVE O'CLOCK`.replace(/\S+/g,w=>(k/=2)&1?w:w.replace(/./g,' '),k=[x=1<<19,88,81,66,84,92,64.5,60,52,34,49,56,x,h=(m<33?h+11:h)%12][m/5+.4|0]*16|6|2048<<(h?h-(h<3):2)))

Cómo funciona

El reloj completo puede verse como 23 LED que están encendidos o apagados. Entonces, el estado del reloj es un entero de 23 bits.

Bit | Word        Bit | Word
----+--------     ----+--------
00  | IT          12  | ONE
01  | IS          13  | FOUR
02  | HALF        14  | FIVE
03  | TEN         15  | SIX
04  | QUARTER     16  | SEVEN
05  | TWENTY      17  | EIGHT
06  | FIVE        18  | NINE
07  | MINUTES     19  | TEN
08  | TO          20  | ELEVEN
09  | PAST        21  | TWELVE
10  | TWO         22  | O'CLOCK
11  | THREE             

La lógica de minutos que necesitamos implementar para habilitar las palabras correctas no es tan simple como podría pensarse a primera vista. Puede existir una fórmula de golf mágico, pero tomé el camino fácil y decidí codificar cada configuración posible:

Minutes | Words                    | Enabled bits | Value   | Value / 8
--------+--------------------------+--------------+---------+----------
  00    | O'CLOCK                  | 22           | 4194304 | 524288
  05    | FIVE MINUTES PAST        | 6, 7, 9      | 704     | 88
  10    | TEN MINUTES PAST         | 3, 7, 9      | 648     | 81
  15    | QUARTER PAST             | 4, 9         | 528     | 66
  20    | TWENTY MINUTES PAST      | 5, 7, 9      | 672     | 84
  25    | TWENTY FIVE MINUTES PAST | 5, 6, 7, 9   | 736     | 92
  30    | HALF PAST                | 2, 9         | 516     | 64.5
  35    | TWENTY FIVE MINUTES TO   | 5, 6, 7, 8   | 480     | 60
  40    | TWENTY MINUTES TO        | 5, 7, 8      | 416     | 52
  45    | QUARTER TO               | 4, 8         | 272     | 34
  50    | TEN MINUTES TO           | 3, 7, 8      | 392     | 49
  55    | FIVE MINUTES TO          | 6, 7, 8      | 448     | 56

Casos de prueba

Arnauld
fuente
2
Muy inteligente. Estaba tratando de cortar un byte más del mío, luego vi esto y no hay esperanza de competir.
edc65
La tarea (regla 8) dice que debe imprimirse, no solo devolverse
smls
@smls Oh, tienes razón. Eso está arreglado.
Arnauld
Muy genial. Excepto que la hora es incorrecta :-( Pantalla: h = 13 m = 15 Hora real: 14:43
Fresa
@ Fresa Por favor vea la regla # 6. Esta implementación utiliza datos de entrada exclusivamente, no la hora local.
Arnauld
6

Lote, 789 bytes

@echo off
if not "%1"=="" setlocal&set time=%1
set/a"h=%time:~0,2%,m=6%time:~3,2%%%60+2,h+=m/35,h%%=12,m=6-m/5%%12,n=m%%3,o=m%%2
set p=
set s=
call:c %m:-=% "IT IS HALF" 0 "IT IS      TEN" 4 "IT IS"
call:c %m:-=% QUARTER 3 "        TWENTY" 2 "        TWENTY" 1
if %m% lss 0 set s= TO
call:c 0 "            " %n% "     MINUTES" %o% "FIVE MINUTES"
set s=
set p=PAST 
if %m%==6 set p=     
if %m% lss 0 set p=     
call:c %h% TWO 2 "    THREE" 3
set p=
call:c %h% ONE 1 "    FOUR" 4 "          FIVE" 5
call:c %h% SIX 6 "    SEVEN" 7 "          EIGHT" 8
call:c %h% NINE 9 "     TEN" 10 "         ELEVEN" 11
if %m%==6 set s= O'CLOCK
call:c %h% TWELVE 0 "      "
exit/b
:c
set t=%1
:l
if %t%==%3 echo(%p%%~2%s%&exit/b
shift
shift
if not "%3"=="" goto l
echo(%p%%~2%s%

Nota: Espacio PASTfinal después y 5 espacios finales en cada una de las dos líneas siguientes.

Neil
fuente
¡Lo ejecuté y funciona bien (excluye un espacio faltante para la hora 3)! ¡Simplemente no entiendo lo que está pasando (con, call:cpor ejemplo)! Probablemente debería aprender algo :)
Olivier Grégoire
@ OlivierGrégoire Lamentablemente, un espacio había desaparecido, pero eso ya está solucionado.
Neil
4

JavaScript, 567 564 551 542 529 527 519 bytes

No sé si está bien tomar horas y minutos como argumentos. Dijiste "lista de enteros". ¿Todavía cuenta?

Es mi primera vez jugando al golf, por cierto. ¿Qué piensas?


Editar: guardado algunos bytes dividiendo minutos. Gracias Olivier!

Hristiyan Dodov
fuente
Sí, la idea detrás de esa regla es que puede tomar argumentos, pero solo si se relacionan con la entrada, que es el momento de imprimir.
Olivier Grégoire
1
Con respecto al golf, probablemente pueda jugar algunos bytes si considera dividir sus minutos entre 5. Además, es posible que desee moverse cdentro de su función. Supongo que no debería perder ningún byte al hacerlo, pero esto lo hace más como un fragmento que como una función (para mí, al menos, tal vez los gurús de JS dirán lo contrario).
Olivier Grégoire
4

JavaScript (ES6) 360

Una función con parámetros de entrada hora (0..23) y minuto (0..59).
Utilizando alertpara la salida, ya que es la función de salida estándar en JavaScript, incluso si es inconveniente. (Y es corto)

(k,n,m=(n+2)/5|0,h=(k+(m>6))%12,i=0)=>alert(`IT IS HALF TEN
QUARTER TWENTY
FIVE MINUTES TO
PAST TWO THREE
ONE FOUR FIVE
SIX SEVEN EIGHT
NINE TEN ELEVEN
TWELVE O'CLOCK`.replace(/\S+/g,w=>[,,m-6,m-2&&m-10,m-3&&m-9,m-4&&m-8&&m-5&&m-7,m-1&&m-11&&m-5&&m-7,!(m%3),m<7|m==12,!m|m>6,h-2,h-3,h-1,h-4,h-5,h-6,h-7,h-8,h-9,h-10,h-11,h%12,m%12][i++]?w.replace(/./g,' '):w))

Nota de prueba : para su tranquilidad, en el fragmento de prueba, la salida de alerta se redirige al texto de la página

F=
(k,n,m=(n+2)/5|0,h=(k+(m>6))%12,i=0)=>alert(`IT IS HALF TEN
QUARTER TWENTY
FIVE MINUTES TO
PAST TWO THREE
ONE FOUR FIVE
SIX SEVEN EIGHT
NINE TEN ELEVEN
TWELVE O'CLOCK`.replace(/\S+/g,w=>[,,m-6,m-2&&m-10,m-3&&m-9,m-4&&m-8&&m-5&&m-7,m-1&&m-11&&m-5&&m-7,!(m%3),m<7|m==12,!m|m>6,h-2,h-3,h-1,h-4,h-5,h-6,h-7,h-8,h-9,h-10,h-11,h%12,m%12][i++]?w.replace(/./g,' '):w))

function alert(x) { O.textContent=x }
function update() { F(+H.value,+M.value) }

update()
input { width:3em }
Hours<input id=H type=number min=0 max=23 value=17 oninput='update()'>
Minutes<input id=M type=number min=0 max=59 value=37 oninput='update()'>
<pre id=O></pre>

edc65
fuente
¡Me encanta tu respuesta! ¡Aprendí un montón de cosas de eso! Sin embargo, ¿qué está pasando con la función de flecha que tiene corchetes? Además, ¿cuál es el papel de i? Puedo ver que obtienes todos los grupos que no son espacios en blanco (los "LED") y los reemplazas con espacios en blanco según las condiciones que escribiste para cada uno de ellos. Por ejemplo, h-2es falso solo cuando h == 2, ¿así que supongo que lo inviertes en alguna parte? ¿Puedes explicar un poco cómo funciona esto? Tal vez como una edición de su respuesta? Estaría realmente agradecido!
Hristiyan Dodov
Actualización: casi me di cuenta de lo que estás haciendo. Tiene una matriz de elementos cero y no cero y los utiliza ipara referirse al correcto incrementándolo después de cada coincidencia de expresiones regulares. Si es verdad, reemplaza la cadena coincidente con espacios en blanco, de lo contrario la deja como está. Sin embargo, no entiendo una cosa. replace()utiliza el valor de retorno de la función especificada (función de flecha en este caso). ¿Dónde devuelves un valor? Acabo de ver un operador ternario.
Hristiyan Dodov
3
@HristiyanDodov una función de flecha hecha de solo una expresión simplemente devuelve el valor de esa expresión. El ejemplo (a,b)=>{ return a+b }es el mismo que(a,b)=>a+b
edc65
4

Python 2, 466 , 460 , 449 , 452 , 459 449 bytes

Como se permite que sea una función que acepte h y m como enteros, podemos guardar algunos bytes. Pruébalo en línea .

def t(h,m):


m=(2+m)//5
 h=h%12
 n=0
 if m>6:n,m=1,12-m;h+=1
 a="""IT IS _HALF _TEN_
 _QUARTER _TWENTY_
 _FIVE _MINUTES _TO_
 _PAST _TWO _THREE_
 _ONE _FOUR _FIVE_
 _SIX _SEVEN _EIGHT_
 _NINE _TEN _ELEVEN_
 _TWELVE _O'CLOCK""".split("_")
 b=[1,m==6,m==2,1,m==3,3<m<6,1,m in[1,5],m in[1,2,4],n*m,1,(1-n)*m,h==2,h==3,1,h==1,h==4,h==5,1,h==6,h==7,h==8,1,h==9,h==10,h==11,1,h==0,m==0]
 for i,c in enumerate(a):
  if b[i]:print c,
  else:print' '*len(c),

Tenía un par de errores (ahora fijo) con la lógica de TO/ PASTvs O'CLOCK. También guardé algunos bytes para enumerate, cambiando el import, y en 19<m<26lugar de m in [20,25]. Ahorró otros 8 para trabajar en fragmentos de 5 minutos en lugar de minutos. Rod señaló algunos errores más que me costaron bastante, pero me recuperé un poco con tareas más eficientes y una corrección de errores que funcionó a mi favor.

Chris H
fuente
Toma un truco de la respuesta PHP de @Titus. Estoy perdiendo a Python ==como comparación y creo que puedo mejorar algunas de las hpruebas
Chris H
puede simplemente print cen la última línea, cya posee a[i], debidoenumerate
Varilla
1
El formato de salida está roto, printagregue una nueva línea después de cada impresión, puede suprimirlo agregando un ,después c. También debe imprimir espacios en blanco cuando no se imprime una palabra, puede arreglar con otra en el último sielse:print' '*len(c),
Rod
1
El orden de los bytes es mejor si desciende.
Gurupad Mamadapur
@ Rod, gracias por los puntos de error, a pesar de que lo hace mucho más largo
Chris H
2

Perl 6 , 308 296 293 bytes

->\h,\m{my \n=round(m/5)%12;say "IT IS HALF TEN
QUARTER TWENTY
FIVE MINUTES TO
PAST TWO THREE
ONE FOUR FIVE
SIX SEVEN EIGHT
NINE TEN ELEVEN
TWELVE O'CLOCK".subst: /\S+/,{++$==1|2|(0,7,4,5,6,(6|7),3)[min n,12-n]|8*?(n%3)|(23,10,9)[(n+5)/6]|(13,11,12,|(14..*))[(h+m/33-1)%12]??$_!!" "x.comb},:g}

Pruébalo en línea!

Explicación

La estructura básica es la siguiente:

-> \h, \m {                             # A lambda taking two args (hour and minute).
    my \n = round(m / 5) % 12;          # Index from 0 to 11, representing the minutes.
    say "...".subst: /\S+/, {           # Print the template with each word replaced:
        ++$ == ...|...|...|...          # If counter equals one of expected indices,
            ?? $_                       # then replace the word with itself,
            !! " " x .comb              # else replace it with spaces.
    }, :g                               # (Use global matching.)
}

La expresión elidida ...|...|...|...anteriormente, es una unión de enteros que representan índices de palabras basados ​​en 1, y se compone de la siguiente manera:

  1|2                                   # IT IS
| (0,7,4,5,6,(6|7),3)[min n,12-n]       # FIVE / TEN / QUARTER / TWENTY / TWENTY FIVE / HALF
| 8*?(n%3)                              # MINUTES
| (23,10,9)[(n+5)/6]                    # O'CLOCK / PAST / TO
| (13,11,12,|(14..*))[(h+m/33-1)%12]    # ONE / TWO / THREE / FOUR / FIVE / SIX / SEVEN / ...
smls
fuente
2

Python3, (569 bytes)

Esta respuesta requiere tiempo en formato hh mm (enteros separados por espacios). Logré imprimir '\ n', inspirado en el método de Chris. ¡Gracias, Chris! Cualquier ayuda para reducir el código es apreciada.

H,M=input().split()
w="""HALF _TEN_
_QUARTER _TWENTY_
_FIVE _MINUTES _TO_
_PAST _TWO _THREE_
_ONE _FOUR _FIVE_
_SIX _SEVEN _EIGHT_
_NINE _TEN _ELEVEN_
_TWELVE _O'CLOCK""".split("_")
h,m=int(H),int(M)
if h>12:h-=12
m=(m//5+1)*5 if m%5>2.5 else m//5*5
if m>30:
    m=60-m
    h=(h+1)%12
X=[m==30,m==10,1,m==15,m in[20,25],1,m in[5,25],m not in[0,15,30],int(M)>30 and m!=0,1,m!=0 and int(M)<31,h==2,h==3,1,h==1,h==4,h==5,1,h==6,h==7,h==8,1,h==9,h==10,h==11,1,h in[0,12],m==0]
t="IT IS "
for i in range(0,28):
    if(X[i]):t+=w[i]
    else:t+=" "*len(w[i])
print(t.strip())

Pruébalo en línea

EffyCoder
fuente
¿Se puede combinar w en una sola cadena y luego usar .split(',')? Debería salvar algunos.
ElPedro
También tome su entrada como H,M=input()donde la entrada es H, M. Se permiten dos secuencias enteras bajo las reglas, no estoy seguro de si esto funciona según lo previsto en Python 3. Todavía soy un chico 2 :-)
ElPedro
Gracias @ElPedro. Ahorró 57 bytes. H,M=input()no funcionó como dudaste.
EffyCoder
1

Python 2 , 443 440 bytes

R=range
w="HALF TEN QUARTER TWENTY FIVE MINUTES TO PAST TWO THREE ONE FOUR FIVE SIX SEVEN EIGHT NINE TEN ELEVEN TWELVE O'CLOCK".split(' ')
h=[10,8,9]+R(11,20)
c=['IT','IS']+[' '*len(x)for x in w]
i,j=input()
i=(i,i+1)[j>30]%13-1
j=int(round(j/5.0)*5.0)%60
for z in[[20],[4,5,7],[1,5,7],[2,7],[3,5,7],[3,4,5,7],[0,7],R(3,7),[3,5,6],[2,6],[1,5,6],R(4,7)][j/5]:c[z]=w[z]
c[h[i]]=w[h[i]]
x=0
for y in[4]+R(6,22,3)+[23]:print' '.join(c[x:y]);x=y

Pruébalo en línea!

Probablemente aún podría beneficiarse de un poco más de golf. La entrada es una lista de enteros, por ejemplo, 7,23 = 7:23

ElPedro
fuente
1

SimpleTemplate , 737 708 bytes

Sí, la verbosidad y la falta de matemáticas "reales" perjudicaron gravemente al bytecount.

{@seth argv.0}{@php$DATA[m]=ceil($DATA[argv][1]/5)*5%60|0}{@ifm}{@ifm is30}{@setA"HALF"}{@/}{@if"@[15]0$@"is matchesm}{@setB"TEN"}{@/}{@if"@[14]5$@"is matchesm}{@setC"QUARTER"}{@/}{@if"@[24]0$@"is matchesm}{@setD"TWENTY"}{@/}{@if"@^[25]?5$@"is matchesm}{@setE"FIVE"}{@/}{@if"@^([235]?5|[1245]0)$@" is matchesm}{@setF"MINUTES"}{@/}{@ifm is greater30}{@setG"TO"}{@else}{@setH"PAST"}{@/}{@else}{@setU"O\'CLOCK"}{@/}{@setZ"","ONE","TWO","THREE","FOUR","FIVE","SIX","SEVEN","EIGHT","NINE","TEN","ELEVEN","TWELVE"}{@setY"J"}{@incbyh Y}{@php$DATA[$DATA[Y]]=$DATA[Z][$DATA[h]]}{@print"IT IS%-6s%s\n%8s%s\n%-5s%-7s %s\n%4s %3s %s\n%3s %4s %s\n%3s %5s %s\n%4s %3s %s\n%6s %s",A,B,C,D,E,F,G,H,J,K,I,L,M,N,O,P,Q,R,S,T,U}

Esto espera la hora y los minutos como el primer y segundo parámetro de la clase.


Sin golf:

{@set hour argv.0}

{@//The bitwise is required for the `@if minutes is 30`}
{@//Otherwise, I would be forced to write `@if minutes is equal to 30`}
{@php $DATA['minutes'] = ((ceil($DATA['argv'][1] / 5) * 5) % 60) | 0}

{@if minutes}
    {@if minutes is 30}
        {@set A "HALF"}
    {@/}
    {@if "@[15]0$@" is matches minutes}
        {@set B "TEN"}
    {@/}
    {@if "@[14]5$@" is matches minutes}
        {@set C "QUARTER"}
    {@/}
    {@if "@[24]0$@" is matches minutes}
        {@set D "TWENTY"}
    {@/}
    {@if "@^[25]?5$@" is matches minutes}
        {@set E "FIVE"}
    {@/}
    {@if "@^([235]?5|[1245]0)$@" is matches minutes}
        {@set F "MINUTES"}
    {@/}
    {@if m is greater than 30}
        {@set G "TO"}
    {@else}
        {@set H "PAST"}
    {@/}
{@else}
    {@set U "O\'CLOCK"}
{@/}


{@set numbers "", "ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN", "EIGHT", "NINE", "TEN", "ELEVEN", "TWELVE"}
{@set key "J"}
{@inc by hour key}
{@php $DATA[$DATA['key']] = $DATA['numbers'][$DATA['hour']]}

{@print "IT IS%-6s%s\n%8s%s\n%-5s%-7s %s\n%4s %3s %s\n%3s %4s %s\n%3s %5s %s\n%4s %3s %s\n%6s %s", A, B, C, D, E, F, G, H, J, K, I, L, M, N, O, P, Q, R, S, T, U}

Como correr:

  1. Obtenga el código de https://github.com/ismael-miguel/SimpleTemplate
  2. Ejecute el siguiente código:

    <?php
        include 'SimpleTemplate.php';
    
        $template = new SimpleTemplate('<code>');
    
        $template->render($hour, $minutes);
    
        //system-time: $template->render(date('g'), date('i'));
    
  3. ¡Hecho!

Ismael Miguel
fuente
1

Java (OpenJDK 9) , 437 bytes

(h,m)->{h=(h+m/35+11)%12+1;Object[]s="HALF TEN QUARTER TWENTY FIVE MINUTES TO PAST TWO THREE ONE FOUR FIVE SIX SEVEN EIGHT NINE TEN ELEVEN TWELVE O'CLOCK".split(" ");for(int i=s.length,M[]={1<<20,176,162,132,168,184,129,120,104,68,98,112};i-->0;)s[i]=(7<i&i<20?h==i-(h>3?7:h>1?6:9):(M[(m+2)/5%12]&(1<<i))>0)?s[i]:"";System.out.printf("IT IS %4s %3s%n%7s %6s%n%4s %7s %2s%n%4s %3s %5s%n%3s %4s %4s%n%3s %5s %5s%n%4s %3s %6s%n%6s %7s",s);}

Pruébalo en línea!

Pensé que finalmente daría una oportunidad a mi desafío;)

Olivier Grégoire
fuente
1

Perl 5 , 487 449 bytes

($a,$_,$h)=localtime;s/[3-7]$/5/;s/[12]$/0/;$m=s/(.?)[89]$/($1+1)*10/er;$_="IT IS half ten
quarter tw
five minutes to
past 2two 3three
1one 4four 5five
6six 7seven 8eight
9nine 10ten 11eleven
12twelve oc";if($m>30){s/to/TO/;$h++;$m=60-$m}elsif($m){s/past/PAST/}$h=$h%12||12;$m!=30?$m%15?s/m\w+/uc$&/e:$m?s/q\w+/uc$&/e:s/oc/O'CLOCK/:s/half/HALF/;$m%10&&!/Q/&&s/five/FIVE/;$m>15&&$m<30?s/tw/TWENTY/:$m==10&&s/ten/TEN/;s/\b$h\w+/uc$&/es;y/a-z0-9/ /;say

Pruébalo en línea!

Xcali
fuente