codegolf.com: economizando tempo

11

Em codegolf.com (não foi carregado em 15 de setembro de 2011), havia um que estava me deixando louco. Imprima para STDOUT um relógio de uma forma exata, lendo o tempo de STDIN e marcando um hàs horas e mminutos (arredondado para um múltiplo de 5) e xse eles se sobrepõem, os tiques não utilizados são marcados com um o, para que

echo "23:13" | perl script.pl

rendimentos

        o
    h       o

 o             m

o               o

 o             o

    o       o
        o

O meu é:

$/=':';($h,$m)=<>;printf'%9s
%5s%8s

%2s%14s

%s%16s

%2s%14s

%5s%8s
%9s',map{qw'o h m x'[2*($_==int$m/5)^$_==$h%12]}map{$_,11-$_}0..5

para 136 caracteres, usando Perl. Eu gostaria de poder entrar no site, mas me lembro que os líderes tinham menos de 100 anos, também usando Perl. Alguém pode vencê-lo?

Joel Berger
fonte
Uma leitura fascinante :)
JB
@ Peter, é a mina de ouro! Obrigado por descobrir isso, gostaria de saber se o meu pode adaptar suas técnicas?
Joel Berger
1
Existe uma razão séria para usar algo em forma de limão, em vez de um círculo?
usuário desconhecido
1
@userunknown: A tarefa original foi provavelmente projetada usando uma fonte mais ampla.
hammar 31/01

Respostas:

3

Golfscript, 75 bytes

Inspirado no artigo vinculado nos comentários .

':'/{~}/5/:m;12%:h;"XXXXXXXXXXXX"{..318\%9/' '*@12%.h=2*\m=+'omhx'=@85/n*}%

A XXXXXXXXXXXXparte representa 12 bytes de dados, alguns deles não imprimíveis, e devem ser substituídos pela sequência de bytes 120 47 253 22 194 9 183 44 196 55 125 246.

Por conveniência, aqui está uma versão codificada em base64:

JzonL3t+fS81LzptOzEyJTpoOyJ4L/0Wwgm3LMQ3ffYiey4uMzE4XCU5LycgJypAMTIlLmg9Mipc
bT0rJ29taHgnPUA4NS9uKn0l

Exemplo de execução:

$ echo -n "JzonL3t+fS81LzptOzEyJTpoOyJ4L/0Wwgm3LMQ3ffYiey4uMzE4XCU5LycgJypAMTIlLmg9MipcbT0rJ29taHgnPUA4NS9uKn0l" | base64 -d > saving-time.gs
$ ls -l saving-time.gs 
-rw-r--r-- 1 ahammar ahammar 75 2012-01-29 17:31 saving-time.gs
$ ruby golfscript.rb saving-time.gs <<< "15:37"
        o
    o       o

 o             o

o               h

 o             o

    m       o
        o
hammar
fonte
2

C, 259 244 163 caracteres

O argumento da linha de comandos substituído por stdin (conforme necessário também acaba mais curto).
Removido o suporte por minutos acima de 59 - um desperdício de 3 caracteres.
O código é mostrado com quebras de linha e recuo, mas os caracteres foram contados sem eles.

main(i,h,m,x){
    scanf("%d:%d",&h,&m);
    for(i=0;i<12;
        printf("%*c","IEHBNAPBNEHI"[i++]-64,"ohmx"[(x==h%12)+2*(x==m/5)]))
        x=i%2?puts("\n"+(i%10==1)),11-i/2:i/2;
    puts("");
}

Tentativa mais antiga (usando códigos de escape ANSI), 244 caracteres:

f(x,y)char*y;{printf("\033[%d%c",x>0?x:-x,y[x<0]);}
main(i,h,m,x){
    char*v="HIJJJJIGFFFFPKJHFDCCDFHJ";
    f(i=f(scanf("%d:%d",&h,&m),"J")*0,v);
    for(;i<12;i++)
        (x=v[i+12]-72)&&f(x,"CD"),
        f(v[i]-72,"BA"),
        putchar("omhx"[2*(i==h%12)+(i==m%60/5)]);
    f(i,"B");
}
Ugoren
fonte
1

Python, 175 caracteres

h,m=map(int,raw_input().split(':'))
S=([' ']*17+['\n'])*11
for i in range(12):p=1j**(i/3.);S[98+int(8.5*p.imag)-18*int(5*p.real)]='ohmx'[2*(i==m/5)+(i==h%12)]
print''.join(S),

Não supera seu código Perl, mas talvez uma linguagem mais concisa com números complexos incorporados (ou funções trigonométricas) possa usar essa idéia para fazer melhor.

Keith Randall
fonte
1

Python, 226 caracteres

h,p,s=raw_input().split(':'),['o']*12,[0,11,1,10,2,9,3,8,4,7,5,6]
a,b=int(h[0])%12,int(h[1])/5
p[a],p[b]='h','m' if a!=b else 'x'
print '%9s\n%5s%8s\n\n %s%14s\n\n%s%16s\n\n %s%14s\n\n%5s%8s\n%9s'%tuple([p[i] for i in s])

Uso: execute 'python script.py' e digite o tempo necessário. (Ex: 09:45)

Resultado:

        o
    o       o

 o             o

x               o

 o             o

    o       o
        o
David Sousa
fonte
0

Minha solução perl:

use POSIX;$/=':';@ss=(8,4,1,0,1,4,8);@sn=(0,7,13,15,13,7,0);$h=<stdin>;
$m=<stdin>;if($h>12){$h=$h-12;}$m=floor($m/5);
for($c=0;$c<7;$c++){for($s=0;$s<$ss[$c];$s++){printf(" ");}
$ac='o';if($h>5&&$h-6==6-$c){$ac='h';}if((($m>5)&&$m-6==6-$c)||($m==$c)&&($c==0)){
if($h>5&&$h-6==6-$c){$ac='x';}else{$ac='m';}}
print($ac);for($s=0;$s<$sn[$c];$s++){printf(" ");}$bc='o';if($h<6&&$h==$c){$bc='h';}
if($m<6&&$m==$c){if($h<6&&$h==$c){$bc='x';}else{$bc='m';}}
if($sn[$c]){print($bc);}printf("\n");if($c&&($c!=5)){printf("\n");}}

527 bytes

Minha solução C:

main(){int x[]={8,4,1,0,1,4,8},y[]={0,7,13,15,13,7,0}
,h,m,z,c,s;scanf("%d:%d",&h,&m);h>12?h-=12:h;m/=5;
for(c=0;c<7;c++){for(s=0;s<x[c];s++){printf(" ");}z='o';
if(h>5&h-6==6-c){z='h';}if((m>5&m-6==6-c)|(m==c)&!c){
z='m';if(h>5&h-6==6-c){z='x';}}printf("%c",z);
for(s=0;s<y[c];s++){printf(" ");}z='o';if(h<6&h==c){
z='h';}if(m<6&m==c){z='m';if(h<6&h==c){z='x';}}
if(y[c]){printf("%c",z);}printf("\n");if(c&&(c!=5)){printf("\n");}}}

440 bytes

smeez e
fonte
1
uma sugestão rápida sobre o Perl: você não precisa posix, você pode ler de stdin com simplesmente <>e eu não acho que você precisa para printfa maneira que você estiver usando, printvai funcionar :)
Joel Berger
0

Scala 327 chars

object C extends App{
val R=List(2,4,6,8,10)
val r=1::R:::11::R.reverse
val C=List(3,6,12,18,21)
val c=1::C:::21::C.reverse
def p(n:Int,i:Char){
val z=r(n)
val s=c((n+3)%12)
printf("[%d;%dH"+i,z,s)}
val t=readLine.split(":")
val h=t(0).toInt%12
val m=t(1).toInt/5
(0 to 11).map(x=>p(x,'o'))
p(h,'h')
p(m,'m')
if(h==m)p(h,'x')}

em uso com um formato de círculo adequado, não com limão-XXXX:

clear  && echo 5:43 | scala C 
           o
     o           o

  o                 o

o                    o

  m                 o

     o           h
           o

ungolfed:

object Clock {
 val R = List (2,4,6,8,10)
 val r = 1 :: R ::: 11 :: R.reverse
 val C = List (3,6,12,18,21)
 val c = 1 :: C ::: 22 :: C.reverse

 def pos (n: Int, i: Char)={
   val z = r (n) 
   val s = c ((n+3) % 12) 
   printf ("[%d;%dH" + i, z, s)
 }

 def main (args: Array [String]) {
   val t = args (0).split (":")
   val h = t (0).toInt % 12
   val m = t (1).toInt /  5
   (0 to 11).map (x=> pos (x, 'o'))
   pos (h, 'h') 
   pos (m, 'm')
   if (h == m) pos (h, 'x')
  }
}

Usa o código ANSI para saída na pos (y, x). Como precisamos apenas da precisão de 5 minutos, os valores pré-calculados para x e y parecem ser mais curtos do que manipular as funções sin e cos com sua importação.

Usuário desconhecido
fonte
0

Python, 176 caracteres

o=map(ord,' .@Set~lWC2&!/0ABTUfgu')
h,m=map(int,raw_input().split(':'))
print''.join([' ',['\n','ohmx'[2*(i==o[m/5])+(i==o[h%12])]][i in o[:12]]][i in o]for i in range(24,127))
Arvind Singh
fonte
0

Perl 131 caracteres

<>=~/:/;$h=$`%12;$m=$'/5;printf'%9s
%12$5s%8s

%11$2s%14s

%10$s%16s

%9$2s%14s

%8$5s%8s
%9s',map$_^$h?$_^$m?o:'m':$h^$m?h:x,0..11
Toto
fonte