Объясните десятичные дроби


12

Задав десятичное число в форме <float>, <precision>, вы рисуете графическое представление десятичной части (т.е. дроби) с плавающей точкой. Примеры:

  1. Вход:, 6.75, 4выход:

    6||| 7
     ---- 
    

    6.75(первое число из входных данных) - это число, которое нужно объяснить, 4(второе число из входных данных) - это число тире под трубами. 6Этаж 6,75, 7это потолок 6.75. Количество труб это decimal part of first input number * second input number.

  2. Вход:, 10.5, 6выход:

    10|||   11
      ------
    
  3. Вход: 20.16, 12выход

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

    .16 на самом деле берет 1,92 трубы, но так как я не могу нарисовать 1,92 трубы, я уменьшу его до 2.

  4. Вход:, 1.1, 12выход:

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

    .1 В данном случае это 1,2 трубы, так что она рассчитана на 1 трубу.

  5. Также крайний случай. Ввод: 5, 4(то есть число является целым числом), вывод:

    5    6
     ----
    

  • Число для объяснения - это положительное число, ограниченное только вашими языковыми способностями.
  • Число точности является четным целым числом, большим 2 (т. Е. Минимальная требуемая точность равна 4). Это может быть произвольно большим тоже.
  • > = n.5 трубы округляются до n + 1 (то есть 1,5 округляется до 2, а 2,5 округляется до 3). <n.5 трубы округляются до n (т.е. 1,4 округляется до 1, а 2,4 округляется до 2).
  • Если это будет более удобно для вашего языка, вы можете принять входные данные в виде массива, например [6.75, 4]. Если вы берете данные в обратном порядке, то есть [4, 6.75], пожалуйста, укажите это в своем ответе.

Можете ли вы быть более точным о том, какой именно желаемый формат вывода?
Исаак

@isaacg Я показал четыре примера результатов. Что неясно?
nicael

Похоже, было раскрыто несколько угловых случаев. Например , вход 5.0 4: это сделать из 5в 6или из 4в 5, или является либо приемлемым? Входные данные 1.25 2: у него есть 0 или 1 |с, и почему (то есть, каково правило округления)? Должен ли первый номер на входе быть положительным? Какова его максимальная точность и величина? Второй номер на входе должен быть положительным? Если это отрицательно, мы рисуем в обратном направлении?
Питер Тейлор

@ Питер уточнил.
nicael

Я не думаю, что вы охватили правило округления.
Питер Тейлор

Ответы:


6

CJam, 32 байта

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

Принимает точность первой и десятичной секунды, разделенных пробелом.

Запустите все тестовые случаи.

объяснение

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.

Да, кажется, работает нормально.
nicael

4

Mathematica, 119 байт

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

Я пытался ... Тестирование:

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

Не могли бы вы предоставить рабочую демоверсию или это невозможно?
nicael


3

Ява, 253 206 181 байт

За счет @Kenney удалось сэкономить 47 байт за счет включения условий и переменных, которые использовались один раз, и сортировки избыточных переменных.

Снова сэкономили 25 байт благодаря @Kenney, добавив 2 цикла с троичными операторами.

Манипуляция чистой строкой:

Версия со встроенными циклами (181 байт):

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

Версия с 4 циклами (206 байт):

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

Безголовая версия:

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.

Рабочий пример здесь на ideone.com . Полная программа принимает ввод STDIN как <float>,<precision>.

ПРИМЕЧАНИЕ: Math.round(float)раунды Java используются RoundingMode.HALF_UPпо умолчанию, что является обязательным поведением OP.

Выходные данные предоставленных тестовых примеров были сопоставлены с тем, что предоставил OP.


Надеюсь, ты не против! Вы забыли удалить a(не используется), настраивая Вас на 233. Вы можете сэкономить еще 23 , чтобы получить в 210 байт: замена q.length()с bэкономит 13: int g=(int)f, b=(""+g).length(), c=b, i=0;. Приращение итератора в состоянии из forэкономит 6 и встраивание d(используется один раз) экономит 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+=" ";.
Кенни

Кроме того, кто-то предложил использовать фактическую новую строку вместо escape-последовательности, но так как я на Windows, это CRLF, 2 байта в любом случае, учитывая\n
Тамогна Чаудхури

Ницца - да, bустаревает как хорошо ;-) Вы все еще можете сохранить 1 байт в 2 для: for(;i++<=c+p;). Вы можете сохранить файл с окончаниями строк Unix на окнах, но, к сожалению, Java не допускает многострочные строки ..
Кенни

@ Кенни, нет. Я попробовал это. Это приводит к смещенным дефисам. Во всяком случае, Java не подходит для этой работы.
Тамогна Чоудхури

Я сократил его до 181 байта, используя только 2 для циклов:for(;i<c+p;)h+=i++<c?" ":"-";for(i=c;i<p+c;)q+=i++<c+Math.round((f-g)*p)?"|":" ";
Кенни

3

Javascript ES6, 105 104 байта

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

Сохранено 1 байт, благодаря, как вы в любом случае печатаете ՊՓԼՃՐՊՃՈԲՍԼ?


Извините, я не осознавал, что черточки были частью результата, я думал, что они просто предназначены для визуализации пространств.
Нил

(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

О да, замените \nреальным переводом строки. И обязательно оберните его в строки шаблона.
Mama Fun Roll

2

Haskell, 113 байт

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

Пример использования:

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

properFractionразбивает десятичную дробь на целые и дробные части. Выходные данные представляют собой список частей (начальное число, столбцы, пробелы, ...), которые объединяются в одну строку (через >>=id).


Можно ли увидеть онлайн демо этого?
nicael

@nicael: демоmainоберткой для полной программы).
Ними

Похоже, все в порядке (кстати, там проверено , думаю, что это более удобный компилятор).
nicael

2

MATL , 49 байт

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

Использует релиз 6.0.0 языка / компилятора. Работает на Matlab или Octave.

Принимает числа в том же порядке, что и в задании.

Примеры

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

объяснение

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

У вас есть онлайн переводчик?
nicael

Еще нет :-( Работает на Matlab или Octave
Луис Мендо

2

Perl, 90 байт

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

Ожидается ввод в качестве аргументов командной строки. Сохранить в файл (скажем 90.pl) и запустить какperl 90.pl 6.75 4

С комментариями

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'

1

Стек , 31 27 байт

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

Подобно большинству других ответов. Я посмотрю, смогу ли я играть в гольф больше. Входные данные могут быть разделены запятыми, разделены пробелами или почти чем-либо разделены.

Не конкурирует, потому что Stackgoat был сделан после этого испытания

объяснение

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

1

Луа, 157 байт

Долго, но не могу найти более короткое решение

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

Вы можете проверить lua онлайн , следующие тесты могут быть полезны :)

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

1

C, 233 231 байт

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

1

Python 3, 116 108 байт

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)

ссылка на trinket.io

Спасибо Seeq за сохранение нескольких символов.

Первая версия:

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)

Безголовая версия:

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)

Не могли бы вы предоставить рабочую демонстрацию?
Ника

Эта ссылка на trinket.io должна работать: trinket.io/python/409b1488f8
Джек Браунштейн,

На самом деле требуется меньше символов, чтобы просто использовать пробел, чем хранить его. Вы также можете просто присоединиться ко всем линиям ;. Вы используете только hодин раз, поэтому вы должны включить его тоже. Должны сохранить некоторые символы.
Seequ

@Seeq Хороший улов на космическом литерале. В начале я печатал отступы пробела в конце второй строки; после того, как я понял, что в этом нет необходимости, я не стал дважды проверять код на предмет экономии. Это hсложнее. Чтобы конкатенация и lenфункция в двух последних строках работали, lдолжна быть строка, поэтому hее необходимо заменить на str(int(l)+1). Установка hперед преобразованием lсохраняет несколько символов.
Джек Браунштейн
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.