Horloge ASCII avec marqueurs de temps point et virgule

39

introduction

code explication golf

Imaginez que la ligne de caractères soit en fait deux lignes. Ligne supérieure - points - représente les heures (système sur 24 heures), tandis que bas - virgules - représente les minutes . Un personnage peut représenter une heure, une minute ou les deux , dans la mesure du possible.

Au début, vous devriez probablement convertir les minutes depuis minuit en heures et minutes .

Le résultat est la chaîne indiquant l'heure actuelle au format "point". Le nombre de points (l' apostrophe compte ici comme un point et sera appelé ainsi! ) Est le nombre d'heures depuis minuit et le nombre de virgules est le nombre de minutes. Je vais montrer quelques exemples pour le rendre clair.

  • (Remarque) hh: mm - result
  • (Heures seulement) 05:00 - '''''
  • (Seulement minutes) 00:08 - ,,,,,,,,
  • (heures <minutes) 03:07 - ;;;,,,,
  • (heures> minutes) 08:02 - ;;''''''
  • (heures = minutes) 07:07 - ;;;;;;;
  • (début de la journée) 00:00 - ( résultat vide )

Notez que le caractère "les deux" peut être utilisé 23 fois maximum - pour 23: xx, où xx est égal à 23 ou plus.

Symboles

Si le caractère doit (voir règle 5) être échappé dans votre langue, vous pouvez le changer en alternative. Si ces alternatives ne suffisent pas, vous pouvez utiliser d'autres symboles, mais restez raisonnable. Je ne veux pas que fuir soit un obstacle.

  • ;(point - virgule) - marqueur pour les heures et minutes (alt: :)
  • '(apostrophe) - marqueur des heures (alt: '``°)
  • ,(virgule) - marqueur de minutes (alt: .)

Règles supplémentaires

  1. Le code avec le moins d'octets gagne!
  2. Vous devez utiliser les deux symboles chaque fois que cela est possible. Pour 02:04 le résultat ne peut pas être '',,,,, ni ;',,,. Ça doit être;;,,
  3. Entrée - peut être un paramètre script / application, une entrée utilisateur (comme readline) ou une variable dans le code
    3.1. Si la variable code interne est utilisée, sa longueur doit être la plus longue possible. C'est 1439(23:59), donc ça ressemblerait àt=1439
  4. La partie commune qui est symbolisée par le caractère "les deux" (12 en 12:05, 3 en 03:10) doit être placée au début de la chaîne
  5. Les symboles peuvent être remplacés par des alternatives uniquement s'ils doivent être insérés dans votre code.
  6. L'entrée est donnée en minutes après 00:00 . Vous pouvez supposer qu'il s'agit d'un entier non négatif.

Cas de test

Input: 300
Output: '''''

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

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

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

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

Input: 0
Output:  (empty)
Krzysiu
la source
Merci, Adnan pour l'édition de mon post! De cette façon, j'apprendrai en comparant mon golf débutant au vôtre :)
Krzysiu
3
Aucun problème! C'est un très bon premier article et un beau défi :)
Adnan
1
ça a l'air tellement bien avec juste des points-virgules et des virgules, mais les apostrophes foutent tout en l'air :(
Sparr
1439Est en fait 23:59et pas 1339. (23 x 60 + 59).
insertusernamehere
Merci à tous pour vos bons mots! :) @Sparr, oui, c'est le mauvais point :( Avez-vous une idée de la façon dont il pourrait être remplacé? Insertusernamehere, bien sûr que c'est vrai! Corrigé :)
Krzysiu

Réponses:

10

Pyth, 19 octets

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

Suite de tests

:.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
la source
8

CJam, 22 20 19 octets

Prend la contribution de STDIN:

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

Testez-le ici.

Explication

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

C’était vraiment chanceux de voir à quel point les choses s’allaient bien ici, en particulier l’affectation des heures 'et des minutes à un ordre ,tel que l’ordre des heures et des minutes de la pile correspond à la représentation sous forme de chaîne du personnage.

C'est le seul bloc de 3 octets que j'ai trouvé jusqu'à présent. Il y avait pourtant des tonnes de solutions à 4 caractères:

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

GNU Sed, 37

Le score inclut +1 pour l' -Eoption sed.

Je n’ai pas été particulièrement impressionné par la golfinesse de ma réponse , alors j’ai pensé que j’essaierais avec sed pour le plaisir.

L'entrée est unaire, selon cette méta-réponse .

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

Essayez-le en ligne

Trauma numérique
la source
étiquette sans nom ??
mikeserv
@manatwork - Je pense que ce doit être un bogue GNU.
mikeserv
@mikeserv - mais utiliser des bogues, c'est bien aussi, non? Je ne vous demande pas de vous moquer de vous, je ne sais tout simplement pas :)
Krzysiu
@ Krzysiu - ok? hmm. sur ce site, je pense que ce serait une marque d’excellence. sinon, presque certainement pas. Lorsque les programmeurs s'éloignent de l'API et utilisent les détails de l'implémentation, les programmes deviennent dépendants de la version / implémentation - ce qui est une mauvaise chose.
mikeserv
6

Python 2, 56 octets

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

Une fonction qui imprime (un caractère plus court que t=input();).

La méthode est similaire à celle de Loovjo . Le nombre de ,est différent entre les minutes et les heures, avec un minimum implicite de 0. En effet ', c'est la négation. For ;, calcule l' minimplicitement en prenant jusqu'à plusieurs ;heures, puis en le tronquant au nombre de minutes.

Il enregistre les caractères à sauvegarder d, mais pas le nombre d'heures et de minutes ici. L'analogue avec lambda avait deux caractères plus longs (58), donc les affectations variables en valent la peine.

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

Le traitement de l'entrée directement n'a pas non plus enregistré de caractères (58):

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

Une autre stratégie de découpage, beaucoup plus longue (64):

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

Pure Bash (aucun utilitaire externe), 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]

Merci à @ F.Hauri pour la sauvegarde de 2 octets.

Trauma numérique
la source
Agréable! Mais vous pouvez économiser 2 caractères en échangeant $1et $2en p()écrivant p , $cà la ligne 3.
F. Hauri
Oui, mais comme il n’est utilisé que dans printf "%s", avoir cvide fonctionnera bien (sans être réutilisé)
F. Hauri
@ F.Hauri Maintenant, je comprends - merci!
Digital Trauma
3

C, 119 octets

#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)}

Détaillé

// 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
la source
1
Utiliser putcharles littéraux & entiers comme des caractères permet d'économiser un octet. Le fait de tirer les points-virgules à l'intérieur de la macro en économise deux autres :)
Quentin
@Quentin note prise, sauvegardée 5 octets
Khaled.K
Vous pouvez perdre de l’espace avant votre whilemacro #define. -1 octet
Albert Renshaw
1
Vous pouvez également enregistrer des octets supplémentaires en faisant simplement de p (a, b) une fonction au lieu d’une macro. (Et saupoudrer encore quelques points-virgules à votre fonction principale)
Albert Renshaw Le
3

Haskell, 68 à 66 octets

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

Exemple d'utilisation:

(g.(`divMod`60)) 482

La partie intelligente ici est que replicatela chaîne vide sera retournée si la longueur donnée est négative ou égale à zéro afin que je puisse l'appliquer aux deux différences et que seule la chaîne positive apparaisse. La première partie est facile, car le nombre de points-virgules n'est que le minimum des deux. zipWithApplique ensuite la fonction aux éléments correspondants.

EDIT: réalisé que j'utilisais le mauvais personnage pendant quelques minutes

EDIT 2: 2 octets sauvés grâce à @Laikoni

utilisateur1472751
la source
Vous pouvez économiser deux octets en remplaçant concat$par id=<<.
Laikoni
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
la source
2

Powershell, 99 85 octets

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

En utilisant la méthode de Loovjo, voici ma mise en œuvre de powershell.

non-golfé

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)

14 octets sauvés grâce à AdmBorkBork

Bjorn Molenmaker
la source
Vous pouvez enregistrer en utilisant un pseudo-ternaire pour le premier, le déplacement de la $met $hdéclarations en elle, puis en utilisant la multiplication booléenne. Ainsi --param($n)';'*(($m=$n%60),($h=$n/60))[($b=$m-gt$h)]+'°'*(($h-$m)*!$b)+','*(($m-$h)*$b)
AdmBorkBork
1

Python 3, 98 octets

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

Probablement pas la meilleure réponse, mais c'était très amusant!

Adnan
la source
1

Python 2, 61 octets

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

Explication:

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
la source
1

PHP, 81 octets

J'ai opté pour la variable, car elle est plus courte que lire STDINou prendre des arguments en ligne de commande.

for($_=1439;$i<max($h=0|$_/60,$m=$_%60);++$i)echo$i<$h?$i<min($h,$m)?';':"'":",";
insertusernamehere
la source
Je pensais que je connaissais assez bien PHP, mais je vois | pour la première fois. Je pense que je vais l'utiliser pour faire un peu d'exercice - je vais l'analyser :)
Krzysiu
Échoue pour 240. Essayez $i>=min($h,$m)?$h<$m?",":"'":";"(+1 octet). Ou utilisez for($_=1439;$i<max($h=0|$_/60,$m=$_%60);)echo"',;"[$i++<min($h,$m)?2:$h<$m];(76 octets). Btw: la citation simple rend -rimpossible; vous devez donc utiliser backtick pendant des heures si vous êtes dans une chaîne ou °autonome (ne nécessite pas de guillemets -> -1 octet).
Titus
1

JavaScript (ES6), 77 71 octets

x=>';'[r='repeat'](y=Math.min(h=x/60|0,m=x%60))+"'"[r](h-y)+','[r](m-y)
Mwr247
la source
Grande utilisation des assignations dans les arguments d'attributs d'accès / fonction. +1
Cyoce
1

Perl 6, 103 101 98 97 69 octets

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

Sort plusieurs tableaux, mais putain, profitez-en. Comme d'habitude, toutes les opportunités de golf sont appréhendées.

Edit: -2 octets: j'ai eu le courage de supprimer quelques transformations.

Edit2: -3 octets en supprimant les tableaux.

Edit3: -1 octet pour imprimer au format correct, en utilisant "lambdas" et en supprimant les parenthèses.

Edit4: (désolé les gars) abusant de cela heures - minutes devraient retourner 0 et l'inverse. Supprimé si déclarations. Supprimez ensuite les crochets, puis réalisez que je n'ai pas du tout besoin du lambda. -28 octets :)

Woah je m'améliore à cela.

Håvard Nygård
la source
0

C, 141 octets

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--;}}}
utilisateur2064000
la source
Je pense que vous pourriez économiser quelques octets en utilisant h>0||m>0. Ensuite, vous n’avez besoin h--;m--;que d’une seule fois à chaque itération et le {}for if/elsedeviendrait obsolète.
insertusernamehere
Vous pouvez également économiser quelques octets sur votre deuxième condition: au lieu de cela, else if(h&&!m)vous pouvez simplement avoirelse if(h)
Hellion
Et enfin, essayez d’utiliser l’opérateur ternaire, cela vous évitera d’utiliser des mots "longs" tels que ifet else.
insertusernamehere
Considérez le refactoring comme une fonction qui prend l’entrée comme un paramètre int - qui devrait au moins vous sauver le fichier scanf().
Traumatismes numériques
Je ne pense pas que ce %24soit nécessaire - l'entrée maximale est de 23h59.
Traumatismes numériques
0

Gema, 119 caractères

<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};,}

Échantillon échantillon:

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'
;;;;,,,,,,,,
homme au travail
la source
0

Matlab: 89 octets

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

Tester:

310
ans =
;;;;;,,,,,
Brainkz
la source
0

SmileBASIC, 59 octets

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

A expliqué:

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 ,

Cela semble assez terrible, car la partie inférieure de ;n'est pas identique ,à celle de la police de SmileBASIC

12Me21
la source
0

PHP, 81 octets

quelques solutions supplémentaires:

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

Courez avec 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]);

Remplacer 1439par l'entrée, enregistrer dans un fichier, exécuter.

Titus
la source
0

Ruby, 50 caractères

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

Grâce à:

  • GB pour
    • me rappelant que je ne peux pas prendre plus de caractères d'une chaîne qu'elle n'en a (-1 caractère)
    • réorganisation de mon calcul (-1 caractère)

J'ai attendu si longtemps pour l'utiliser Numeric.divmod, juste pour me rendre compte que c'est horriblement long.

Échantillon échantillon:

2.1.5 :001 > puts ->t{(?;*h=t/60)[0,m=t%60]+",',"[0<=>m-=h]*m.abs}[252]
;;;;,,,,,,,,
homme au travail
la source
1
Sauvegardez 1 caractère en tronquant la chaîne au lieu d'utiliser min:(?;*h=t/60)[0,m=t%60]
GB
1
Et un autre octet en soustrayant h de m:",',"[0<=>m-=h]*m.abs
GB
0

05AB1E , 25 octets

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

Essayez-le en ligne!

60‰vy„'.Nè×}peut certainement être raccourci, je ne pouvais tout simplement pas comprendre, et je doute que je serai capable de gagner 7 octets pour gagner avec cette approche à moins d’une version vectorielle de ×.


Exemple (avec une entrée égale à 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 C'était ma version originale, mais c'est encore PLUS coûteux que divmod.

60‰WDµ';ˆ¼}-¬0Qi'.ë''}ZׯìJ encore une autre méthode que j'ai essayée ...

Urne Magique De Pieuvre
la source
0

Java 8, 101 99 86 octets

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

Explication:

Essayez ici.

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
la source