Exibir um registro (em várias bases)


16

Tallying é um sistema simples de contagem que funciona na base 5. Existem vários sistemas diferentes de cálculo usados ​​em todo o mundo, mas o que é usado na maioria dos países de língua inglesa é talvez o mais simples - contar unidades marcando linhas verticais e, em seguida, para cada quinta marca coloca uma linha horizontal na coleção anterior de quatro. Isso agrupa as marcas de contagem em grupos de 5 (e facilita a contagem rápida).

Você vai escrever um programa que exibe marcas de registro até um determinado valor. Mas calcular apenas na base 5 é chato! Portanto, seu programa também deve poder exibir registros em diferentes bases.

Entrada

A entrada será um ou dois valores inteiros não negativos separados por vírgula (por exemplo, 9ou 8,4). O primeiro número é o valor que deve ser exibido pelo registro. O segundo valor é a base da contagem. Se o segundo valor não for fornecido, use a base 5 .

Resultado

A saída será o valor inserido representado como marcas de registro de arte ASCII. Aqui estão alguns exemplos contra os quais você pode testar seu programa - sua saída deve corresponder exatamente a eles!

Entrada: 12ou12,5

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

Entrada: 7,3

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

Entrada: 4,2

 |   |
-+- -+-
 |   |

Entrada: 6,1ou 6,10(observe os espaços iniciais)

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

Observe também que a base 1 deve ser inconsistente - somente linhas verticais devem ser usadas.

Se um dos valores inseridos for 0, não haverá saída alguma (e seu programa deve terminar normalmente).

Regras

  • Isso é , portanto a implementação correta mais curta (em bytes) vence.
  • A entrada / saída pode estar em qualquer meio adequado (por exemplo, stdin / stdout, arquivo ...).
  • A entrada pode ser na forma de vários argumentos de linha de comando ou separados por espaços, etc., se for mais adequado para o idioma de destino.
  • Novas linhas à direita são permitidas na saída. Os espaços à direita não são. Esta regra se aplica somente quando há uma saída (ou seja, não quando o valor inserido é 0).
  • Seu código deve ter como padrão a base 5 quando nenhuma base for inserida.

3
A saída de não deveria 6,1parecer mais -+- -+- -+- -+- -+- -+-?
— Peter Taylor

3
Se você declarar "A entrada será um ou dois valores inteiros positivos separados por vírgula (por exemplo, 9 ou 8,4)." então, devemos considerar isso como um dado e não ter que nos preocupar com "Seu programa deve ser robusto - você deve validar a entrada ..." além de manipular um ou dois números.
— AndoDaan

11
@PeterTaylor -+-representaria dois, porque há uma linha vertical e uma pontuação horizontal através dela. A base 1 teria apenas linhas verticais. @AndoDaan ammended.
— Sean Latham

Ok --- --- --- --- --- ---então. Para obter consistência com as outras bases, você deve fazer um ataque horizontal através de b-1linhas verticais. Se pretende ser inconsistente, você deve declarar isso explicitamente.
— Peter Taylor

Eu já fiz isso. Desculpe, eu pensei que estava implícito.
— Sean Latham

Respostas:


4

CJam 103 85 72 caracteres

Experimente em 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}{;}?

Trabalha definindo um conjunto de tallys com espaços, linhas e l para espaços que devem permanecer espaços. Em seguida, aproveita a função er (tranliteração) para criar a segunda linha. A parte mais ineficiente é lidar com os 1 e 0 casos especiais. Editará à medida que eu a melhorar. Dica: Demorei muito para perceber: como a segunda entrada sendo 1 é igual ao infinito ou a primeira entrada +1, redefini-la quando for igual a 1 economiza muito trabalho.

melhorado até agora com delimitação por vírgula

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

melhorado até agora com entrada delimitada por espaço

Naturalmente, o CJam foi realmente projetado para entrada delimitada por espaço. Colocar a entrada em 20 3 em vez de 20,3 é um grande benefício.

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 136 135 134 - Experimente

Ok, vamos tentar:

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: Eu esqueci que não deve haver saída se n==0ou b==0. Isso me custa 11 caracteres. :(

Edit: Ok, depois de corrigir o segundo problema mencionado nos comentários, minha solução basicamente convergiu para a do BeetDemGuise.


Isso imprime novas linhas quando uma das entradas (ou ambas) é zero, o que de acordo com o desafio é indesejável. Além disso, e se apenas um número for inserido no programa?
— BeetDemGuise

11
Isso falha quando o segundo valor é omitido ( bnesse caso, deve ser 5). Vou deixar mais claro na pergunta. Edit: oh, não importa, você corrigiu isso assim como eu fiz esse comentário!
— Sean Latham

Qual Python é esse?
— Beta Decay

É o Python 2.7.8. - Ah, houve um pequeno erro no final ...
— Falko

11
Se for o Python 2.x, você não poderá salvar mais um caractere usando em n/bvez de n//b?
— Emil

5

Bater, 239 228 199 189 188

Aqui está a minha tentativa, poderia ser muito jogado.

Nota: a segunda linha não subtrai 5 de 2, define um valor padrão se $2estiver vazio!

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"

Funciona em {1..$n}vez de `seq $n`?
— FUZxxl

@FUZxxl infelizmente não, h=8;echo {1..$h}outputs{1..8}

Isso não é bom.
— 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

O programa é bem direto:

  • Obtenha a entrada e tente descompactar t,b. Se isso falhar, simplesmente atribua os valores corretos.
  • Se a base era 1, altere seu valor para algo que possa manipular todas as linhas verticais facilmente ( t+1).
  • Defina algumas variáveis ​​e crie as seções inferior e superior das notas.
  • Imprima os registros se ambos te bforem diferentes de zero.

EDIT 1: Use a inputfunção em vez de raw_inputdepois de algumas brincadeiras.

EDIT 2: Obrigado a Falko por apontar um pequeno bug com minha verificação diferente de zero. Agora nosso código é basicamente idêntico, menos alguns nomes de variáveis ​​e alguma lógica pequena.

EDIT 3: Graças a como o Python compara seqüências e tipos diferentes , podemos comparar icom a listpara obter uma versão mais curta do nosso try...exceptbloco.

Aqui está a versão não destruída:

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

Eu acho que t&bé Falsepor 10,5. Caso contrário, nossas soluções estão convergindo! ;)
— Falko

@ Falko Você está certo em ambos os aspectos! Você sabe o que eles dizem sobre grandes mentes.
— BeetDemGuise

Seria ótimo se pudéssemos encontrar uma maneira curta de testar se ié escalar ou uma lista. Então poderíamos largar o try ... exceptmonstro.
— Falko

@ Falko Acho que encontrei uma verificação de 1 byte melhor. A listé sempre maior que um int. Além disso, lists são comparados em ordem lexicográfica. Portanto, se compararmos, [0]<iisso sempre retornará Falsese ifor um número e Truese ifor uma lista (com um primeiro elemento diferente de zero).
— BeetDemGuise

11
Ótimo! Encurtei ainda mais sua abordagem. Bom trabalho em equipe! :)
— 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 golfe:

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

Você pode economizar alguns fazendo ium, longpara não precisar declará-lo separadamente. Um pouco mais, fazendo i++%b>0seus loops em vez de incrementá-lo separadamente (e i++<n%bno terceiro loop). Outro usando 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

destroçado

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

exibe linhas horizontais em vez dos verticais para a base 1 :(
— perl chinês gótico

@chineseperlgoth sim, esse é um dos requisitos. Por favor, leia os comentários sobre Q.
— Fozi

3

C - 193

Eu sinto muito. Lidar com o caso especial de 1 foi um truque ruim, então acho que isso poderia ser melhorado com uma abordagem melhor. Além disso, este código inclui uma nova linha no início da saída; portanto, se isso não for permitido, entre em contato.

Claro, define muito feio sempre ajuda :)

A contagem de caracteres inclui apenas os espaços necessários e novas linhas.

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

Seu código parece imprimir novas linhas quando um dos valores é zero. Isso é explicitamente proibido. Sua solução não está em conformidade.
— FUZxxl

@FUZxxl Você está certo, eu perdi isso! Essa má solução rápida terá que ser feita por enquanto. Espero ter tempo em breve para encontrar uma maneira melhor.
— Allbeert

Tenho certeza de que você pode salvar alguns caracteres substituindo printfpor putse substituindo returnpor um operador ternário.
— millinon

@millinon O problema putsé que ela adiciona uma nova linha sempre :(. E para o operador ternário, não é possível adicionar returns ou fors dentro deles! Seu comentário me deu a idéia de salvar mais alguns caracteres facilmente, removendo o returnque Obrigado.!
— Allbeert

2

C # 271bytes

Não é o mais curto, não consegui jogar a leitura de entrada devido à necessidade de aceitar 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 formatado:

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 bytes

Fui para fazer d cópias de b cópias de "|" e adicionar r cópias de "|" no fim. Eu sinto que talvez eu devesse ter subido a contagem dos "|" para a corda, uma de cada vez.

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)

ungolfed:

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!

Amostra:

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


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


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

11
Você poderia postar uma versão ligeiramente mais legível e não-destruída? Golfe em Lua parece interessante!

@Alessandro done. E obrigado, fez encontrar algumas coisas que eu perdi.
— precisa saber é o seguinte

1

JavaScript (193)

Isso pode ser excessivamente complexo.

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)

Versão 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)

1

Python - 127 123 122

Apenas entrando com uma versão python um pouco mais curta.

edit: Corrigido 0 não imprimindo nada e rejeitador, terminou com o mesmo comprimento

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 caracteres)

A nova linha logo antes exité apenas para legibilidade.

#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 descaradamente roubado da Allbeert. Observe que esta solução não é compilada com o gcc, pois tenta impor um protótipo inexistente para exit. Compile com um compilador C funcional, comotcc . Além disso, essa função pode ou não funcionar em plataformas de 64 bits. Use com cuidado.

Aqui está a implementação original não-baseada em que isso se baseia:

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

Experimente online!

Velha pergunta que eu conheço, mas divertido de qualquer maneira. Chance de experimentar alguns truques que aprendi desde que entrei.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.