Relógio ASCII com marcadores de ponto e vírgula

39

Introdução

explicação de código de golfe

Imagine que a linha de caracteres seja de fato duas linhas. A linha superior - pontos - representa horas (sistema 24 horas), enquanto as vírgulas inferiores representam minutos . Um personagem pode representar hora, minuto ou ambos - sempre que possível.

No começo, provavelmente você precisaria converter minutos desde a meia-noite para horas e minutos .

O resultado é a sequência que mostra a hora atual em "formato de ponto". A contagem de pontos ( apóstrofo conta aqui como um ponto e será chamado assim! ) É a contagem de horas desde a meia-noite e a contagem de vírgulas é a contagem de minutos. Vou mostrar alguns exemplos para deixar claro.

  • (Observação) hh: mm - result
  • (Apenas horas) 05:00 - '''''
  • (Apenas alguns minutos) 00:08 - ,,,,,,,,
  • (horas <minutos) 03:07 - ;;;,,,,
  • (horas> minutos) 08:02 - ;;''''''
  • (horas = minutos) 07:07 - ;;;;;;;
  • (o começo do dia) 00:00 - ( resultado vazio )

Observe que o caractere "ambos" pode ser usado no máximo 23 vezes - para 23: xx, em que xx é 23 ou mais.

Símbolos

Se o personagem precisar (consulte a regra 5.) escapar do seu idioma, você poderá alterá-lo para uma das alternativas. Se essas alternativas não forem suficientes, você pode usar outros símbolos - mas mantenha-o razoável. Só não quero que escapar seja uma barreira.

  • ;(ponto e vírgula) - marcador para ambas as horas e minutos (alt: :)
  • '(apóstrofo) - marcador para hora (ALT: '``°)
  • ,(vírgula) - marcador para minuto (ALT: .)

Regras adicionais

  1. O código com a menor quantidade de bytes vence!
  2. Você deve usar os dois símbolos sempre que possível. Para 02:04, o resultado não pode ser '',,,,, nem ;',,,. Tem que ser;;,,
  3. Entrada - pode ser parâmetro de script / aplicativo, entrada do usuário (como linha de leitura) ou variável dentro do código
    3.1. Se a variável dentro do código for usada, seu comprimento deverá ser o maior possível. É 1439(23:59), então parecet=1439
  4. A parte comum que é simbolizada pelo caractere "both" (12 em 12:05, 3 em 03:10) deve ser colocada no início da string
  5. Os símbolos podem ser substituídos por alternativas apenas se precisarem ser escapados em seu código.
  6. A entrada é fornecida em minutos após as 00:00 . Você pode assumir que este é um número inteiro não negativo.

Casos de teste

Input: 300
Output: '''''

Input: 8
Output: ,,,,,,,,

Input: 187
Output: ;;;,,,,

Input: 482
Output: ;;''''''

Input: 427
Output: ;;;;;;;

Input: 0
Output:  (empty)
Krzysiu
fonte
Obrigado, Adnan, por editar minha postagem! Desta forma, eu vou aprender através da comparação da minha, golfe novato para seu :)
Krzysiu
3
Sem problemas! É um muito bom primeiro post e um desafio agradável :)
Adnan
1
isso parece tão bom com apenas ponto e vírgula e vírgulas, mas os apóstrofos estragam tudo :(
Sparr
Na verdade 1439é 23:59e não 1339. (23 x 60 + 59).
insertusernamehere
Obrigado a todos por boas palavras! :) @Sparr, sim, esse é o ponto ruim :( Você já idéia de como ele poderia ser substituído insertusernamehere, é claro que é direito fixo :)?!
Krzysiu

Respostas:

10

Pitão, 19 bytes

:.iF*V.DQ60J"',"J\;

Suíte de teste

:.iF*V.DQ60J"',"J\;
      .DQ60            Divmod the input by 60, giving [hours, minutes].
           J"',"       Set J equal to the string "',".
    *V                 Perform vectorized multiplication, giving H "'" and M ','.
 .iF                   Interleave the two lists into a single string.
:               J\;    Perform a substitution, replacing J with ';'.
isaacg
fonte
8

CJam, 22 20 19 bytes

Toma entrada de STDIN:

ri60md]',`.*:.{;K+}

Teste aqui.

Explicação

ri     e# Read input and convert to integer.
60md   e# Divmod 60, pushes hours H and minutes M on the stack.
]      e# Wrap in an array.
',`    e# Push the string representation of the comma character which is "',".
.*     e# Repeat apostrophe H times and comma M times.
:.{    e# Apply this block between every pair of characters. This will only applied to
       e# first N characters where N = min(hours,minutes). The others will remain
       e# untouched. So we want the block to turn that pair into a semicolon...
  ;    e#   Discard the comma.
  K+   e#   Add 20 to the apostrophe to turn it into a semicolon.
}

Foi muita sorte o quão bem as coisas funcionaram juntas aqui, em particular a atribuição de horas 'e minutos para, que a ordem de horas e minutos na pilha correspondesse à representação em cadeia do personagem.

Este é o único bloco de 3 bytes que encontrei até agora. Havia toneladas de soluções de 4 caracteres:

{;;';}
{';\?}
{^'0+}
{^'F-}
{-'@+}
{-'6-}
...
Martin Ender
fonte
6

GNU Sed, 37

A pontuação inclui +1 para a -Eopção sed.

Eu não estava particularmente impressionado com a capacidade de resposta da minha resposta , então pensei em tentar com o sed por diversão.

A entrada é unária, conforme esta meta-resposta .

y/1/,/          # Convert unary 1's to commas (minutes)
s/,{60}/'/g     # divmod by 60.  "'" are hours
:               # unnamed label
s/(.*)',/;\1/   # replace an apostrophe and comma with a semicolon
t               # jump back to unnamed label until no more replacements

Experimente online

Trauma Digital
fonte
etiqueta sem nome ??
mikeserv
@mikeserv, consulte Trauma Digital 's ponta relacionada no Dicas para golfe em sed .
manatwork
@manatwork - acho que deve ser um bug do GNU.
mikeserv
@mikeserv - mas usar bugs também é bom, certo? Eu não estou pedindo para zombar de você, eu só não sei :)
Krzysiu
@Krzysiu - ok? Hmm. sobre este site que eu acho que seria uma marca de excelência. caso contrário, quase definitivamente não. quando os programadores se afastam da API e usam os detalhes de implementação, os programas se tornam dependentes da versão / implementação - o que é uma coisa ruim.
mikeserv
6

Python 2, 56 bytes

def g(t):d=t%60-t/60;print(t/60*";")[:t%60]+","*d+"'"*-d

Uma função que imprime (um caractere menor que t=input();).

O método é semelhante ao de Loovjo . O número de ,é diferente entre minutos e horas, com um mínimo implícito de 0. Pois ', é a negação. Para ;, calcula o minimplicitamente, levando quantas ;horas e, em seguida, truncando para o número de minutos.

Ele salva caracteres para salvar d, mas não o número de horas e minutos aqui. O análogo com lambda tinha dois caracteres a mais (58), portanto as atribuições variáveis ​​valem a pena.

lambda t:(t%60*";")[:t/60]+","*(t%60-t/60)+"'"*(t/60-t%60)

O processamento da entrada diretamente também não salvou caracteres (58):

h,m=divmod(input(),60);d=m-h;print(";"*m)[:h]+","*d+"'"*-d

Outra estratégia com fatiar, por muito mais tempo (64):

def g(t):m=t%60;h=t/60;return(";"*m)[:h]+(","*m)[h:]+("'"*h)[m:]
xnor
fonte
3

Pure Bash (sem utilitários externos), 103

p()(printf -vt %$2s;printf "${t// /$1}")
p \; $[h=$1/60,m=$1%60,m>h?c=m-h,h:m]
p , $c
p \' $[m<h?h-m:0]

Obrigado a F.Hauri por salvar 2 bytes.

Trauma Digital
fonte
Agradável! Mas você poderia economizar 2 caracteres trocando $1e $2em p()e escrever p , $cna linha 3.
F. Hauri
Sim, mas como ele é usado apenas em um printf "%s", tendo co trabalho vai esvaziar bem (embora não reutilizada)
F. Hauri
@ F.Hauri Agora entendi - obrigado!
Digital Trauma
3

C, 119 bytes

#define p(a,b) while(a--)putchar(b);
main(h,m,n){scanf("%d",&m);h=m/60;m%=60;n=h<m?h:m;h-=n;m-=n;p(n,59)p(h,39)p(m,44)}

Detalhado

// macro: print b, a times
#define p(a,b) while(a--)putchar(b)

int main(void)
{
    int h,m,n;
    scanf("%d",&m);  // read input

    h=m/60;m%=60;    // get hours:minutes
    n=h<m?h:m;       // get common count
    h-=n;m-=n;       // get remaining hours:minutes

    p(n,59);        // print common
    p(h,39);        // print remaining hours
    p(m,44);        // print remaining minutes

    return 0;
}
Khaled.K
fonte
1
Usando putchar& literais inteiro como personagens salva um byte, puxando as vírgulas dentro do macro economiza mais dois :)
Quentin
Nota do @Quentin tirada, salva 5 bytes
Khaled.K
Você pode perder o espaço anterior à sua whilena macro #define. -1 byte
Albert Renshaw
1
Você também pode salvar mais alguns bytes, tornando p (a, b) uma função em vez de uma macro. (E polvilhar um pouco mais ponto e vírgula à sua função principal)
Albert Renshaw
3

Haskell, 68 66 bytes

g(h,m)=id=<<zipWith replicate[min h m,h-m,m-h]";',"
g.(`divMod`60)

Exemplo de uso:

(g.(`divMod`60)) 482

A parte inteligente aqui é que replicate retornará a string vazia se o comprimento fornecido for negativo ou zero, para que eu possa aplicá-la às duas diferenças e apenas a positiva seja exibida. A primeira parte é fácil, já que o número de ponto e vírgula é apenas o mínimo dos dois. Em seguida, zipWithaplica a função aos itens correspondentes.

Edição: percebi que eu estava usando o char errado por minutos

EDIT 2: salvou 2 bytes graças a @Laikoni

user1472751
fonte
Você pode salvar dois bytes substituindo concat$por id=<<.
Laikoni 2/17/17
2

JavaScript (ES6) 69

m=>";".repeat((h=m/60|0)>(m%=60)?m:h)+",'"[h>m|0].repeat(h>m?h-m:m-h)
edc65
fonte
2

Powershell, 99 85 bytes

param($n)";"*(($m=$n%60),($h=$n/60))[($b=$m-gt$h)]+"'"*(($h-$m)*!$b)+","*(($m-$h)*$b)

Usando o método de Loovjo , esta é a minha implementação do PowerShell.

destroçado

param($n) 
# set the number of minutes and hours, and a boolean which one is bigger
# and also output the correct number of ;s
";"*(($m=$n%60),($h=$n/60))[($b=$m-gt$h)]+ 
# add the difference between h and m as 's but only if h > m
"'"*(($h-$m)*!$b)+
# add the difference between m and h as ,s but only if m > h
","*(($m-$h)*$b)

Economizou 14 bytes graças ao AdmBorkBork

Bjorn Molenmaker
fonte
Você pode salvar usando um pseudo-ternário para o primeiro, movendo as declarações $me $hpara ele e, em seguida, usando a multiplicação booleana. Como assim -param($n)';'*(($m=$n%60),($h=$n/60))[($b=$m-gt$h)]+'°'*(($h-$m)*!$b)+','*(($m-$h)*$b)
AdmBorkBork
1

Python 3, 98 bytes

d=int(input());m=d%60;h=int((d-m)/60)
if m>=h:print(";"*h+","*(m-h))
else:print(";"*(m)+"'"*(h-m))

Provavelmente não é a melhor resposta, mas foi muito divertido!

Adnan
fonte
1

Python 2, 61 bytes

t=input();m,h=t%60,t/60
print";"*min(h,m)+","*(m-h)+"'"*(h-m)

Explicação:

t=input();              # Read input
          m,  t%60,     # Do a divmod, h = div, m = mod
            h=     t/60

print";"*min(h,m)+                    # Print the minimum of the h and m, but in ";"s
                  ","*(m-h)+          # Print (m-h) ","s (if m-h is negative, print nothing)
                            "'"*(h-m) # Print (h-m) "'"s (if h-m is negative, print nothing)
Loovjo
fonte
1

PHP, 81 bytes

Eu fui para a entrada variável, pois é mais curta do que ler STDINou aceitar argumentos de linha de comando.

for($_=1439;$i<max($h=0|$_/60,$m=$_%60);++$i)echo$i<$h?$i<min($h,$m)?';':"'":",";
insertusernamehere
fonte
Eu pensei que conhecia PHP muito bem, mas eu vejo | pela primeira vez. Eu acho que vou usá-lo para exercer um pouco - eu vou analisá-lo :)
Krzysiu
Falha em 240. Experimente $i>=min($h,$m)?$h<$m?",":"'":";"(+1 byte). Ou use for($_=1439;$i<max($h=0|$_/60,$m=$_%60);)echo"',;"[$i++<min($h,$m)?2:$h<$m];(76 bytes). Entre: aspas simples torna -rimpossível; portanto, você deve usar o backtick por horas, se estiver em uma string ou °autônomo (não precisa de aspas -> -1 byte).
Titus
1

JavaScript (ES6), 77 71 bytes

x=>';'[r='repeat'](y=Math.min(h=x/60|0,m=x%60))+"'"[r](h-y)+','[r](m-y)
Mwr247
fonte
Grande uso de atribuições em argumentos de acesso / função de atributo. +1
Cyoce 2/17/17
1

Perl 6, 103 101 98 97 69 bytes

$_=get;say ";"x min($!=($_-$_%60)/60,$_=$_%60)~"'"x $!-$_~","x $_-$!;

Produz várias matrizes, mas foda-se, aproveite. Como sempre, qualquer oportunidade de golfe é appericada.

Edit: -2 bytes: ficou corajoso e removeu alguns lançamentos.

Edit2: -3 bytes removendo as matrizes.

Edit3: -1 byte para imprimir no formato correto, usando "lambdas" e removendo parênteses.

Edit4: (desculpe pessoal) abusando dessa hora - minutos devem retornar 0 e o oposto. Removido se instruções. Em seguida, removendo os suportes, percebendo que eu não precisava do lambda. -28 bytes :)

Woah, estou melhorando nisso.

Håvard Nygård
fonte
0

C, 141 bytes

main(h,m){scanf("%d",&m);h=(m/60)%24;m%=60;while(h||m){if(h&&m){printf(";");h--;m--;}else if(h&&!m){printf("'");h--;}else{printf(",");m--;}}}
user2064000
fonte
Eu acho que você poderia salvar alguns bytes usando h>0||m>0. Então você precisa h--;m--;apenas uma vez em cada iteração e o {}for if/elsefica obsoleto.
insertusernamehere
Você também pode economizar alguns bytes em seu segundo condicional: em vez de else if(h&&!m)você pode apenas terelse if(h)
Hellion
E, finalmente, tente usar o operador ternário, ele evitará o uso de palavras "longas" como ife else.
insertusernamehere
Considere refatorar como uma função que recebe a entrada como um parâmetro int - que deve pelo menos salvar você scanf().
Digital Trauma
Eu não acho que %24é necessário - o máximo de entrada é 23:59.
Digital Trauma
0

Gema, 119 caracteres

<D>=@set{h;@div{$0;60}}@set{m;@mod{$0;60}}@repeat{@cmpn{$h;$m;$h;$h;$m};\;}@repeat{@sub{$h;$m};'}@repeat{@sub{$m;$h};,}

Exemplo de execução:

bash-4.3$ gema '<D>=@set{h;@div{$0;60}}@set{m;@mod{$0;60}}@repeat{@cmpn{$h;$m;$h;$h;$m};\;}@repeat{@sub{$h;$m};`}@repeat{@sub{$m;$h};,}' <<< '252'
;;;;,,,,,,,,
homem a trabalhar
fonte
0

Matlab: 89 bytes

i=input('');m=mod(i,60);h=(i-m)/60;[repmat(';',1,min(h,m)),repmat(39+5*(m>h),1,abs(h-m))]

Teste:

310
ans =
;;;;;,,,,,
brainkz
fonte
0

SmileBASIC, 59 bytes

INPUT M
H%=M/60M=M-H%*60?";"*MIN(H%,M);",'"[M<H%]*ABS(H%-M)

Explicado:

INPUT MINUTES 'input
HOURS=MINUTES DIV 60 'separate the hours and minutes
MINUTES=MINUTES MOD 60
PRINT ";"*MIN(HOURS,MINUTES); 'print ;s for all positions with both
PRINT ",'"[MINUTES<HOURS]*ABS(HOURS-MINUTES) 'print extra ' or ,

Parece muito terrível, desde a parte inferior ;não é ainda o mesmo que ,na fonte de SmileBASIC

12Me21
fonte
0

PHP, 81 bytes

mais algumas soluções:

echo($r=str_repeat)(";",min($h=$argn/60,$m=$argn%60)),$r(",`"[$h>$m],abs($h-$m));
// or
echo($p=str_pad)($p("",min($h=$argn/60,$m=$argn%60),";"),max($h,$m),",`"[$h>$m]);

Corra com echo <time> | php -R '<code>'.

<?=($r=str_repeat)(";",min($h=($_=1439)/60,$m=$_%60)),$r(",`"[$h>$m],abs($h-$m));
// or
<?=($r=str_repeat)(";",min($h=.1/6*$_=1439,$m=$_%60)),$r(",`"[$h>$m],abs($h-$m));
// or
<?=str_pad(str_pad("",min($h=($_=1439)/60,$m=$_%60),";"),max($h,$m),",`"[$h>$m]);

Substitua 1439por entrada, salve no arquivo, execute.

Titus
fonte
0

Ruby, 50 caracteres

->t{(?;*h=t/60)[0,m=t%60]+",',"[0<=>m-=h]*m.abs}

Graças a:

  • GB para
    • lembrando-me de que não posso pegar mais caracteres de uma string do que ela tem (-1 caractere)
    • reorganizando meu cálculo (caractere -1)

Esperou tanto tempo para usar Numeric.divmod , apenas para perceber que é horrivelmente longo.

Exemplo de execução:

2.1.5 :001 > puts ->t{(?;*h=t/60)[0,m=t%60]+",',"[0<=>m-=h]*m.abs}[252]
;;;;,,,,,,,,
homem a trabalhar
fonte
1
Salve 1 caractere truncando a string em vez de usar min:(?;*h=t/60)[0,m=t%60]
GB
1
E outro byte subtraindo h de m:",',"[0<=>m-=h]*m.abs
GB
0

05AB1E , 25 bytes

60‰vy„'.Nè×}‚.BøJ„'.';:ðK

Experimente online!

60‰vy„'.Nè×}definitivamente pode ser encurtado, eu simplesmente não consegui descobrir e duvido que consiga economizar 7 bytes para vencer com essa abordagem, a menos que exista uma versão vetorial do ×.


Exemplo (com entrada igual a 63):

60‰                       # Divmod by 60.
                          # STACK: [[1,3]]
   vy      }              # For each element (probably don't need the loop)...
                          # STACK: []
     „'.Nè×               # Push n apostrophe's for hours, periods for minutes.
                          # STACK: ["'","..."]
            ‚             # Group a and b.
                          # STACK: [["'","..."]]
             .B           # Boxify.
                          # STACK: [["'  ","..."]]
               ø          # Zip it (Transpose).
                          # STACK: [["'."," ."," ."]
                J         # Join stack.
                          # STACK: ["'. . ."]
                 „'.';:   # Replace runs of "'." with ";".
                          # STACK: ["; . ."]
                       ðK # Remove all spaces.
                          # OUTPUT: ;..

D60÷''×s60%'.ׂ.BøJ„'.';:ðK foi a minha versão original, mas isso é ainda mais caro que o divmod.

60‰WDµ';ˆ¼}-¬0Qi'.ë''}ZׯìJ ainda outro método que eu tentei ...

Urna de polvo mágico
fonte
0

dc , 95 bytes

[60~sdsp39sj]sd[60~spsd44sj]se?ddd60~<d60~!<e[59Plp1-spld1-dsd0<y]syld0<y[ljPlp1-dsp0<y]sylp0<y

Experimente online!

R. Kap
fonte
0

Java 8, 101 99 86 bytes

n->{String r="";for(int m=n%60,h=n/60;h>0|m>0;r+=h--*m-->0?";":h<0?",":"'");return r;}

Explicação:

Experimente aqui.

n->{                      // Method with integer parameter and String return-type
  String r="";            //  Result-String (starting empty)
  for(int m=n%60,h=n/60;  //   Get the minutes and hours from the input integer
      h>0|m>0;            //   Loop as long as either the hours or minutes is above 0
    r+=                   //   Append the result-String with:
       h--*m-->0?         //    If both hours and minutes are above 0
                          //    (and decrease both after this check):
        ";"               //     Use ";"
       :h<0?              //    Else-if only minutes is above 0 (hours is below 0)
        ","               //     Use ","
       :                  //    Else:
        "'"               //     Use "'"
  );                      //  End loop
  return r;               //  Return the result
}                         // End of method
Kevin Cruijssen
fonte