Mostrar una cuenta (en diferentes bases)

16

El recuento es un sistema de recuento simple que funciona en la base 5. Hay varios sistemas de recuento diferentes que se utilizan en todo el mundo, pero el que se usa en la mayoría de los países de habla inglesa es quizás el más simple: contar unidades marcando líneas verticales, luego para cada quinta marca pone una línea horizontal a través de la colección anterior de cuatro. Esto agrupa las marcas de conteo en grupos de 5 (y hace que sea más fácil contarlas rápidamente).

Vas a escribir un programa que muestre marcas de conteo hasta un valor dado. Pero, contar solo en la base 5 es aburrido. Por lo tanto, su programa también debería poder mostrar los recuentos en diferentes bases.

Entrada

La entrada será uno o dos valores enteros no negativos separados por una coma (por ejemplo, 9o 8,4). El primer número es el valor que debe mostrar la cuenta. El segundo valor es la base de la cuenta. Si no se da el segundo valor, use la base 5 .

Salida

La salida será el valor ingresado representado como marcas de conteo de arte ASCII. Aquí hay algunos ejemplos con los que puede probar su programa: ¡su salida debe coincidir exactamente con ellos!

Entrada: 12o12,5

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

Entrada: 7,3

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

Entrada: 4,2

 |   |
-+- -+-
 |   |

Entrada: 6,1o 6,10(observe los espacios iniciales)

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

Tenga en cuenta también que la base 1 está destinada a ser inconsistente, solo se deben usar líneas verticales.

Si alguno de los valores ingresados ​​es 0, no debería haber ningún tipo de salida (y su programa debería finalizar correctamente).

Reglas

  • Este es el , por lo que gana la implementación correcta más corta (en bytes).
  • La entrada / salida puede estar en cualquier medio adecuado (por ejemplo, stdin / stdout, archivo ...).
  • La entrada puede ser en forma de argumentos de línea de comandos múltiples o separados por espacios, etc. si es más adecuado para su idioma de destino.
  • Las nuevas líneas finales están permitidas en la salida. Los espacios finales no lo son. Esta regla solo se aplica cuando hay una salida (es decir, no cuando el valor ingresado es 0).
  • Su código debe ser predeterminado a la base 5 cuando no se ingresa ninguna base.
Sean Latham
fuente
3
¿No debería 6,1parecer más la salida de -+- -+- -+- -+- -+- -+-?
Peter Taylor
3
Si dice "La entrada será uno o dos valores enteros positivos separados por una coma (por ejemplo, 9 u 8,4)". entonces deberíamos poder tomar eso como un hecho, y no tener que preocuparnos por "Su programa debe ser robusto, debe validar la entrada ..." más allá de manejar uno o dos números.
AndoDaan
1
@PeterTaylor -+-representaría dos, porque hay una línea vertical y una puntuación horizontal a través de ella. La base 1 solo tendría líneas verticales. @AndoDaan enmendado.
Sean Latham
Ok --- --- --- --- --- ---entonces. Para mantener la coherencia con las otras bases, debe colocar un golpe horizontal a través de b-1líneas verticales. Si se pretende que sea inconsistente, debe indicarlo explícitamente.
Peter Taylor
Ya hice eso. Lo siento, pensé que estaba implícito.
Sean Latham

Respuestas:

4

CJam 103 85 72 caracteres

Pruébalo en 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}{;}?

Funciona definiendo un conjunto de recuentos con espacios, líneas y una l para espacios que deberían permanecer espacios. Luego aprovecha la función er (tranliteración) para hacer la segunda línea. La parte más ineficiente es tratar con los casos especiales 1 y 0. Se editará a medida que lo mejore. Consejo, me tomé demasiado tiempo para darme cuenta: como la segunda entrada es 1 es igual que infinito o la primera entrada +1, redefinirla cuando es igual a 1 ahorra mucho trabajo.

más mejorado hasta ahora con comas delimitadas

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

más mejorado hasta ahora con entrada delimitada por espacios

Naturalmente, como CJam está realmente diseñado para entradas delimitadas por espacios. Colocar la entrada en 20 3 en lugar de 20,3 es un gran beneficio.

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

Python 2 - 111 108 119 144 140 136 135 134 - Pruébalo

Ok, vamos a intentarlo:

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)

Editar: he pasado por alto que no debería haber salida si n==0o b==0. Esto me cuesta 11 caracteres. :(

Editar: Ok, después de solucionar el segundo problema mencionado en los comentarios, mi solución básicamente convergió con la de BeetDemGuise.

Falko
fuente
Esto imprime nuevas líneas cuando cualquiera de las entradas (o ambas) son cero, lo que según el desafío no es deseado. Además, ¿qué pasa si solo se ingresa un número en el programa?
BeetDemGuise
1
Esto falla cuando se omite el segundo valor ( bdebería ser 5 en este caso). Lo dejaré más claro en la pregunta. Editar: ¡oh, no importa, lo arreglaste justo cuando hice este comentario!
Sean Latham el
¿Qué Python es este?
Beta Decay
Es Python 2.7.8. - Oh, hubo un pequeño error al final ...
Falko
1
Si es Python 2.x, ¿no podrías guardar un personaje más usando en n/blugar de n//b?
Emil
5

Golpetazo, 239 228 199 189 188

Aquí está mi intento, se podría jugar mucho al golf.

Nota: la segunda línea no resta 5 de 2, ¡establece un valor predeterminado si $2está vacío!

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"

fuente
¿ {1..$n}Funciona en lugar de `seq $n`?
FUZxxl
@FUZxxl desafortunadamente no, h=8;echo {1..$h}salidas{1..8}
Eso no es bueno.
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

El programa es bastante sencillo:

  • Obtenga la entrada e intente desempaquetar t,b. Si eso falla, simplemente asigne los valores correctos.
  • Si la base era 1, cambie su valor a algo que pueda manejar todas las líneas verticales fácilmente ( t+1).
  • Establezca algunas variables y cree las secciones inferior y superior de los recuentos.
  • Imprima los recuentos si ambos ty bno son cero.

EDITAR 1: use la inputfunción en lugar de raw_inputdespués de jugar un poco.

EDIT 2: Gracias a Falko por señalar un pequeño error con mi comprobación distinta de cero. Ahora nuestro código es básicamente idéntico, menos algunos nombres de variables y alguna pequeña lógica.

EDITAR 3: Gracias a cómo Python compara secuencias y diferentes tipos , podemos comparar icon a listpara obtener una versión más corta de nuestro try...exceptbloque.

Aquí está la versión sin golf:

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
BeetDemGuise
fuente
Creo que t&bes Falsepor 10,5. De lo contrario, nuestras soluciones son convergentes. ;)
Falko
@Falko ¡Tienes razón en ambos aspectos! Ya sabes lo que dicen sobre las grandes mentes.
BeetDemGuise
Sería realmente genial si pudiéramos encontrar una forma corta de probar si ies escalar o una lista. Entonces podríamos dejar caer al try ... exceptmonstruo.
Falko
@Falko Creo que encontré un cheque de 1byte mejor. A listes siempre mayor que un int. Además, los lists se comparan en orden lexicográfico. Entonces, si comparamos [0]<iesto, siempre devolverá Falseif ies un número y Trueif ies una lista (con un primer elemento distinto de cero).
BeetDemGuise
1
¡Excelente! Acorté aún más tu enfoque. Buen trabajo en equipo! :)
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);}}

Menos golfizado:

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);
  }
}
Ypnypn
fuente
Puede ahorrar unos pocos haciendo iun longpara que no tenga que declararlo por separado. Unos cuantos más haciendo i++%b>0en sus bucles en lugar de incrementarlo por separado (y i++<n%ben el tercer bucle). Otro mediante el uso 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

sin 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
Fozi
fuente
muestra líneas horizontales en lugar de verticales para la base 1 :(
perl chino goth
@chineseperlgoth sí, ese es uno de los requisitos. Lea los comentarios sobre P.
Fozi
3

C - 193

Lo siento mucho. Tratar con el caso especial para 1 fue un poco malo, así que supongo que esto se podría jugar más con un mejor enfoque. Además, este código incluye una nueva línea al comienzo de la salida, por lo que si esto no está permitido, avíseme.

Por supuesto, las definiciones de aspecto muy feo siempre ayudan :)

El recuento de caracteres incluye solo espacios necesarios y nuevas líneas.

#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;}
}
Allbeert
fuente
Su código parece imprimir nuevas líneas cuando uno de los valores es cero. Esto está explícitamente rechazado. Su solución no es conforme.
FUZxxl
@FUZxxl Tienes razón, ¡me lo perdí! Esta mala solución rápida tendrá que hacer por ahora. Espero tener tiempo pronto para encontrar una mejor manera.
Allbeert
Estoy bastante seguro de que usted puede ahorrar unos cuantos caracteres mediante la sustitución printfcon puts, y su sustitución returncon un operador ternario.
millinon
@millinon El problema putses que agrega una nueva línea cada vez :(. ¡Y para el operador ternario, no es posible agregar returns o fors dentro de ellos! Su comentario me dio la idea de guardar algunos caracteres más fácilmente retirando el returnpesar de Gracias.!
Allbeert
2

C # 271bytes

No es el más corto, no pude jugar golf a la lectura de entrada debido a que necesitaba aceptar 0 como entrada.

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

Código formateado:

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;
    }
}
VisualMelon
fuente
1

Lua - 219 203 bytes

Fui a hacer copias d de copias b de "|", luego agregué copias r de "|" al final. Siento que tal vez debería haber ido con el "conteo" las "|" s a la cadena de una en una.

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)

sin 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!

Muestra:

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


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


c:\Programming\AnarchyGolfMine>lua test.lua
18,1
 | | | | | | | | | | | | | | | | | |
 | | | | | | | | | | | | | | | | | |
 | | | | | | | | | | | | | | | | | |
AndoDaan
fuente
1
¿Podrías publicar una versión un poco más legible y sin golf? ¡Jugar al golf en Lua parece interesante!
@Alessandro hecho. Y gracias, hizo encontrar un par de cosas que me perdí.
AndoDaan
1

JavaScript (193)

Esto puede ser demasiado complejo.

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)

Versión comentada

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)
Mika lammi
fuente
1

Python - 127 123 122

Solo a escondidas con una versión de Python un poco más corta.

editar: Se corrigió 0 sin imprimir nada y rejigger, terminó la misma longitud

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))
Bizangles
fuente
0

C (207 caracteres)

La nueva línea anterior exites solo para legibilidad.

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

scanfuso desvergonzado robado de Allbeert. Tenga en cuenta que esta solución no se compila con gcc ya que trata de aplicar un prototipo no existente para exit. Compila con un compilador de C como tcc. Además, esta función puede o no funcionar en plataformas de 64 bits. Usar con cuidado.

Aquí está la implementación original sin golf en la que se basa:

#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);
}
FUZxxl
fuente
0

Python 2 , 134 126 123 114 bytes

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)

Pruébalo en línea!

Antigua pregunta que conozco, pero es divertido intentarlo de todos modos. Posibilidad de probar algunos trucos que he aprendido desde que me uní.

ElPedro
fuente