Поліном довгий поділ


10

Реалізуйте багаточлен тривалого поділу - алгоритм, який ділить два поліноми і отримує коефіцієнт та залишок:

(12x ^ 3 - 5x ^ 2 + 3x - 1) / (x ^ 2 - 5) = 12x - 5 R 63x - 26

У своїх програмах ви представлятимете поліноми як масив, з постійним членом на хвості. наприклад, x ^ 5 - 3x ^ 4 + 2x ^ 2 - x + 1 стане [1, -3, 0, 2, -1, 1].

Функція довгого поділу, яку ви збираєтеся записати, поверне два значення: коефіцієнт і решту. Не потрібно обробляти числові неточності та арифметичні помилки. Не використовуйте математичну бібліотеку для своєї роботи, однак, ви можете зробити свою функцію здатною боротися із символічними значеннями. Найкоротший код виграє.

ПРИКЛАД: div([12, -5, 3, -1], [1, 0, -5]) == ([12, -5], [63, -26])


Відповіді:


3

J, 94

f=:>@(0&{)
d=:0{[%~0{[:f]
D=:4 :'x((1}.([:f])-((#@]{.[)f)*d);([:>1{]),d)^:(>:((#f y)-(#x)))y'

напр.

(1 0 _5) D (12 _5 3 _1;'')
63 _26 | 12  _5

Пояснення деяких фрагментів, враховуючи, що a: (12 -5 3 -1) і b: (1 0 -5)

довжина:

#a
4

зробіть a і b те саме замовлення, додавши нулі до b:

(#a) {. b
1 0 -5 0

розділити вищі сили (перші елементи) a, b:

(0{a) % (0{b)
12

помножимо b на це і віднімемо його від:

a - 12*b
12 0 _60

повторити n разів b = f (a, b):

a f^:n b

Дві речі. 1) Ви перемагаєте персонажів, отримуючи дивіденд / дільник у незвичному порядку? 2) чи потрібне те, що відставання `; '' 'у дивіденді? виглядає як щось, що ви повинні зробити всередині фактичної програми.
JB

@JB: 1) Ні, насправді це може бути коротшим для "звичайного" порядку; це просто так, як я почав думати про це. 2) Це частина масиву, тому я вважаю, що він повинен бути частиною вводу.
Енадцять

Я не можу зрозуміти, який додатковий порожній масив стосується введення.
JB

3

Python 2, 260 258 257 255 байт

exec'''def d(p,q):
 R=range;D=len(p);F=len(q)-1;d=q[0];q=[q[i]/-d@R(1,F+1)];r=[0@R(D)];a=[[0@R(F)]@R(D)]
@R(D):
  p[i]/=d;r[i]=sum(a[i])+p[i]
  for j in R(F):
   if i<D-F:a[i+j+1][F-j-1]=r[i]*q[j]
 return r[:D-F],[d*i@r[D-F:]]'''.replace('@',' for i in ')

Це виконує:

def d(p,q):
 R=range;D=len(p);F=len(q)-1;d=q[0];q=[q[i]/-d for i in R(1,F+1)];r=[0 for i in R(D)];a=[[0 for i in R(F)] for i in R(D)]
 for i in R(D):
  p[i]/=d;r[i]=sum(a[i])+p[i]
  for j in R(F):
   if i<D-F:a[i+j+1][F-j-1]=r[i]*q[j]
 return r[:D-F],[d*i for i in r[D-F:]]

Використовуйте так:

>>>d([12., -5., 3., -1.],[1.,0.,-5.])
([12.0, -5.0], [63.0, -26.0])

1
Нічого собі, перший раз, коли я бачив, як виконавець / заміна фактично використовується для збереження символів.
xnor

@xnor Я це робив один раз, але вже не одну заміну.
Джастін

2

Хаскелл, 126

Для початку:

l s _ 0=s
l(x:s)(y:t)n=x/y:l(zipWith(-)s$map(*(x/y))t++repeat 0)(y:t)(n-1)
d s t=splitAt n$l s t n where n=length s-length t+1

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

*Main> d [12, -5, 3, -1] [1, 0, -5]
([12.0,-5.0],[63.0,-26.0])

1

Javascript з лямбдами, 108

f=(a,b)=>{for(n=b.length;a.length>=n;a.shift())for(b.push(k=a[q=0]/b[0]);q<n;++q)a[q]-=k*b[q];b.splice(0,n)}

Він замінює перший аргумент нагадуванням та другий за результатом.

Приклад використання у Firefox:

f(x=[12,-5,3,-1], y=[1,0,-5]), console.log(x, y)
// Array [ 63, -26 ] Array [ 12, -5 ]

Вибачте за помилку. Вже виправлено.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.