Explique os decimais

12

Dado um decimal na forma de <float>, <precision>, você desenha a representação gráfica da parte decimal (ou seja, fração) do flutuador. Exemplos:

  1. Entrada:, 6.75, 4saída:

    6||| 7
     ---- 
    

    6.75(primeiro número da entrada) é o número a ser explicado 4(o segundo número da entrada) é o número de traços abaixo dos tubos. 6é o piso 6,75, 7é o teto 6.75. O número de tubos é o decimal part of first input number * second input number.

  2. Entrada:, 10.5, 6saída:

    10|||   11
      ------
    
  3. Entrada:, 20.16, 12saída

    20||          21
      ------------
    

    .16 na verdade, usa 1,92 tubos, mas como não consigo desenhar 1,92, eu o levo a 2.

  4. Entrada:, 1.1, 12saída:

    1|           2
     ------------
    

    .1 é de 1,2 canos neste caso, então ele é colocado em um cano.

  5. Além disso, um estojo de ponta. Entrada: 5, 4(ou seja, o número é um número inteiro), saída:

    5    6
     ----
    

  • O número a ser explicado é o número positivo, limitado apenas pelas suas habilidades no idioma.
  • O número de precisão é um inteiro par, maior que 2 (ou seja, a precisão mínima exigida é 4). Também pode ser arbitrário grande.
  • > = n.5 os tubos são arredondados para n + 1 (ou seja, 1,5 é arredondado para 2 e 2,5 é arredondado para 3). <n.5 os tubos são arredondados para n (ou seja, 1,4 é arredondado para 1 e 2,4 é arredondado para 2).
  • Se for mais conveniente para o seu idioma, você pode receber a entrada como uma matriz, por exemplo [6.75, 4]. Se você receber a entrada na ordem inversa, ou seja [4, 6.75], especifique-a na sua resposta.
nicael
fonte
Você pode ser mais específico sobre exatamente qual é o formato de saída desejado?
Isaacg
@isaacg Eu mostrei quatro saídas de exemplo. O que não está claro?
Nicael 01/01
Parece haver alguns casos de esquina descobertos. De entrada, por exemplo 5.0 4: ele extrair 5para 6ou a partir 4de 5, ou seja aceitável? Entrada 1.25 2: possui 0 ou 1 se |, e por quê (ou seja, qual é a regra de arredondamento)? O primeiro número na entrada precisa ser positivo? Qual é a máxima precisão e magnitude? O segundo número na entrada precisa ser positivo? Se é negativo, desenhamos para trás?
Peter Taylor
@ Peter Esclarecido.
Nicael
Não acho que você tenha coberto a regra de arredondamento.
Peter Taylor

Respostas:

6

CJam, 32 bytes

l~1md@:X*mo'|*XSe]1$)NW$s,S*'-X*

Pega primeiro a precisão e o segundo decimal, separados por um espaço.

Execute todos os casos de teste.

Explicação

l~   e# Read input and evaluate, pushing precision and decimal on the stack.
1md  e# Divmod 1, separating the decimal into integer and fractional part.
@:X  e# Pull up precision, store in X.
*mo  e# Multiply precision by fractional part and round.
'|*  e# Push that many vertical bars.
XSe] e# Pad with length X with spaces.
1$)  e# Copy integer part and increment.
N    e# Push linefeed.
W$   e# Copy integer part.
s,   e# Get number of digits as length of string representation.
S*   e# Push that many spaces, to indent the hyphens correctly.
'-X* e# Push X hyphens.
Martin Ender
fonte
Sim, parece funcionar bem.
Nicael
4

Mathematica, 119 bytes

a=ToString;b=Array;a[c=Floor@#]<>{b["|"&,d=Round[#2#~Mod~1]],b[" "&,#2-d],a[c+1],"
"," "&~b~IntegerLength@c,"-"&~b~#2}&

Eu tentei ... Testando:

In[1]:= a=ToString;b=Array;f=a[c=Floor@#]<>{b["|"&,d=Round[#2#~Mod~1]],b[" "&,#2-d],a[c+1],"\n"," "&~b~IntegerLength@c,"-"&~b~#2}&;

In[2]:= f[6.75, 4]

Out[2]= 6||| 7
         ----

In[3]:= f[10.5, 6]

Out[3]= 10|||   11
          ------

In[4]:= f[20.16, 12]

Out[4]= 20||          21
          ------------

In[5]:= f[1.1, 12]

Out[5]= 1|           2
         ------------

In[6]:= f[5, 4]

Out[6]= 5    6
         ----
LegionMammal978
fonte
Você poderia talvez fornecer uma demonstração funcional, ou não é possível?
Nicael 01/01
3

Japonês, 47 46 bytes

Uf +'|pA=ºU-Uf)*V c)+SpV-A +Uc +R+SpUk l)+'-pV

Apenas um monte de adição e repetição.

Experimente online

Downgoat
fonte
(U-Uf)é o mesmo que U%1salvar dois bytes.
ETHproductions
3

Java, 253 206 181 bytes

Economizou 47 bytes graças ao @Kenney, ao incluir condições e variáveis ​​usadas uma vez e classificar variáveis ​​redundantes.

Economizou 25 bytes novamente graças ao @Kenney, alinhando 2 loops com operadores ternários.

Manipulação de Cordas Puras:

Versão de loops embutidos (181 bytes):

String m(float f,int p){int g=(int)f,i=0;String h="",q=""+g;int c=q.length();for(;i<c+p;)h+=i++<c?" ":"-";for(i=c;i<p+c;)q+=i++<c+Math.round((f-g)*p)?"|":" ";return q+(g+1)+"\n"+h;}

Versão de 4 loops (206 bytes):

String m(float f,int p){int g=(int)f,i=0;String h="",q=""+g;int c=q.length();for(;i++<c;)h+=" ";for(;i<=c+p;i++)h+="-";for(i=c;i<c+Math.round((f-g)*p);i++)q+="|";for(;i++<p+c;)q+=" ";return q+(g+1)+"\n"+h;}

Versão não destruída:

String m(float f,int p){
//initialize some useful values, d is the number of pipes needed
int g=(int)f,d=Math.round((f-g)*p),i=0;
String h="",q=""+g;//append the floored value to the pipe string first
int c=q.length();
for(;i<c;i++)h+=" ";//pad hyphen string with spaces for alignment
for(++i;i<=c+p;i++)h+="-";//append hyphens
for(i=c;i<c+d;i++)q+="|";//append pipes
for(;i<p+c;i++)q+=" ";//append spaces for padding
return q+(g+1)+"\n"+h;}//concatenate the strings in order, separating the strings with a UNIX newline, and return it.

Exemplo de trabalho aqui em ideone.com . O programa completo aceita a entrada STDIN como <float>,<precision>.

OBSERVAÇÃO: as Math.round(float)rodadas de Java usam RoundingMode.HALF_UPcomo padrão, que é o comportamento necessário do OP.

A saída dos casos de teste fornecidos foi diferente do que o OP forneceu.

Tamoghna Chowdhury
fonte
Espero que você não se importe! Você esqueceu de remover a(nunca usado), definindo-lo em 233. Você poderia salvar outros 23 para chegar aos 210 bytes: a substituição q.length()com bsalva 13: int g=(int)f, b=(""+g).length(), c=b, i=0;. Incrementando o iteração na condição da forsalva 6, e inline d(usado uma vez) economiza 4: int c = b; for(;i++<b;)h+=" "; for(;i++<=b+p;)h+="-"; for(i=c;i<c+Math.round((f-g)*p);i++)q+="|"; for(;i++<p+b;)q+=" ";.
Kenney
Além disso, alguém sugeriu o uso de uma nova linha real em vez da seqüência de escape, mas desde que eu estou no Windows, isso é um CRLF, 2 bytes de qualquer maneira, dada a\n
Tamoghna Chowdhury
Nice - sim, btornou-se aswell obsoleto ;-) Você ainda pode salvar 1 byte na 2ª para: for(;i++<=c+p;). Você pode salvar o arquivo com terminações de linha Unix no Windows, mas, infelizmente, Java não permitir que cordas de várias linhas ..
Kenney
@ Kenney, não. Eu tentei isso. Isso leva a hífens desalinhados. Java não é o homem certo para o trabalho, de qualquer maneira.
Tamoghna Chowdhury
Eu o reduzi para 181 bytes usando apenas 2 para loops:for(;i<c+p;)h+=i++<c?" ":"-";for(i=c;i<p+c;)q+=i++<c+Math.round((f-g)*p)?"|":" ";
Kenney
3

Javascript ES6, 105 104 bytes

(f,p)=>(i=f|0)+("|".repeat(j=(f-i)*p+.5|0)+" ".repeat(p-j))+(i+1)+(`
`+i).replace(/\d/g," ")+"-".repeat(p)

Economizei 1 byte graças a, hum, como você digita ՊՓԼՃՐՊՃՈԲՍԼ?

Neil
fonte
Desculpe, eu não sabia que os traços faziam parte da saída, pensei que eles estavam lá apenas para visualizar os espaços.
Neil
(f,p)=>(i=f|0)+("|"[r="repeat"](j=(f-i)*p+.5|0)+" "[r](p-j))+(i+1)+("\n"+i).replace(/\d/g," ")+"-"[r](p)
Mama Fun Roll
Ah, sim, substitua \npor uma nova linha real. E certifique-se de envolvê-lo em seqüências de caracteres de modelo.
Mama Fun Roll
2

Haskell, 113 bytes

(%)=replicate.round
s=show
x!y|(n,m)<-properFraction x=[s n,(y*m)%'|',(y-y*m)%' ',s$n+1,"\n",s n>>" ",y%'-']>>=id

Exemplo de uso:

*Main> putStrLn $ 20.16 ! 12
20||          21
  ------------

properFractiondivide o decimal em sua parte inteira e fração. A saída é uma lista das partes (número inicial, barras, espaços, ...) que são concatenadas em uma única sequência (via >>=id).

nimi
fonte
É possível ver uma demonstração online disso?
Nicael
@nicael: demo (com um maininvólucro para um programa completo).
Ni1
Parece que está tudo bem (btw: testado , pense que é um compilador mais conveniente).
Nicael
2

MATL , 49 bytes

2#1\tYUbiXK*Yo'|'1bX"tnKw-Z"hb1+YUhht4Y2m13*_45+c

Utiliza a versão 6.0.0 do idioma / compilador. É executado em Matlab ou Octave.

Toma números na mesma ordem que no desafio.

Exemplos

>> matl
 > 2#1\tYUbiXK*Yo'|'1bX"tnKw-Z"hb1+YUhht4Y2m13*_45+c
 >
> 20.16
> 12
20||          21
  ------------

>> matl
 > 2#1\tYUbiXK*Yo'|'1bX"tnKw-Z"hb1+YUhht4Y2m13*_45+c
 >
> 5
> 4
5    6
 ----

Explicação

2#1\       % implicit input 1st number. Separate decimal and integer part
tYU        % duplicate integer part and convert to string
biXK*Yo    % input 2nd number. Copy it. Multiply by decimal part of 1st number and round
'|'1bX"    % row vector of as many '|' as needed
tnKw-Z"    % row vector of as many spaces as needed
h          % concat horiontally
b1+YUhh    % integer part of 1st number plus 1. Convert to string. Concat twice
t4Y2m      % detect numbers in this string
13*_45+c   % transform numbers into spaces, and non-numbers into '|'
           % implicitly display both strings
Luis Mendo
fonte
Você tem um intérprete online?
Nicael
Ainda não :-( Corre em Matlab ou Octave
Luis Mendo
2

Perl, 90 bytes

print$f,"|"x($d=.5+($b=pop)*(($a=pop)-($f=0|$a))),$"x(1+$b-$d),$f+1,$/,$"x length$f,"-"x$b

Espera entrada como argumentos da linha de comando. Salve em um arquivo (digamos 90.pl) e execute comoperl 90.pl 6.75 4

Com comentários

print $f,                        # floored input (initialized below due to expr nesting)
      "|" x ($d=.5+              # rounded pipe count (`x` operator casts to int)
             +($b=pop)           # second argument  (executed first)
             *( ($a=pop)         # first argument   (executed second)
               -($f=0|$a) )      # minus floored first argument = fractional part
            ),
      $"x(1+$b-$d),              # spaces
      $f+1,                      # floored + 1
      $/,                        # newline
      $"  x length $f,           # 2nd line alignment
      "-" x $b                   # the 'ruler'
Kenney
fonte
1

Stackgoat , 31 27 bytes

CFv1%C*D'|^w1P-Y^vHXNY^w'-^

Semelhante à maioria das outras respostas. Vou ver se consigo jogar mais golfe. A entrada pode ser separada por vírgula, espaço ou quase qualquer coisa separada.

Não competir porque o Stackgoat foi criado após esse desafio

Explicação

CF   // Input, floored, push to stack
v1%  // Decimal part
C*   // Times second part
D    // Duplicate that result
'|^  // Repeat | by previous number
w    // Second input
1P   // Move # of |'s to the top of stack
-    // Subtract
Y^   // Repeat " " by above number
vH   // Ceil first input
X    // Newline
Z+   // Add to 
N    // Get length of first #
Y^   // Repeat by spaces
w'-  // Repeat - second input times
Downgoat
fonte
1

Lua, 157 bytes

Longo, mas não consegue encontrar uma solução mais curta

function f(d,n)r=""a=math.floor(d)d,s=d-a,a..r for i=1,#s do r=r.." "end for i=1,n do s,r=s..(i-.5>n*d and" "or"|"),r.."-"end s=s..a+1 return s.."\n"..r end

Ungolfed

function g(d,n)
  r=""
  a=math.floor(d)
  d,s=d-a,a..r                         -- d now contains its decimal part
  for i=1,#s do r=r.." "end            -- padding the hyphens
  for i=1,n
  do
    s,r=s..(i-.5>n*d and" "or"|"),r.."-"
    -- s is concatenated with a "|" if i-.5>n*d, a space otherwise
  end
  s=s..a+1
  return s.."\n"..r
end

Você pode testar o lua online , os seguintes casos de teste podem ser úteis :)

function f(d,n)r=""a=math.floor(d)d,s=d-a,a..r for i=1,#s do r=r.." "end for i=1,n do s,r=s..(i-.5>n*d and" "or"|"),r.."-"end s=s..a+1 return s.."\n"..r end
print(f(16.75,4))
print(f(5,4))
print(f(20.16,12))
Katenkyo
fonte
1

C, 233 231 bytes

#include <stdlib.h>
#include <math.h>
i,n,l;main(c,v)char**v;{double m;l=atol(v[2]);n=(int)(modf(atof(v[1]),&m)*l+0.5);c=printf("%.f",m);for(;i++<l;)putchar(i>n?32:'|');printf("%.f\n",m+1);printf("%*s",c,"");for(;--i;)putchar(45);}

Ungolfed:

#include <stdlib.h>
#include <math.h>
i,n,l;

main(c,v)
char**v;
{
    double m;
    l=atol(v[2]); /* Get length from command line */
    n=(int)(modf(atof(v[1]),&m)*l+0.5); /* Get number of pipes and lower limit */
    c=printf("%.f",m); /* print lower limit */

    /* print pipes and spaces */
    for(;i++<l;)
            putchar(i>n?32:'|');

    /* print upper limit */
    printf("%.f\n",m+1);

    /* print spaces before dashes */
    printf("%*s",c,"");

    /* print dashes */
    for(;--i;)
            putchar(45);
}
Cole Cameron
fonte
1

Python 3, 116 108 bytes

def f(F,P):l=int(F);h,p=str(l+1),int((F-l)*P+.5);l=str(l);print(l+"|"*p+" "*(P-p)+h);print(" "*len(l)+"-"*P)

link trinket.io

Obrigado a Seeq por salvar alguns caracteres.

Primeira versão:

def f(F,P):
 l=int(F)
 h,s,p=str(l+1)," ",int((F-l)*P+.5)
 l=str(l)
 print(l+"|"*p+s*(P-p)+h)
 print(s*len(l)+"-"*P)

Versão não destruída:

def frac(F,P):
        low = int(F)
        high = low+1
        pipes = int((F-low)*P+.5)
        print(str(low)+"|"*pipes+" "*(P-pipes)+str(high))
        print(" "*len(str(low))+"-"*P)
Jack Brounstein
fonte
Você poderia fornecer uma demonstração funcional?
Nicael
Este link trinket.io deve funcionar: trinket.io/python/409b1488f8
Jack Brounstein
Na verdade, são necessários menos caracteres para usar apenas o literal de espaço do que armazená-lo. Você também pode juntar todas as linhas com ;. Você usa apenas huma vez, portanto, deve incorporá-lo também. Deve salvar alguns caracteres.
seequ
@Seeq Boa captura no literal do espaço. No início, eu estava imprimindo o preenchimento de espaço em branco no final da segunda linha; depois que percebi que era desnecessário, não verifiquei o código para economizar. O hé mais complicado. Para que a concatenação e a lenfunção nas duas últimas linhas funcionem, ldeve ser uma cadeia de caracteres, portanto h, precisará ser substituída por str(int(l)+1). A configuração hantes da conversão lsalva alguns caracteres.
Jack Brounstein