Imprimir um word clock

59

Desde que eu vi o primeiro, há alguns anos, eu sempre fui subjugado por esse tipo de relógio de palavras, onde o tempo é realmente determinado por palavras sendo iluminadas ou não em uma frase significativa.

Um relógio de palavras

O texto exibido nesse relógio é o seguinte.

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

Sua tarefa é escrever um relógio que funcione. As palavras são acesas se e somente se forem relevantes para a impressão da hora atual. Caso contrário, eles estão iluminados. As palavras são "iluminadas" ao serem impressas e "iluminadas" ao serem substituídas por vários espaços, sendo o comprimento da palavra.

Exemplo: se o horário atual for 17:23, o texto impresso deverá ser exatamente o seguinte:

IT IS 
        TWENTY
FIVE MINUTES
PAST
         FIVE

Regras

  1. A hora impressa é a variante de 12 horas, mas sem AM / PM.
  2. O arredondamento é feito apenas com base em minutos (os segundos são totalmente irrelevantes). O arredondamento é feito para o múltiplo mais próximo de 5. Portanto, por exemplo, embora 17:52:38 seja realmente o mais próximo de 17:55, mas como os segundos são irrelevantes, 17:52 é na verdade arredondado para 17:50, e o texto impresso é "SÃO DEZ MINUTOS A SEIS" (com espaçamento relevante). Portanto, se XXfor múltiplo de cinco, XXserá usado de HH: (XX-2): 00 até HH: (XX + 2): 59. A palavra MINUTESdeve aparecer se FIVE, TENou TWENTYestiver acesa na seção de minutos (antes de "TO" ou "PASSADO").
  3. Todas as palavras irrelevantes são substituídas por quantos espaços forem necessários para manter o texto onde ele está localizado no modelo acima. Os espaços à direita podem ser aparados. Os espaços relevantes para manter o texto na posição esperada devem ser mantidos.
  4. As linhas à direita também podem ser cortadas. Linhas vazias relevantes ainda precisam aparecer. Exemplo:

    IT IS      TEN
    
         MINUTES
    PAST TWO
    
  5. Não acenda TENna primeira linha ou FIVEna terceira linha quando esses valores se referirem às horas.

  6. Você pode aceitar uma entrada. Se você aceitar uma entrada, a entrada será a hora de imprimir em qualquer formato válido desejado (sequência, lista de números inteiros, horário nativo, digite o seu suporte ao idioma, ...), mas nenhum parâmetro será permitido se não estiver relacionado até a hora de imprimir. Se você não suportar nenhuma entrada, deverá usar a hora atual. Se você apoia os dois, é melhor, mas não há bônus;)
  7. Seu código pode ser um programa, uma função, um lambda, mas não um trecho.
  8. Se seu idioma suportar impressão de qualquer forma, ele deverá imprimir o resultado (em um arquivo, na saída padrão, não me importo). Se o seu idioma não suportar a impressão de forma alguma, é permitido simplesmente "retornar" o texto esperado. O resultado pode ser todo em maiúsculas ou minúsculas, não uma mistura de ambos.
  9. Aplicam-se brechas padrão.
  10. Isso é código-golfe, então o código mais curto vence!
  11. Na medida do possível, forneça um link para um intérprete on-line do seu idioma.

Casos de teste

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
fonte
8
Grande desafio, eu realmente gosto!
Timtech 18/01/19

Respostas:

14

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

Obrigado @Christoph por jogar golfe junto com suas excelentes descobertas!
Pelo menos 45 bytes estão em sua conta; 16 ou mais inspirado por ele.

Uma Marvel Team Up!

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

percorre os dados e verifica se o índice atual está em uma sequência gerada que contém os índices das palavras a serem acesas (mapeadas para letras); acrescenta quebra de linha ou espaço, dependendo do índice.

Pode gerar avisos se você não usar o valor padrão para error_reporting(22519).

Teste online.

demolir

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

Golfe :

  • $x/5+.5|0é dois bytes menor que round($x/5).
  • Duas chamadas de date(h)são um byte mais curto do que atribuir o dateresultado a uma variável.
  • O uso de uma única atribuição alterou a variável em que os índices de iluminação foram armazenados.
  • Uma sequência para os índices de iluminação em vez de uma matriz salva em torno de 30 bytes .
  • $w<Aé três bytes menor que $w=="\n"- verifique se não há espaço após um delimitador!
  • abs salvou 8 bytes na palavra minutos.
  • Obrigado @Christoph: A mudança de números para letras do mapa tornou os separadores obsoletos e permitiu mais uma sequência em vez de matriz; salvou 23 + 8 bytes .
    Usar o sublinhado como o primeiro índice permitiu incluí-lo nas alternativas "é"; e tornou obsoleta a cotação das horas.
  • Duplicar o 1valor no mapa de horas tornava o módulo obsoleto e, com o golfe adicional, economizava 10 bytes. Inspirado por @Christoph.
  • O cálculo das quebras de linha e espaços, em vez de codificá-las, reduziu 19 bytes .
  • A lógica de bits nas seqüências economiza 7 bytes: str_pad("",strlen($w))-> $w^$w^" ". (Christoph)
  • Se strtro segundo parâmetro não for uma string, ele será interpretado como um código ascii. salva 5 bytes.
Titus
fonte
Isso é muito legal! Tentei essa implementação em Java ao garantir que a questão fosse solucionável, mas acabou sendo tão complicada que desisti e usei uma abordagem mais longa, mas mais direta! Então, parabéns pelo sucesso em que eu falhei;):
Olivier Grégoire
1
Batida do resto: $i++%3^($i<3)para $i++%3^$i<3. Estou oficialmente completamente perdido agora. Farei uma pausa até que alguém combine conosco. Foi muito divertido. Obrigado Titus pelo seu trabalho em equipe!
Christoph
1
@Christoph Você é ... GRANDE parece pequena uma palavra. \ o /
Titus
18

TI-Básico, 335 334 bytes

Praticamente perfeito, já que os TI-84 calcs têm displays de letras 8x16, e isso é 8x15. A data é tomada como entrada para suportar cálculos anteriores à TI-84, que não possuem relógios internos. Sem argumentos, Inputobtém entrada por padrão em Xe Y, semelhante a Prompt X,Y. Portanto, faça Xhoras (tudo >=0funcionará corretamente) e terá 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 a TI-84 +, você pode substituir Inputpor algo como getTime:Ans(1->X:getTime:Ans(2->Y. Além disso, int(Y/5-5.6é equivalente a round(Y/5,0)-6. E não, neste caso int(não foi possível trocar iPart(.

Nota 2: Isso imprime a entrada muito bem, mas por razões estéticas você provavelmente deseja que, Pauseno final do programa, evite a Donemensagem ao finalizar o programa.

Edit: Contagem de bytes reduzida por token (veja a nota na revisão anterior); também é corrigido um erro graças ao @Neil. Terceiro, corrigi um bug que me custou 2 bytes, mas a otimização economizou 1 byte no geral, e também percebi que estou recebendo informações para não precisar ligar getTime(duh?). Por fim, para quem deseja confirmar essa contagem de bytes, o único token de dois bytes é sub(.

Timtech
fonte
Parece-me que, após a saída O'CLOCKdo código, a saída PASTtambém será ...
Neil
2
Conto 545 bytes, você poderia me esclarecer?
Christoph
2
@Christoph Encontrou a meta post relacionada: meta.codegolf.stackexchange.com/a/4764/29637
Christoph
1
@ OlivierGrégoire Na verdade, não está relacionado à linha anterior. O que está fazendo é converter o tempo de 24 horas para 12 horas e também para a hora mais próxima (por exemplo, arredondamento com minutos contabilizados). Basicamente, em um idioma normal, seria algo como x+(y>32) mod 12se a comparação produz 1 ou 0 como no TI-Basic.
Timtech 18/01/19
1
Então, @Christoph, parece que você respondeu sua própria pergunta com esse link, você ainda quer que eu explique? Se você quiser ver onde eu mudei da pontuação ASCII para a tokenizada, verifique a revisão nº 4.
Timtech
11

JavaScript (ES6), 291 303 295 bytes

Recebe entrada como dois números inteiros com sintaxe de currying (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)))

Como funciona

O relógio inteiro pode ser visto como 23 LEDs que estão LIGADOS ou DESLIGADOS. Portanto, o estado do relógio é um número inteiro 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             

A lógica dos minutos que precisamos implementar para permitir as palavras certas não é tão simples quanto se pensa à primeira vista. Pode existir uma fórmula de golfe mágico, mas eu fui do jeito mais fácil e decidi apenas codificar cada configuração possível:

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 teste

Arnauld
fonte
2
Muito esperto. Eu estava tentando cortar mais um byte do meu, então vi isso e não há esperança de competir.
Edc65
A tarefa (regra 8) diz que deve ser impresso, não apenas voltou
SMLS
@smls Oh, você está certo. Isso está consertado.
Arnauld
Muito legal. Exceto que o tempo está errado :-( Visor: h = 13 m = 15 Hora real: 14:43
Morango
@Trawberry Consulte a regra nº 6. Esta implementação está usando entrada exclusivamente, não a 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: Espaço à direita após PASTe 5 espaços à direita em cada uma das duas linhas a seguir.

Neil
fonte
Eu corri e ele funciona muito bem (barra um espaço faltando por uma hora 3)! Eu simplesmente não entendo o que está acontecendo ( call:cpor exemplo)! Eu provavelmente deveria aprender algumas lote :)
Olivier Grégoire
@ OlivierGrégoire Infelizmente, um espaço havia desaparecido, mas isso foi corrigido agora.
Neil
4

JavaScript, 567 564 551 542 529 527 519 bytes

Não sei se tudo bem levar horas e minutos como argumentos. Você disse "lista de números inteiros". Ainda conta?

É a minha primeira vez jogando golfe, a propósito. O que você acha?


Editar: salvou alguns bytes dividindo minutos. Obrigado, Olivier!

Hristiyan Dodov
fonte
Sim, a ideia por trás dessa regra é que você pode receber argumentos, mas apenas se eles estiverem relacionados à entrada, que é a hora de imprimir.
Olivier Grégoire
1
Em relação ao golfe, você provavelmente pode jogar alguns bytes se considerar dividir seus minutos por 5. Além disso, convém mudar csua função. Você não deve perder nenhum byte ao fazê-lo, eu acho, mas isso o torna mais um trecho de uma função (para mim, pelo menos, talvez os gurus do JS digam o contrário).
Olivier Grégoire
4

JavaScript (ES6) 360

Uma função com parâmetros de entrada hora (0..23) e minuto (0..59).
Usando alertpara saída, pois é a função de saída padrão em javascript, mesmo que seja inconveniente. (E é curto)

(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 do teste : para sua tranquilidade, no trecho de teste, a saída do alerta é redirecionada para o texto da 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
fonte
Eu amo sua resposta! Eu aprendi um monte de coisas com isso! No entanto, o que está acontecendo com a função de seta que possui colchetes? Além disso, qual é o papel i? Vejo que você obtém todos os grupos que não são de espaço em branco (os "LEDs") e os substitui por um espaço em branco com base nas condições que você escreveu para cada um deles. Por exemplo, h-2é falso apenas quando h == 2, então presumo que você o inverta em algum lugar? Você pode explicar um pouco como isso funciona? Talvez como uma edição da sua resposta? Eu ficaria muito grato!
Hristiyan Dodov
Atualização - eu quase percebi o que você está fazendo. Você tem uma matriz de elementos zero e diferentes de zero e usa ipara se referir à correta, incrementando-a após cada correspondência de expressão regular. Se for verdade, você substitui a sequência correspondente por espaços em branco, caso contrário, você a deixa como está. Eu não entendo uma coisa, no entanto. replace()usa o valor de retorno da função especificada (função de seta neste caso). Onde você retorna um valor? Acabei de ver um operador ternário.
Hristiyan Dodov
3
@HristiyanDodov uma função de seta feita apenas de uma expressão retorna o valor dessa expressão. Exemplo (a,b)=>{ return a+b }é o mesmo que(a,b)=>a+b
edc65
4

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

Como é permitido que seja uma função que aceita he em números inteiros, podemos economizar alguns bytes. Experimente online .

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

Eu tinha um par de erros (agora corrigido) com a lógica para TO/ PASTvs O'CLOCK. Também salvou alguns bytes para enumerate, alterando importe em 19<m<26vez de m in [20,25]. Economizou outros 8 por trabalhar em blocos de 5 minutos em minutos. Rod apontou mais alguns erros que me custaram um pouco, mas eu me recuperei um pouco com atribuições mais eficientes e uma correção de bug que funcionava a meu favor.

Chris H
fonte
É necessário um truque da resposta PHP do @Titus. Estou perdendo para o python ==como comparação e acho que posso melhorar alguns dos htestes
Chris H
você pode apenas print c na última linha, cjá detém a[i]devidoenumerate
Rod
1
O formato de saída está quebrado, printadicione uma nova linha após cada impressão, você pode suprimi-lo adicionando um ,depois c. Além disso, ele deve imprimir espaços em branco quando uma palavra não é impressa. Você pode corrigir com outra pessoa no último caso.else:print' '*len(c),
Rod
1
A ordem dos bytes é melhor se decrescente.
Gurupad Mamadapur
@ Rod, obrigado pelos pontos de erro, mesmo que demore muito mais
H 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}

Experimente online!

Explicação

A estrutura básica é a seguinte:

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

A expressão elidida como ...|...|...|...acima é um junção de números inteiros que representam índices de palavras com base em 1 e é composta da seguinte maneira:

  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
fonte
2

Python3, (569 bytes)

Esta resposta requer tempo no formato hh mm (números inteiros separados por espaço). Consegui imprimir '\ n', o que é inspirado no método de Chris.Obrigado, Chris! Qualquer ajuda para reduzir o código é 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())

Experimente Online

EffyCoder
fonte
Você pode combinar w em uma única string e depois usá-la .split(',')? Deve economizar alguns.
ElPedro
Também leve sua entrada como H,M=input()onde está H, M. Dois sequência de inteiros é permitido sob as regras, não tenho certeza se isso funciona como pretendido em Python 3. Eu ainda sou um cara 2 :-)
ElPedro
Obrigado @ElPedro. Salvou 57 bytes. H,M=input()não funcionou como você duvidou.
precisa saber é o seguinte
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

Experimente online!

Provavelmente ainda poderia se beneficiar de mais golfe. Entrada é uma lista de números inteiros, por exemplo, 7,23 = 7:23

ElPedro
fonte
1

SimpleTemplate , 737 708 bytes

Sim, a verbosidade e a falta de matemática "real" prejudicam muito o número de bytes.

{@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}

Isso espera a hora e os minutos como o primeiro e o segundo parâmetros da classe.


Ungolfed:

{@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 executar:

  1. Obtenha o código de https://github.com/ismael-miguel/SimpleTemplate
  2. Execute o seguinte código:

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

Ismael Miguel
fonte
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);}

Experimente online!

Eu pensei que finalmente daria uma chance no meu desafio;)

Olivier Grégoire
fonte
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

Experimente online!

Xcali
fonte