Виконайте довільний поділ на точність


15

Реалізуйте функцію, divide(int a, int b, int c)яка друкує базове значення 10 a/b. без використання жодної математики з плаваючою точкою та BigInteger/ BigDecimalабо еквівалентних бібліотек. Принаймні cточні символи в наборі 0123456789.повинні бути надруковані, за винятком (можливого) винятку в пункті 4 нижче.

  1. aі bможе бути будь-якими 32 бітовими цілими числами. Оновлення: Якщо для цілей гольфу ви хочете, щоб ваш вхід був 64-бітовим примітивом, це нормально, але вам не потрібно підтримувати весь 64-бітовий діапазон даних.
  2. Вам не потрібно перевіряти, що cце позитивно (хоча, сподіваємось, ваша програма не виходить з ладу), якщо це не так.
  3. Мінімальна підтримувана верхня межа для c- 500. Добре, якщо ваша програма не підтримує значення, cнаведені вище500 , але це також добре, якщо це так.
  4. Для чисел, які поділяються рівномірно, вибираєте, друкувати зайві нулі (виходячи зі значення c) або нічого.
  5. Вам не потрібно мати можливість використовувати цю функцію для виконання будь-яких подальших завдань з коефіцієнтом, єдина мета - друк.
  6. Для чисел між -1і 1, вибираєте, чи надрукувати провідну 0. Однак це єдиний сценарій, коли друк провідного нуля є прийнятним, і ви можете надрукувати лише один такий нуль.
  7. Ви можете використовувати будь-яку логіку округлення / підлоги / стелі для останнього десяткового знака.
  8. Для негативної відповіді потрібно надрукувати ведучий -. Це не рахується c. Однак ви бажаєте друкувати ,+ або нічого для позитивної відповіді.
  9. Ціле ділення та цілий модуль дозволено. Однак майте на увазі, що ви обмежені лише примітивами, якщо ви не вирішите реалізувати власну BigInteger/ BigDecimalбібліотеку, яка вважатиметься вашою кодовою довжиною.
  10. Вам не потрібно впоратися з bбуттям 0, хоча ви можете, якщо хочете. Ваша програма може увійти в нескінченний цикл або вийти з ладу, якщо b=0і вас не покарають.
  11. Невелика зміна правила за коментарем. Щоб переконатися, що ігрове поле є рівним, тоді як aі bгарантовано вони будуть 32-бітовими цілими числами, ви можете використовувати 64-бітні цілі числа. Якщо обрана вами мова перевищує 64-бітні цілі числа як примітивні, ви можете ні в якому разі не використовувати цю функціональність (зробіть вигляд, що вона обмежена 64 бітами).
  12. Ще один незрозумілий момент (він не повинен змінювати жодної з поточних дійсних відповідей): хоча cможе бути інтерпретований як кількість друкованих символів, так і кількість пробілів після десяткової, ваша програма повинна cякось використовувати відповідний спосіб щоб вирішити, скільки символів надрукувати. Іншими словами, divide(2,3,2)вихід повинен бути значно коротшим, ніж divide(2,3,500); друкувати 500 символів без уваги не годиться c.
  13. Я насправді не хвилююся назвою функції. dдобре для цілей гольфу.

Вхідні дані

stdinПриймаються як виклик функції, так і читання з . Якщо ви читаєте з stdin, будь-який символ, який не знаходиться в наборі [-0123456789], вважається роздільником аргументів.

Вихідні дані

Символи, stdoutяк описано вище.

Приклад

для divide(2,3,5), всі наступні є прийнятними результатами:

0.666
0.667
.6666
.6667
 0.666
 0.667
 .6666
 .6667
+0.666
+0.667
+.6666
+.6667

Ще один приклад: для divide(371,3,5)наступного наведено всі прийнятні результати:

123.6
123.7
 123.6
 123.7
+123.6
+123.7
123.66666
123.66667
 123.66666
 123.66667
+123.66666
+123.66667

А для divide(371,-3,5)наступного всі прийнятні:

-123.6
-123.7
-123.66666
-123.66667

Заради рівних ігрових умов може бути доцільним вказати конкретну максимальну довжину бітів, яка може бути використана (примітивна чи інша), якщо ви не скочуєте власну більшу реалізацію, оскільки а) в деяких мовах довжина бітів примітивів змінюється залежно від основна архітектура та б) у деяких мовах велика кількість типів - примітиви.
Джонатан Ван Матре

@JonathanVanMatre Додано правило 11 за ваш коментар
durron597

1
Як ви рахуєте точні цифри ? У вашому прикладі я бачу три або чотири, але ніколи п'ять, як свідчить останній аргумент.
Говард

@Howard, якби ти 92,3,5відповів, наприклад,30.67
durron597

1
btw 370/3 = 123,333 lol
izabera

Відповіді:


5

Ява, 92/128

void d(long a,int b,int c){if(a<0^b<0){a=-a;p('-');}for(p(a/b+".");c>0;c--)p((a=a%b*10)/b);}<T>void p(T x){System.out.print(x);}

Мені довелося імпровізувати, щоб aчи bмогли бути -2147483648 як позитивні 32-бітові цілі числа зараховуються лише до 2147483647, тому я aстав а long. Можливо, є кращий спосіб поводження з негативними результатами, але я знаю, що жоден ( doubleімовірно, змусив би це працювати, abs(a) < abs(b)як у них, -0але лише доповнення збереже точність).

Чому два байтові числа? Для обчислення мені знадобилося 92 байти і 36 для помічника друку ( System.out.printвідстійно; взагалі Java не така вже й гола).

public class Div {

    void d(long a, int b, int c) {
        if (a < 0 ^ b < 0) {
            a = -a;
            p('-');
        }
        for (p(a / b + "."); c > 0; c--) {
            p((a = a % b * 10) / b);
        }
    }

    <T> void p(T x) {
        System.out.print(x);
    }

    public static void main(String[] args) {
        final Div div = new Div();
        div.d(12345, 234, 20);
        div.p('\n');
        div.d(-12345, 234, 20);
        div.p('\n');
        div.d(234, 234, 20);
        div.p('\n');
        div.d(-234, 234, 20);
        div.p('\n');
        div.d(234, 12345, 20);
        div.p('\n');
        div.d(234, -12345, 20);
        div.p('\n');
        div.d(-234, 12345, 20);
        div.p('\n');
        div.d(-234, -12345, 20);
        div.p('\n');
        div.d(-2147483648, 2147483647, 20);
        div.p('\n');
        div.d(2147483647, -2147483648, 20);
        div.p('\n');
    }
}

Метод в основному здійснює те, що більшість з нас навчилися в школі, щоб генерувати потрібні десяткові цифри.


Офіційна постанова: Я б сказав, що ігнорувати Integer.MIN_VALUEце не нормально, але longяк внесок це нормально.
durron597

Це набагато коротше. Чудово зроблено.
durron597

@ durron597 дякую Тим не менш, суворе введення тексту і System.outзмушує Яву почуватися об'ємною ;-) Все ще добре відчуття, що вже розміщені відповіді.
TheConstructor

1
@ durron597 ви спеціально попросили функцію, тому я подумав, що вона не зараховується. Якби мені довелося використовувати імпорт, ніж, ймовірно, так.
Конструктор

1
Принаймні, немає $ на кожну змінну ;-)
TheConstructor

9

C, 98 95 89

d(a,b,c){if(a>0^b>0)a=-a,printf("-");for(printf("%d.",a/b);c--;putchar(a/b+48))a=a%b*10;}

друкує cцифри після.

Приклад виведення:

d(2,3,5);
0.66666

d(-2,3,5);
-0.66666

d(24352345,31412,500);
775.25611231376543995925124156373360499172290844263338851394371577740990704189481726728638736788488475741754743410161721635043932255189099707118298739335285878008404431427479943970457150133706863618999108620909206672609193938622182605373742518782630841716541449127721889723672481854068508850120972876607665860180822615560932127849229593785814338469374761237743537501591748376416656055010823888959633261174073602444925506175983700496625493441996689163377053355405577486310963962816757926906914554947153953

d(-77,12346463,500);
-0.00000623660395693892250760399962321192717298873369644407471192356871761572524859953818352673150196943043525906974329409159530142357369879940514137530724386409289850866600418273638369142644334656816288195250736992448768525852302801215214430238036593962173620088603513411087855687900251270343579371679160258286118056645048869461642577311412993340683886551152342172814999729072204727783171585254821563066280601982932277851559592411203111368818745903178910429650985873444078680671541315111866451144752954

має працювати для -2147483647 <= a <= 2147483647, те ж саме для b. поводження з -болем було.

Інтернет-версія: ideone


Чи працює це для істоти -2147483648? Не знайте компіляторів c досить добре, щоб сказати, який цілочисельний тип призначений вашим параметрам.
TheConstructor

дякую, що вказали на це. вона працює правильно для -2147483647 <= a <= 2147483647, те ж саме для b. виникає проблема, коли a = -2147483648 і b додатна черезa=-a .
izabera

Я намагався, але врешті-решт отримав по суті те саме рішення, що і ти. Ви можете зберегти одного персонажа, зрозумівши, що printf("-")повертається 1.
Томас,

4

PHP, 108

function d($a,$b,$c){$a*$b<0&&$a*=-print'-';for($p='.';$c--;$a.=0,print$i.$p,$p='')$a-=$b*$i=($a-$a%$b)/$b;}

Він працює, просто виводячи коефіцієнт a/ bпід час циклу cкроків, aперетворюючи решту, помножену на 10 при кожній ітерації.

DEMO


Дає дивні результати, коли a або b є негативними
TheConstructor

Я виправив помилку за від’ємними числами. Спасибі!
Разван

Щойно знайшли 112 версію вашого коду: function d($a,$b,$c){if($a*$b<0)$a*=-print'-';for($p='.';$c--;$a*=10,$p=''){$a-=$b*$i=($a-$a%$b)/$b;echo$i.$p;}}дивіться значення повернення
TheConstructor

Спасибі. Я навіть оновив вашу версію і зумів виграти додатковий 1 байт.
Разван

2

Пітон 111

f=lambda a,b,c:'-'[a*b>=0:]+'%s'%reduce(lambda(d,r),c:(d%c*10,r+`d/c`+'.'[r!='':],),[abs(b)]*c,(abs(a),''))[-1]

Це рішення не порушує жодного із заявлених правил.


2

C: 72 символи

d(a,b,c){for(printf("%d.",a/b);c--;putchar((a=abs(a)%b*10)/abs(b)+48));}

Він майже повністю робить те, що повинен робити. Однак, як і деякі інші відповіді, тут даватимуться непрості значення або не вдасться, d(-2147483648,b,c)і d(a,-2147483648,c)оскільки абсолютне значення -2147483648 не виходить за межі для 32-бітного слова.


2

Perl, без арифметики, 274 байти

Це довгий поділ Евкліда, який , ймовірно, споживає незвичну кількість пам'яті. Найближче до математики на числах з плаваючою комою - це використання бітових операцій для їх розбору.

sub di{($v,$i,$d,$e)=(0,@_);($s,$c,$j)=$i=~s/-//g;$s^=$d=~s/-//g;
$i=~s/\.(\d+)/$j=$1,""/e;$d=~s/\.(\d+)/$c=$1,""/e;
$z=0.x+length($c|$j);$i.=$j|$z;$d.=$c|$z;
($e,$m,$z,$t)=(1.x$e,0.x$i,0.x$d,"-"x($s&1));
for(;$e;$t.="."x!$v,$v=chop$e){$t.=$m=~s/$z//g||0;$m="$m"x10}
print"$t\n"}

Приклади:

di(-355,113,238);
di(1.13,355,239);
di(27942,19175,239);
di(1,-90.09,238);
di("--10.0","----9.801",239);
di(".01",".200",239);

Вихід:

-3.141592920353982300884955752212389380530973451327433628318
584070796460176991150442477876106194690265486725663716814159
292035398230088495575221238938053097345132743362831858407079
646017699115044247787610619469026548672566371681415929203539

0.0031830985915492957746478873239436619718309859154929577464
788732394366197183098591549295774647887323943661971830985915
492957746478873239436619718309859154929577464788732394366197
183098591549295774647887323943661971830985915492957746478873

1.4572099087353324641460234680573663624511082138200782268578
878748370273794002607561929595827900912646675358539765319426
336375488917861799217731421121251629726205997392438070404172
099087353324641460234680573663624511082138200782268578878748

-0.011100011100011100011100011100011100011100011100011100011
100011100011100011100011100011100011100011100011100011100011
100011100011100011100011100011100011100011100011100011100011
100011100011100011100011100011100011100011100011100011100011

1.0203040506070809101112131415161718192021222324252627282930
313233343536373839404142434445464748495051525354555657585960
616263646566676869707172737475767778798081828384858687888990
919293949596979900010203040506070809101112131415161718192021

0.0500000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000

1

Рубі, 178

def d(a,b,c)
    n=(a<0)^(b<0)
    a=-a if n
    m=a/b-b/a
    l=m.to_s.size-1
    g=(a*10**(10+c)/b).to_s
    f=m<0?"."+"0"*(l-1)+g[0..c-l-1] : g[0..l]+"."+g[l+1..c-2]
    p n ? "-"+f : f
end

Інтернет-версія для тестування.

Трюк полягає в тому, щоб множити a на досить високе число, тому результат - це ціле число, кратне операції з плаваючою комою. Тоді точку та нулі потрібно вставити в потрібне місце в отриманому рядку.


Це працює для c більше 350?
durron597

Я перевірив це на c = 1000 - код дав мені відповідь, можливо, я повинен перевірити фактичний результат, хоча ...
Девід Геррманн

2
чи не gперевищує 64 біт для великих c? Редагувати: Я думаю, що ви неявно використовуєте BigIntegerтут
durron597

Помилка, gце рядок, але перед тим, як зателефонувати, to_sви створили число в пам'яті, яке перевищує 64 біти
durron597,

1
Це зрозуміло - і робить завдання більш складним (і цікавим)! Чи краще видалити відповідь або залишити її для інших, щоб мати приклад того, як не реалізувати завдання?
Девід Геррман

1

пітон 92 байти:

def d(a,b,c):c-=len(str(a/b))+1;e=10**c;a*=e;a/=b;a=str(a);x=len(a)-c;return a[:x]+'.'+a[x:]

я думаю, що ще кілька гольфу можливо ...


2
чи не eперевищує 64 біт для великих c? Редагувати: Я думаю, ви тут неявно використовуєте BigInteger.
durron597

1
@ durron597 я дуже сумніваюся в цьому. Він переходить до BigInt (Long in python), але 2 ** 45 - 48 біт. Хіба цього вистачає? Крім того, у пітона немає НЕ примітивів, тому ...
Малтісен

Якщо a=5і c=400потім після e=10**c, у шістнадцятковій кількості число становить 333 цифри. Починається 8889e7dd7f43fc2f7900bc2eac756d1c4927a5b8e56bbcfc97d39bac6936e648180f47d1396bc905a47cc481617c7...це більше 64 біт.
durron597

@ durron597 400 ... мені це потрібно
Малтісен

1
Так, правило 3 говорить, що вам потрібно підтримати щонайменше 500 ... Я намагався запобігти цьому (іммотривіальному) рішенню.
durron597

1

C 83

d(a,b,c){printf("%d.",a/b);for(a=abs(a),b=abs(b);c--&&(a=a%b*10);)putchar(a/b+48);}

Та сама ідея, яку я використовував у своїй реалізації python


Дуже хороша! Однак він виходить з ладуd(-2147483648,-1,10)
durron597
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.