Візуалізуйте довгий поділ за допомогою мистецтва ASCII


16

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

Приклади:

1234 ÷ 56:

     22
   ----
56|1234
   112
   ---
    114
    112
    ---
      2

1002012 ÷ 12:

     83501
   -------
12|1002012
    96
   ---
     42
     36
     --
      60
      60
      --
        12
        12
        --

0 ÷ 35

   0
   -
35|0

Правила:

  • Використання оператора ділення мови програмування в це дозволено.
  • Використання великої цілої підтримки також дозволено.
  • Для послідовності:
    • Якщо коефіцієнт дорівнює нулю, надрукуйте один кінець нуля в кінці дайвінг-дошки.
    • Якщо залишок дорівнює нулю, не друкуйте його.
    • Не друкуйте провідні нулі на жодних номерах.
  • Зайві нові рядки в кінці та пробіли праворуч дозволені.
  • Рішення з найменшими символами виграє.

Обмеження:

  • 0 <= чисельник <= 10 72 - 1
  • 1 <= знаменник <= 9999999

Це означає, що вихід ніколи не буде ширшим за 80 стовпців.

Тестовий набір та реалізація вибірки:

Ви можете використовувати long-Division.c ( gist ) для тестування програми. Це насправді баш-скрипт із програмою C всередині. Налаштуйте його, щоб викликати свою програму в тестовому наборі. Подивіться на код C внизу, щоб побачити реалізацію посилань. Будь ласка, повідомте мені, чи є якісь проблеми із зразком програми або тестовим набором.

$ ./long-division.c 10 7
   1
  --
7|10
   7
  --
   3
$ ./long-division.c
PASS 1234 ÷ 56
PASS 1002012 ÷ 12
PASS 1 ÷ 1
--- snip ---

Score: 35 / 35
All tests passed!

Змінити: За бажанням, я поставив набір тестів введення і очікувані результати в текстові файли ( GIST ). Використання зразка (bash):

cat input | while read nd; do
    ./program $nd |
        sed 's/\s*$//' | sed -e :a -e '/^\n*$/{$d;N;};/\n$/ba'
done > output

diff -u expected output

Дивні команди sed відфільтровують нові результати та пробіли з результатів програми.


Я виявив незначний недолік у еталонній реалізації, а саме у випадку 123000123000123 ÷ 123. Лінії віднімання охоплювали порожній простір, але вони повинні бути лише на довжину видимих ​​цифр мінусу. Це зараз виправлено.
Джої Адамс

2
Я думаю, що вихід трохи упереджений до англомовної аудиторії гольфу: en.wikipedia.org/wiki/…
hallvabo

Чи можете ви просто створити файл, який показує очікуваний вихід усіх тестів і посилається на нього?
mellamokb

@mellamokb: Додано, дякую!
Joey Adams

Що з прийняттям? Питання досить старе ...
Олег Припін

Відповіді:


3

Python 3, 284 257 символів

div.py

n,t=input().split()
d=int(t)
l=lambda x:len(str(x))
s=l(n)
def p(x):print(' '*(l(d)+s-l(x)+1)+str(x))
p(int(n)//d)
p('-'*s)
p(t+'|'+n)
s=z=f=0
while t:
 try:
  while z<d:z=z*10+int(n[s]);s+=1
 except:t=0
 if z*f:p(z)
 if t:f=1;t=z//d*d;p(t);p('-'*l(z));z-=t

Використання: python3 div.py
Введення: з клавіатури

test.py

import sys
sys.stdin=open('input'); sys.stdout=open('output','w')
for line in open('input'): exec(open('div.py').read())

вихідні матчі очікується

Версії:
 1. 284
 2. 257 : s,z,f=0,0,0s=z=f=0; z and fz*f; краща петля; видалено кілька нових рядків.


2
ви можете спробувати ideone для python3 та input - ideone.com/clone/ZZyzu
ВАС

3

Haskell, 320 символів

l=length
(®)=replicate
p!v=p&show v
p&s=(p-l s)®' '++s
0§_=[];_§l=l
d[m,n]=l c!(read m`div`e):l c&(l m®'-'):c:drop 1(g 0(map(toInteger.fromEnum)m)$1+l n)where
 e=read n;c=n++'|':m
 g r(d:z)p=i§[o!k,o!(i*e),o&(l(show k)®'-')]++g j z o where k=r*10+d-48;(i,j)=k`divMod`e;o=1+p
 g r[]p=r§[p!r]
main=interact$unlines.d.words

Проходить усі тести. Хоча цей гарний гольф - я думаю, що ще потрібно зробити ще багато ...


  • Редагувати: (344 -> 339) затримка readвикликів, що зменшує потребу в дзвінках show, достатньо скороченняshow , як sне варто.
  • Редагувати: (339 -> 320) переписати функції форматування рядкових рядків

Акуратно! Я зробив рішення Haskell з 344 символами, але не опублікував. Крім того, я не знав, що ви можете використовувати символи Unicode для операторів (без -XUnicodeSyntax).
Джої Адамс

3

JavaScript (400 394 418 )

function d(n,d){t=parseInt;p=function(v){return(s+v).substring(v.length)};a=function(v,c){return v.replace(/\d/g,c)};w='\n';q=b=o=c=e='';s=a(d,' ')+' ';f=true;i=-1;z='0';while(++i<n.length){s+=' ';if(t(c+=n[i])>=t(d)){q+=r=Math.floor(t(c)/t(d));o+=(!f?p(c)+w:e)+p(''+r*t(d))+w+p(a(c,'-'))+w;c=t(c)%t(d);f=false}else if(!f){q+=z;}c=(c==0)?e:e+c}return p(!q?z:q)+w+p(a(n,'-'))+w+d+'|'+n+w+o+(q?p(c):e)}

ПРИМІТКА. Настільки ж спокусливо, як здається, поголити кілька символів замінивши c=(c==0)? з c=!c?, не використовується , оскільки це призводить до плаваючою точкою помилки , пов'язані з .

http://jsfiddle.net/nLzYW/9/

Виконання зразка:

document.writeln("<pre>");
document.writeln(d("1234","56"));
document.writeln();
document.writeln(d("1002012","12"));
document.writeln();
document.writeln(d("0","35"));
document.writeln();
document.writeln(d("123000123000123","123"));
document.writeln("</pre>");

Редагуйте 1 : Невеликі виправлення помилок, численні оптимізації коду.

Редагувати 2 : Виправити помилку за допомогою 1/7 отримання додаткового результату.


Тестовий сценарій виявив одну проблему. d(1,7)(і подібні тести) повторюйте знаменник, а не друкуйте нічого. Це неправильно, оскільки це число повинно бути коефіцієнтом, кратним знаменнику, що дорівнює нулю.
Joey Adams

Усі тести проходять зараз.
Joey Adams

1

Javascript: (372)

function g(a){for(var c="",e=0;e<a;e++)c=" "+c;return c}function i(a,c){for(var e=a+"/"+c+"\\",j=(""+c).split(""),k="",d=0,b=0;b<j.length;b++){d*=10;d+=parseInt(j[b],10);var f=d>9?b-1:b,h=0;h=Math.floor(d/a);d%=a;f=g(f+a.toString().split("").length);f+=h*a+"\n"+g(b+a.toString().split("").length)+"--\n"+g(b+a.toString().split("").length)+d+"\n";k+=f;e+=h}return e+"\n"+k}

Викликати за допомогою i (дільник, число). Codegolfed JS: http://jsfiddle.net/puckipedia/EP464/ Ungolfed (голландський) JS: http://jsfiddle.net/puckipedia/M82VM/

Повертає довгий поділ (у голландському форматі, як я його вивчив):

5/25\05
 0
 --
 2
 25
  --
  0

Тестова шафа:

document.write("<pre>"+i(5,25)+"</pre>");
document.write("<pre>"+i(7,65669726752476)+"</pre>");

Гей, це не так, як потрібно!
Олег Припін

@BlaXpirit Я знаю, я дізнався це саме так.
puckipedia

Цікаво. Хоча як говорить @BlaXpirit, це не відповідає специфікації. Спеціалізація має бути справедливим стандартом порівняння для визначення ефективності коду з гольф-кодом, тому ви не можете довільно змінити специфікацію, навіть якщо ви не згодні з вихідним форматом :)
mellamokb
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.