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)

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 ';'.

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

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


é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:]


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.


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

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


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)

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


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!


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)

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)?';':"'":",";

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)

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.


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

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

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

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


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.


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

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



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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.