Wyjaśnij ułamki dziesiętne

12

Biorąc pod uwagę liczbę dziesiętną w postaci <float>, <precision>, rysujesz graficzną reprezentację części dziesiętnej (tj. Ułamka) liczby zmiennoprzecinkowej. Przykłady:

  1. Wejście:, 6.75, 4wyjście:

    6||| 7
     ---- 
    

    6.75(pierwsza liczba z wejścia) to liczba do wyjaśnienia, 4(druga liczba z wejścia) to liczba myślników pod rurami. 6jest floored 6,75, 7jest sufitem 6.75. Liczba rur to decimal part of first input number * second input number.

  2. Wejście:, 10.5, 6wyjście:

    10|||   11
      ------
    
  3. Wejście:, 20.16, 12wyjście

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

    .16 faktycznie bierze 1,92 rury, ale ponieważ nie mogę narysować 1,92 rur, ustawiam sufit na 2.

  4. Wejście:, 1.1, 12wyjście:

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

    .1 w tym przypadku jest 1,2 rurki, więc jest przeniesiony do 1 rury.

  5. Również skrzynia krawędzi. Dane wejściowe: 5, 4(tzn. Liczba jest liczbą całkowitą), dane wyjściowe:

    5    6
     ----
    

  • Liczba do wyjaśnienia to liczba dodatnia, ograniczona tylko twoimi umiejętnościami językowymi.
  • Liczba dokładności jest parzystą liczbą całkowitą, większą niż 2 (tj. Minimalna wymagana precyzja wynosi 4). Może być również dowolnie duży.
  • > = n.5 rur zaokrągla się w górę, do n + 1 (tj. 1,5 zaokrągla się do 2, a 2,5 zaokrągla się do 3). <n.5 rury są zaokrąglane do n (tj. 1.4 jest zaokrąglany do 1, a 2.4 jest zaokrąglany do 2).
  • Jeśli byłoby to wygodniejsze dla twojego języka, możesz wziąć dane wejściowe jako tablicę, np [6.75, 4]. Jeśli wprowadzisz dane w odwrotnej kolejności, tzn. [4, 6.75]Podaj je w swojej odpowiedzi.
Nicość
źródło
Czy możesz bardziej szczegółowo określić, jaki jest pożądany format wyjściowy?
isaacg
@isaacg Pokazałem cztery przykładowe wyniki. Co jest niejasne?
nicael
Wydaje się, że odkryto kilka przypadków narożnych. Wejście na przykład 5.0 4: czy wyciągnąć z 5do 6lub od 4celu 5, czy też dopuszczalne? Dane wejściowe 1.25 2: czy ma 0 lub 1 |s i dlaczego (tj. Jaka jest zasada zaokrąglania)? Czy pierwsza liczba na wejściu musi być dodatnia? Jaka jest jego maksymalna precyzja i wielkość? Czy druga liczba na wejściu musi być dodatnia? Jeśli jest negatywny, czy cofamy się?
Peter Taylor
@Peter Clarified.
nicael
Nie sądzę, żebyś przestrzegał zasady zaokrąglania.
Peter Taylor

Odpowiedzi:

6

CJam, 32 bajty

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

Najpierw precyzja i sekunda dziesiętna, oddzielone spacją.

Uruchom wszystkie przypadki testowe.

Wyjaśnienie

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
źródło
Tak, wydaje się działać dobrze.
nicael
4

Mathematica, 119 bajtów

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

Próbowałem ... Testowanie:

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
źródło
Czy możesz podać działające demo, czy nie jest to możliwe?
nicael
3

Japt, 47 46 bajtów

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

Tylko kilka dodawania i powtarzania.

Wypróbuj online

Downgoat
źródło
(U-Uf)jest taki sam jak U%1zapisanie dwóch bajtów.
ETHprodukcje
3

Java, 253 206 181 bajtów

Zaoszczędź 47 bajtów dzięki @Kenney, wprowadzając warunki i zmienne używane raz, i sortując zbędne zmienne.

Zaoszczędź 25 bajtów ponownie dzięki @Kenney, wprowadzając 2 pętle z operatorami trójskładnikowymi.

Manipulacja czystym ciągiem:

Wersja z wbudowanymi pętlami (181 bajtów):

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

Wersja z 4 pętlami (206 bajtów):

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

Wersja bez golfa:

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.

Przykład działania tutaj w ideone.com . Pełny program akceptuje wejście STDIN jako <float>,<precision>.

UWAGA: Math.round(float)rundy Java są używane RoundingMode.HALF_UPjako domyślne, co jest wymaganym zachowaniem PO.

Wynik dostarczonych przypadków testowych był dopasowany do tego, co zapewnił PO.

Tamoghna Chowdhury
źródło
Mam nadzieję, że nie masz nic przeciwko! Zapomniałeś, aby usunąć a(nie używany), ustawienie na 233. Można zaoszczędzić dodatkowe 23 do 210 bajtów dostać na: wymianie q.length()z boszczędza 13: int g=(int)f, b=(""+g).length(), c=b, i=0;. Zwiększanie iteracyjnej w stanie z forzapisuje 6 i inline d(raz) zachowuje 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
Ponadto ktoś zasugerował użycie rzeczywistej nowej linii zamiast sekwencji ucieczki, ale ponieważ jestem w systemie Windows, jest to CRLF, 2 bajty w każdym razie biorąc pod uwagę\n
Tamoghna Chowdhury
Nice - Tak, bstało się nieaktualne aswell ;-) Można jeszcze uratować 1 bajt w 2. za: for(;i++<=c+p;). Ty mógł zapisać plik Unix zakończeń linii na okna, ale niestety Java nie pozwala multilinii struny ..
Kenney
@Kenney, no. Próbowałem tego. Prowadzi to do niedopasowanych łączników. W każdym razie Java nie jest odpowiednim człowiekiem do tego zadania.
Tamoghna Chowdhury
Sprowadziłem go do 181 bajtów, używając tylko 2 pętli for: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 bajtów

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

Zaoszczędzono 1 bajt dzięki, um, jak w ogóle wpisujesz ՊՓԼՃՐՊՃՈԲՍԼ?

Neil
źródło
Przepraszam, nie zdawałem sobie sprawy, że kreski są częścią wyjścia, myślałem, że są tylko po to, aby wizualizować przestrzenie.
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
O tak, zastąp \nprawdziwą nową linią. I pamiętaj o owinięciu go ciągami szablonów.
Mama Fun Roll
2

Haskell, 113 bajtów

(%)=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

Przykład użycia:

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

properFractiondzieli przecinek dziesiętny na część całkowitą i ułamkową. Dane wyjściowe to lista części (liczba początkowa, słupki, spacje, ...), która jest połączona w pojedynczy ciąg (via >>=id).

nimi
źródło
Czy można zobaczyć demo online?
nicael
@nicael: demo (z mainopakowaniem dla pełnego programu).
nimi
Wygląda na to, wszystko jest w porządku (btw: testowany tam , myślę, że jest to bardziej wygodne kompilator).
nicael
2

MATL , 49 bajtów

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

Korzysta z wersji 6.0.0 języka / kompilatora. Działa na Matlabie lub Oktawie.

Pobiera liczby w tej samej kolejności, co w wyzwaniu.

Przykłady

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

Wyjaśnienie

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
źródło
Czy masz tłumacza online?
nicael
Jeszcze nie :-( Działa na Matlabie lub Oktawie
Luis Mendo
2

Perl, 90 bajtów

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

Oczekuje danych wejściowych jako argumentów wiersza polecenia. Zapisz w pliku (powiedzmy 90.pl) i uruchom jakoperl 90.pl 6.75 4

Z komentarzami

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
źródło
1

Stackgoat , 31 27 bajtów

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

Podobne do większości innych odpowiedzi. Zobaczę, czy mogę więcej grać w golfa. Dane wejściowe mogą być oddzielone przecinkami, spacjami lub prawie dowolne.

Nie konkuruje, ponieważ Stackgoat powstał po tym wyzwaniu

Wyjaśnienie

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
źródło
1

Lua, 157 bajtów

Długie, ale nie można znaleźć krótszego rozwiązania

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

Nie golfił

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

Możesz przetestować lua online , przydatne mogą być następujące przypadki testowe :)

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
źródło
1

DO, 233 231 bajtów

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

Nie golfowany:

#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
źródło
1

Python 3, 116 108 bajtów

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

Dziękujemy Seeq za uratowanie kilku znaków.

Pierwsza wersja:

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)

Wersja bez golfa:

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
źródło
Czy możesz podać działające demo?
nicael
Ten link trinket.io powinien działać: trinket.io/python/409b1488f8
Jack Brounstein
Właściwie potrzeba mniej znaków, aby po prostu użyć literału spacji niż go zapisać. Możesz także po prostu połączyć wszystkie linie za pomocą ;. Używasz tylko hraz, więc też powinieneś to wstawić. Powinien zapisać niektóre znaki.
patrz
@Seeq Dobry chwyt literału odstępu. Na początku drukowałem białe wypełnienie na końcu drugiej linii; kiedy zdałem sobie sprawę, że nie było to konieczne, nie sprawdziłem dwukrotnie kodu oszczędności. To htrudniejsze. Aby konkatenacja i lenfunkcja w dwóch ostatnich wierszach działały, lmusi to być ciąg znaków, więc hnależy go zastąpić str(int(l)+1). Ustawienie hprzed konwersją lzapisuje kilka znaków.
Jack Brounstein,