Afficher un décompte (dans différentes bases)


16

Le décompte est un système de comptage simple qui fonctionne en base 5. Il existe différents systèmes de décompte utilisés dans le monde, mais celui qui est utilisé dans la plupart des pays anglophones est peut-être le plus simple - compter les unités en marquant des lignes verticales, puis pour chaque 5ème marque met une ligne horizontale à travers la collection précédente de quatre. Cela regroupe les marques de pointage par groupes de 5 (et les rend plus faciles à compter rapidement).

Vous allez écrire un programme qui affiche les marques de pointage jusqu'à une valeur donnée. Mais compter sur seulement la base 5 est ennuyeux! Par conséquent, votre programme devrait également pouvoir afficher des décomptes dans différentes bases.

Contribution

L'entrée sera soit une ou deux valeurs entières non négatives séparées par une virgule (par exemple 9ou 8,4). Le premier nombre est la valeur qui devrait être affichée par le décompte. La deuxième valeur est la base du décompte. Si la deuxième valeur n'est pas donnée, utilisez la base 5 .

Production

La sortie sera la valeur entrée représentée sous forme de marques de pointage ASCII. Voici quelques exemples par rapport auxquels vous pouvez tester votre programme - votre sortie doit correspondre exactement à ceux-ci!

Entrée: 12ou12,5

 | | | |   | | | |   | |
-+-+-+-+- -+-+-+-+-  | |
 | | | |   | | | |   | |

Contribution: 7,3

 | |   | |   |
-+-+- -+-+-  |
 | |   | |   |

Contribution: 4,2

 |   |
-+- -+-
 |   |

Entrée: 6,1ou 6,10(remarquez les espaces de tête)

 | | | | | |
 | | | | | |
 | | | | | |

Notez également que la base 1 est censée être incohérente - seules les lignes verticales doivent être utilisées.

Si l'une des valeurs entrées est 0, il ne devrait y avoir aucune sortie (et votre programme devrait se terminer normalement).

Règles

  • Il s'agit de , donc la mise en œuvre correcte la plus courte (en octets) gagne.
  • L'entrée / sortie peut se faire sur tout support approprié (par exemple stdin / stdout, fichier ...).
  • L'entrée peut prendre la forme de plusieurs arguments de ligne de commande ou être séparée par des espaces, etc. si elle convient mieux à votre langue cible.
  • Les retours à la ligne de fin sont autorisés dans la sortie. Les espaces de fin ne le sont pas. Cette règle ne s'applique que lorsqu'il y a une sortie (c'est-à-dire pas lorsque la valeur entrée est 0).
  • Votre code doit être par défaut à la base 5 lorsqu'aucune base n'est entrée.

3
La sortie de ne devrait-elle pas 6,1ressembler davantage à cela -+- -+- -+- -+- -+- -+-?
Peter Taylor

3
Si vous indiquez "L'entrée sera soit une ou deux valeurs entières positives séparées par une virgule (par exemple 9 ou 8,4)." alors nous devrions pouvoir considérer cela comme une donnée, et ne pas avoir à nous soucier de "Votre programme devrait être robuste - vous devriez valider l'entrée ..." au-delà de la gestion d'un ou deux nombres.
AndoDaan

1
@PeterTaylor en -+-représenterait deux, car il y a une ligne verticale et un score horizontal à travers. La base 1 n'aurait que des lignes verticales. @AndoDaan modifié.
Sean Latham

D'accord --- --- --- --- --- ---. Par souci de cohérence avec les autres bases, vous devez placer une frappe horizontale à travers b-1les lignes verticales. S'il est censé être incohérent, vous devez l'indiquer explicitement.
Peter Taylor

Je l'ai fait. Désolé, je pensais que c'était implicite.
Sean Latham

Réponses:


4

CJam 103 85 72 caractères

Essayez-le sur http://cjam.aditsu.net/ .

original

q","/(i:A\_,{~i}{;5}?:B_@*{(_{" |"*S"l"++AB/*AB%}{;MA}?\:J" |l""-+ "er\" |"*N+_J\+@2$+@J\+++"l"Ser}{;}?

Fonctionne en définissant un ensemble de comptages avec des espaces, des lignes et un l pour les espaces qui doivent rester des espaces. Profite ensuite de la fonction er (tranliteration) pour faire la deuxième ligne. La partie la plus inefficace concerne les cas spéciaux 1 et 0. Éditera comme je l'améliore. Astuce J'ai pris trop de temps à réaliser: comme la deuxième entrée étant 1 est identique à l'infini ou la première entrée +1, le redéfinir quand il est égal à 1 économise beaucoup de travail.

le plus amélioré jusqu'à présent avec une virgule délimitée

l",":G/(i:A\_5a?~i:B_@*{(_" |":K*\{SG++AB/*AB%}{A}?\_KG+"-+ "er[\GSer_@@M]\K*N+*}{;}?

le plus amélioré jusqu'à présent avec une entrée délimitée par l'espace

Naturellement, CJam est vraiment conçu pour une entrée délimitée par l'espace. Placer l'entrée à 20 3 au lieu de 20,3 est un énorme avantage.

ri:Aq_5s?S-i(_)A)?:B*{B(" |":K*STs++ABmd@@*_K"-+"er[\_@@M]\K*N+*TsSer}M?

5

Python 2 - 111 108 119 144 140 140 136 135 134 - Essayez-le

Ok, essayons:

i=input()
n,b=[(i,5),i][i>[]]
o=b-1
a=[n,n%b][b>1]*' |'
m=(b>1)*n/b
s=(' |'*o+'  ')*m+a
print(s+'\n'+('-+'*o+'- ')*m+a+'\n'+s)*(b*n>0)

Edit: j'ai oublié qu'il ne devrait pas y avoir de sortie si n==0ou b==0. Cela me coûte 11 caractères. :(

Edit: Ok, après avoir corrigé le deuxième problème mentionné dans les commentaires, ma solution a essentiellement convergé vers celle de BeetDemGuise.


Cela imprime des retours à la ligne lorsque l'une des entrées (ou les deux) est nulle, ce qui, selon le défi, n'est pas souhaité. Et si un seul numéro est entré dans le programme?
BeetDemGuise

1
Cela échoue lorsque la deuxième valeur est omise ( bdevrait être 5 dans ce cas). Je vais être plus clair dans la question. Edit: oh, tant pis, vous l'avez corrigé comme je l'ai fait ce commentaire!
Sean Latham

De quel Python s'agit-il?
Beta Decay

C'est Python 2.7.8. - Oh, il y a eu une toute petite erreur à la toute fin ...
Falko

1
Si c'est Python 2.x, ne pourriez-vous pas enregistrer un caractère de plus en utilisant n/bau lieu de n//b?
Emil

5

Frapper, 239 228 199 189 188

Voici ma tentative, ça pourrait être beaucoup joué au golf.

Remarque: la deuxième ligne ne soustrait pas 5 de 2, elle définit une valeur par défaut si $2est vide!

n=$1
b=${2-5}
((n<1&b<1))&&exit
while ((n>b&b>1));do
n=$[n-b]
x+=\
y+=-
for i in `seq $[b-1]`;{
x+='| '
y+=+-
}
x+=\
y+=\
done
for j in `seq $n`;{
x+=' |'
y+=' |'
}
echo -e "$x\n$y\n$x"

Fonctionne {1..$n}au lieu de `seq $n`?
FUZxxl

@FUZxxl malheureusement pas, h=8;echo {1..$h}sorties{1..8}

Ce n'est pas bon.
FUZxxl

3

Python - 171 143

i=input();t,b=i if[0]<i else(i,5);b=[b,t+1][b==1];l,d,m,o=' |',t/b,t%b,b-1;r=(l*o+'  ')*d+l*m
if t*b>0:print r,'\n',('-+'*o+'- ')*d+l*m,'\n',r

Le programme est assez simple:

  • Obtenez l'entrée et essayez de décompresser t,b. Si cela échoue, attribuez simplement les valeurs correctes.
  • Si la base était 1, changez sa valeur en quelque chose qui peut gérer facilement toutes les lignes verticales ( t+1).
  • Définissez certaines variables et créez les sections inférieure et supérieure des comptages.
  • Imprimez les décomptes si les deux tet bsont différents de zéro.

EDIT 1: utilisez la inputfonction au lieu deraw_input jouer.

EDIT 2: Merci à Falko d'avoir signalé un petit bug avec ma vérification non nulle. Maintenant, notre code est fondamentalement identique, moins quelques noms de variables et une petite logique.

EDIT 3: Grâce à la façon dont Python compare les séquences et les différents types , nous pouvons comparer ià unlist pour obtenir une version plus courte de notretry...except bloc.

Voici la version non golfée:

i=input()

# If True, `i` must be a list
if [0]<i:
    t,b=i
# Otherwise, we know its a number (since `list` comes after `int` lexicographically.)
else:
    b=5
    t=i

b = b if b==1 else t+1
l=' |'
d=t/b
m=t%b
o=b-1

r=(l*o+'  ')*d+l*m
if t and b:
    print r,'\n',('-+'*o+'- ')*d+l*m,'\n',r

Je pense que t&bc'est Falsepour 10,5. Sinon, nos solutions convergent! ;)
Falko

@Falko Vous avez raison sur les deux plans! Vous savez ce qu'ils disent des grands esprits.
BeetDemGuise

Ce serait vraiment génial si nous pouvions trouver un moyen court de tester si iest scalaire ou une liste. Ensuite, nous pourrions laisser tomber le try ... exceptmonstre.
Falko

@Falko Je pense avoir trouvé un chèque d'un octet de mieux. A listest toujours supérieur à un int. De plus, les lists sont comparés dans l'ordre lexicographique. Donc, si nous comparons, [0]<icela retournera toujours Falsesi iest un nombre et Truesi iest une liste (avec un premier élément non nul).
BeetDemGuise

1
Génial! J'ai encore raccourci votre approche. Beau travail d'équipe! :)
Falko

3

Java, 343

class C{public static void main(String[]a){long n=new Long(a[0])+1,b=a.length>1?new Long(a[1]):5;if(b>0){if(b<2)b=(int)2e9;int i;for(i=1;i<n;i++)p(i%b>0?" |":"  ");p("\n");for(i=1;i<n-n%b;i++)p(i%b>0?"-+":"- ");if(n>b)p("- ");for(i=1;i<n%b;i++)p(" |");p("\n");for(i=1;i<n;i++)p(i%b>0?" |":"  ");}}static void p(String s){System.out.print(s);}}

Moins golfé:

class C {
  public static void main(String[] a) {
    long n=new Long(a[0])+1, b=a.length>1 ? new Long(a[1]) : 5;
    if(b>0) {
      if(b<2) b=(int)2e9; // if the base is 1, pretend the base is 2 billion
      int i;
      for(i=1;i<n;i++) p(i%b>0 ? " |" : "  ");
      p("\n");
      for(i=1;i<n-n%b;i++) p(i%b>0 ? "-+" : "- ");
      if(n>b) p("- ");
      for(i=1;i<n%b;i++) p(" |");
      p("\n");
      for(i=1;i<n;i++) p(i%b>0 ? " |" : "  ");
    }
  }
  static void p(String s) {
    System.out.print(s);
  }
}

Vous pouvez en enregistrer quelques-uns en faisant iun longafin de ne pas avoir à le déclarer séparément. Un peu plus en faisant i++%b>0dans vos boucles au lieu de l'incrémenter séparément (et i++<n%bdans la troisième boucle). Un autre en utilisant b=b<2?(int)2e9:b.
Geobits

3

Perl - 167 165 156

my($n,$b)=($ARGV[0]=~/(\d+)(?:,(\d+))?/,5);print$b>1?map{join(" ",($_ x($b-1))x int($1/$b)," | "x($1%$b))."\n"}(" | ","-+-"," | "):join" ",("---")x$1if$1*$b

non golfé

my($n,$b) = ($ARGV[0] =~ /(\d+)(?:,(\d+))?/, 5);
print($b>1 ?
    map{ 
        join(" ",($_ x ($b-1)) x int($1/$b)," | " x ($1%$b))."\n"
    } (" | ","-+-"," | ") :
    join " ", ("---") x $1
) if $1 * $b

affiche des lignes horizontales au lieu de verticales pour la base 1 :(
chinese perl goth

@chineseperlgoth oui, c'est l'une des exigences. Veuillez lire les commentaires sur Q.
Fozi

3

C - 193

Je suis vraiment désolé. Traiter le cas spécial pour 1 était un peu un mauvais hack donc je suppose que cela pourrait être joué plus avec une meilleure approche. En outre, ce code inclut une nouvelle ligne au début de la sortie, donc si cela n'est pas autorisé, faites-le moi savoir.

Bien sûr, des définitions très laides aident toujours :)

Le nombre de caractères comprend uniquement les espaces nécessaires et les nouvelles lignes.

#define P printf(
#define L P" |")
#define A P"\n");for(i=0;i<a;)b==1?i++,L:i++&&i%b==0?P
i;
main(a,b)
{
    scanf("%d,%d",&a,&b)<2?b=5:!b?a=0:a;
    if(a){
    A"  "):L;
    A"- "):a%b&&i>a/b*b?L:P"-+");
    A"  "):L;}
}

Votre code semble imprimer des retours à la ligne lorsque l'une des valeurs est zéro. Ceci est explicitement interdit. Votre solution n'est pas conforme.
FUZxxl

@FUZxxl Vous avez raison, ça m'a manqué! Cette mauvaise solution rapide devra faire pour l'instant. J'espère avoir bientôt le temps de trouver un meilleur moyen.
Allbeert

Je suis sûr que vous pouvez enregistrer quelques caractères en remplaçant printfpar putset en remplaçant returnpar un opérateur ternaire.
millinon

@millinon Le problème putsest qu'il ajoute une nouvelle ligne à chaque fois :(. Et pour l'opérateur ternaire, il n'est pas possible d'ajouter des returns ou des fors dedans!. Votre commentaire m'a donné l'idée de sauvegarder quelques caractères de plus très facilement en enlevant le returnbien. Merci!
Allbeert

2

C # 271 octets

Pas le plus court, je ne pouvais pas jouer au golf en raison de la nécessité d'accepter 0 comme entrée.

using C=System.Console;class P{static void Main(){var L=C.ReadLine().Split(',');int t=int.Parse(L[0]),f=L.Length>1?int.Parse(L[1]):5,r=3,i;for(var R="";t*f>0&r-->0;C.WriteLine(R.TrimEnd()))for(R="",i=0;i<t;R+=r==1&i++<t-t%f?(i%f<1?"- ":"-|"):i%f<1?"  ":" |")f+=f<2?t:0;}}

Code formaté:

using C=System.Console;

class P
{
    static void Main()
    {
        var L=C.ReadLine().Split(',');
        int t=int.Parse(L[0]),f=L.Length>1?int.Parse(L[1]):5,r=3,i;

        for(var R="";t*f>0&r-->0;C.WriteLine(R.TrimEnd()))
            for(R="",i=0;i<t;R+=r==1&i++<t-t%f?(i%f<1?"- ":"-|"):i%f<1?"  ":" |")
                f+=f<2?t:0;
    }
}

1

Lua - 219 203 octets

Je suis allé faire les copies d de b copies de "|", puis j'ai ajouté r copies de "|" à la fin. J'ai l'impression que j'aurais peut-être dû aller avec le 'tally up' les "|" à la chaîne un à la fois.

l=' |'s=string.rep _,_,a,b=io.read():find'(%d+)%D*(%d*)'b=tonumber(b)or 5 d=(a-a%b)/b f=b>1 and s(s(l,b-1)..'  ',d)g=b>1 and s(s('-+',b-1)..'- ',d)r=b>1 and a%b or a e=s(l,r)..'\n'print(f..e..g..e..f..e)

non golfé:

l=' |'          --the base string
s=string.rep    --string.rep will be used a lot, so best shorten it

_,_,a,b=io.read():find'(%d+)%D*(%d*)' --reads a,b I'm probably way of the mark with this one

b=tonumber(b)or 5

d=(a-a%b)/b -- shorter than math.floor(a/b), d equal the vertical mark

f=b>1 and s(s(l,b-1)..'  ',d) or '' --creates d multiples of b multiples of "|" more or less
g=b>1 and s(s('-+',b-1)..'- ',d)or''--same as above but with the middle "-+-"

r=b>1 and a%b or a --idk maybe i should set r before d(a- a%b )/b

e=s(l,r)..'\n'  -- makes the remainder string, notice that if b==1  then e will output all the "|" 

print(f..e..g..e..f..e) -- here's where the real magic happens!

Échantillon:

c:\Programming\AnarchyGolfMine>lua test.lua
13,5
 | | | |   | | | |   | | |
-+-+-+-+- -+-+-+-+-  | | |
 | | | |   | | | |   | | |


c:\Programming\AnarchyGolfMine>lua test.lua
6,2
 |   |   |
-+- -+- -+-
 |   |   |


c:\Programming\AnarchyGolfMine>lua test.lua
18,1
 | | | | | | | | | | | | | | | | | |
 | | | | | | | | | | | | | | | | | |
 | | | | | | | | | | | | | | | | | |

1
Pourriez-vous publier une version légèrement plus lisible et non golfée? Jouer au golf à Lua semble intéressant!

@Alessandro fait. Et merci, ça m'a fait trouver quelques choses qui m'ont manqué.
AndoDaan

1

JavaScript (193)

Cela pourrait être trop complexe.

s=prompt().split(",");a=+s[0];b=s[1];b=b?+b:5;o=b>1;v=" | ";q=w="";for(g=~~(a/b),c=o?a-g:a;g+1;g--,q+=" ",w+=" ")for(i=o;c&&i<b;i++)c--,q+=v,w+=g&&o?"-+-":v;if(a&&b)console.log(q+'\n'+w+'\n'+q)

Version commentée

s=prompt().split(",");
a=+s[0];
b=s[1];
b=b?+b:5;   // convert b to int and default to 5
o=b>1;      // special handling for b0 and b1
v=" | ";
q=w="";
// calculate number of lines and number of groups
for(g=~~(a/b),c=o?a-g:a;g+1;g--,q+=" ",w+=" ")
    for(i=o;c&&i<b;i++)
        c--,  // decrease line count
        q+=v,
        w+=g&&o?"-+-":v; // use " | " for last group and "-+-" for others
if(a&&b) // handle b0
    console.log(q+'\n'+w+'\n'+q)

1

Python - 127 123 122 122

Juste se faufiler avec une version python légèrement plus courte.

edit: Correction de 0 qui n'imprimait rien et qui rebondissait, finissait par la même longueur

k=input()
k=i,j=((k,5),k)[k>[]]
for m in[' |','-+',' |']*all(k):
 print(m*(j-1)+m[0]+' ')*(i/j*(j>1))+' |'*(i%(j+(j<2)*i))

0

C (207 caractères)

La nouvelle ligne juste avant exitest uniquement pour la lisibilité.

#define P printf(
#define t(v)for(a=c;b<=a;a-=b)a-c&&P" "),P v+1),q(b,v);q(a," |");P"\n");
q(n,c){while(n--)P c);}a;b;c;main(){scanf("%d,%d",&c,&b)<2?b=5:0;b&&c||
exit();b==1?b=32767:0;t("| ")t("+-")t("| ")}

scanfusage sans vergogne volé à Allbeert. Notez que cette solution ne se compile pas avec gcc car elle essaie d'imposer un prototype inexistant pour exit. Compilez avec un compilateur C fonctionnel comme tcc. En outre, cette fonction peut ou non fonctionner sur les plates-formes 64 bits. Utilisez avec précaution.

Voici l'implémentation non golfée d'origine sur laquelle elle est basée:

#include <stdio.h>
#include <stdlib.h>

static void
tally_line(int base, int count, const char *str)
{
     int follower = 0, i;

     /* full tallies first */
     for (; count >= base; count -= base) {
          if (follower++)
               putchar(' ');

          /* only print second character */
          printf(str + 1);

          for (i = 0; i < base; i++)
               printf(str);
     }

     /* partial tally */
     for (i = 0; i < count; i++)
          printf(" |");

     /* newline */
     puts("");
}

extern int
main(int argc, char **argv)
{
     int base, count;

     /* do away with program name */
     count = atoi(*++argv);

     base = argc - 3 ? 5 : atoi(*++argv);

     /* remove 0 later */
     base | count || exit(0);

     /* a crossed-out tally never appears for large numbers */
     if (base == 1)
          base = 32767;

     tally_line(base, count, "| ");
     tally_line(base, count, "+-");
     tally_line(base, count, "| ");

     return (EXIT_SUCCESS);
}

0

Python 2 , 134 126 123 123 114 octets

lambda i,j=5,a=" |":"\n".join(("",(a*~-j+"  ","-+"*~-j+"- ")[x%2]*(i/j))[j>1]+a*(i,i%j)[j>1]for x in(0,1,2)if i*j)

Essayez-le en ligne!

Vieille question que je connais mais amusante à essayer quand même. Chance d'essayer quelques trucs que j'ai appris depuis mon arrivée.

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.