Đơn giản hóa và lấy đạo hàm từng phần thành một chuỗi đa thức


8

Giới thiệu

Viết chương trình tính đạo hàm riêng của một đa thức (có thể là đa biến) đối với một biến.

Thử thách

Đạo hàm là các công cụ toán học rất quan trọng đã được áp dụng rộng rãi trong vật lý, hóa học, sinh học, kinh tế, tâm lý học và nhiều hơn nữa để xử lý tất cả các loại vấn đề. Biểu thức có nhiều biến cũng rất phổ biến.

Trong phạm vi của thử thách này, một chuỗi đa thức ("polystr") được xác định bởi BNF (dạng Backus giật Naur sau):

<polystr> ::= <term> | <term><plusminus><polystr>

<plusminus> ::= "+" | "-"

<term> ::= <coeff> | <coeff><baseterm> | <baseterm>

<baseterm> ::= <variable> | <variable><exponent> | <baseterm><baseterm>

<coeff> ::= positive_integer

<exponent> ::= positive_integer

<variable> ::= lowercase_ASCII_letters

Ở đâu positive_integerlowercase_ASCII_letterskhá tự giải thích.

Ví dụ: Chuỗi 3x2y-x3y-x2y+5có nghĩa 3*(x^2)*y-(x^3)*y-(x^2)*y+5. Các thuật ngữ được đưa ra trong đầu vào có thể xuất hiện theo bất kỳ thứ tự nào và các biến trong mỗi thuật ngữ cũng có thể xuất hiện theo bất kỳ thứ tự nào. Vì vậy, ví dụ 5-yx2-x3y+y3x2cũng là một đầu vào hợp lệ và trên thực tế giống như ví dụ trước.

Quy tắc để lấy đạo hàm một phần chỉ là thực hiện theo thuật ngữ. Nếu biến xuất hiện không xuất hiện trong thuật ngữ, đạo hàm bằng không. Mặt khác, hệ số của số hạng được nhân với số mũ của biến đó và sau đó số mũ của biến bị giảm đi một. Số mũ của các biến khác không thay đổi. Đây chỉ là theo định nghĩa trong toán học. Ngoài ra, nếu số mũ kết quả bằng 0, loại bỏ biến khỏi thuật ngữ.

Ví dụ, để lấy đạo hàm một phần 5z-z2y2-5w3yđối với y. Quá trình sau đây được thực hiện (theo BNF được xác định ở trên, "hệ số" đều được coi là số dương, tức là các dấu hiệu được xem xét riêng)

          5z          -   z2y2        - 5w3y

Coeff                 1->1*2=2      5->5*1=5
Expon                 2->2-1=1      1->1-1=0
Term                  -   2yz2         - 5w3 
      (y is not here            (expon 0->y removed)
     so the term is 0)

Kết quả là -2yz2-5w3y.

Mặt khác, nếu biểu thức trên được lấy đạo hàm một phần đối với a, kết quả là 0akhông có trong các điều khoản.

Nhiệm vụ của bạn là viết một hàm hoặc một chương trình đầy đủ để tính đạo hàm này. Nó nên lấy một chuỗi đa thức và một ký tự đơn (biến để lấy đạo hàm đối với) và trả về đạo hàm ở dạng đơn giản nhất.

"Hình thức đơn giản nhất" có nghĩa là ba điều.

  1. Số 0(không phải chữ số) sẽ không xuất hiện trong đầu ra trừ khi chính đầu ra chỉ là 0. Vì vậy, cũng không 0+10yphải 3-y0zlà đầu ra hợp lệ và nên được chuyển đổi thành 10y3-z, tương ứng.

  2. Số 1không được xuất hiện dưới dạng số mũ hoặc hệ số, nhưng có thể xuất hiện dưới dạng một thuật ngữ độc lập.

  3. Các thuật ngữ với chính xác cùng một bộ biến và số mũ nên được hợp nhất, có nghĩa 3a2b5-4b5a2là không phải là một đầu ra hợp lệ, và nó nên được -a2b5thay thế. Thông tin thêm về đầu vào và đầu ra có thể được tìm thấy trong phần "Thông số kỹ thuật".

Các trường hợp thử nghiệm

Input
Output

2xy+4ax-5+7mx4-4-7x4m, x
2y+4a

4upv+5u2v3w4-4w4u2v3+qr-v,v
4up+3u2v2w4-1

12ux-7x2m3+ab5,q
0

-a+10ca11y-1nv3rt3d-poly, a
-1+110ca10y

1y+1x3y, y
1+x3

Thông số kỹ thuật

  • Đầu vào có thể được thực hiện thông qua các hình thức tiêu chuẩn . Nói cách khác, bạn có thể lấy đầu vào là một chuỗi, một danh sách các ký tự, một mảng các hệ số, các biến (có thể được biểu thị bằng giá trị ASCII của chúng trừ đi 'a' hoặc một cái gì đó giống nhau) và số mũ, v.v. chuỗi đến 2*x^3y^2hoặc giống nhau thay vì 2x3y2.

Tuy nhiên, vui lòng không sử dụng đầu vào [2,0,0,0,1,0,0,3,0,0,...0](một mảng gồm 27 phần tử) cho thuật ngữ 2dghoặc bất kỳ định dạng dài dòng nào khác liệt kê 26 chữ cái như thế này. Định dạng đầu vào của bạn cũng sẽ có thể xử lý abbanhư các đầu vào khác nhau (vì vậy định dạng mảng 27 phần tử không hợp lệ do hạn chế này là tốt).

  • Mỗi biến số (chữ cái) sẽ chỉ xuất hiện một lần trong mỗi thuật ngữ của đầu vào, điều đó có nghĩa là xxsẽ không xuất hiện và sẽ luôn được trình bày dưới dạng x2, cũng như sẽ a3b4a2xuất hiện một cái gì đó giống như .

  • Để nhắc lại, các điều khoản trong đầu vào có thể xuất hiện theo bất kỳ thứ tự nào.

  • Bạn cũng có thể tự do chọn định dạng đầu ra với điều kiện tránh định dạng dài dòng được đề cập ở trên. Tuy nhiên, đầu ra phải luôn ở dạng đơn giản nhất như được định nghĩa ở trên. Giống như đầu vào, các thuật ngữ trong đầu ra có thể xuất hiện theo bất kỳ thứ tự nào và các biến trong mỗi thuật ngữ cũng có thể xuất hiện theo bất kỳ thứ tự nào và không nhất quán giữa các thuật ngữ. Điều đó có nghĩa pu+2up2là một đầu ra hợp lệ. Dấu hiệu cho thuật ngữ hàng đầu có thể là tích cực hay tiêu cực và -y+3x3x-yđều có giá trị, như vậy là +3x-y.

  • Đầu vào luôn được cung cấp sao cho tất cả các hệ số và số mũ trong đầu ra sẽ nhỏ hơn 2 32 -1 hoặc số nguyên lớn nhất mà ngôn ngữ của bạn có thể xử lý, tùy theo giá trị nào nhỏ hơn. Khẳng định rằng số nguyên lớn nhất mà ngôn ngữ của bạn có thể xử lý là nhỏ một cách vô lý và tầm thường hóa thách thức rơi vào loại lỗ hổng mặc định.

  • Đây là , số byte thấp nhất sẽ thắng.

  • Như thường lệ, sơ hở mặc định áp dụng ở đây.

Chỉnh sửa: Vì hầu hết các câu trả lời cho đến nay đều trở thành nội bộ thực hiện toàn bộ thử thách và mặc dù biết rằng có các nội dung, tôi không có ý định cấm các nội bộ đó ngay từ đầu, hiện tại tôi cũng không có. Tôi sẽ đặt tiêu chí chiến thắng dựa trên cơ sở cho mỗi ngôn ngữ, tức là bài nộp có ít byte nhất trong mỗi ngôn ngữ sẽ thắng trong ngôn ngữ đó. Tôi sẽ thêm một đoạn tiêu chuẩn cho một danh mục nếu có đủ bài nộp. Vui lòng tiếp tục gửi nội dung để thể hiện sức mạnh của ngôn ngữ của bạn nhưng xin vui lòng gửi câu trả lời không tích hợp của bạn ngay cả khi nó dài hơn và ngôn ngữ của bạn không có nội dung. Chúc mừng mã golf trong ngôn ngữ yêu thích của bạn!


@JonathanFrech Thuật ngữ thứ hai và thứ ba trong đầu vào có thể được hợp nhất. Họ cùng nhau đưa ra thuật ngữ thứ hai trong đầu ra.
Weijun Zhou

À được rồi. Trong ví dụ đầu tiên của bạn, tại sao -9xuất hiện trong đầu ra?
Jonathan Frech

1
Lý do duy nhất bạn có thể hợp nhất trong đầu ra là vì đầu vào đã có thể được hợp nhất. Điều đó làm cho điều này thực sự là sự kết hợp của 2 vấn đề độc lập take derivativemerge
TonMedel

Tôi giả sử hình thức đơn giản nhất cũng ngụ ý no exponent 1, mặc dù bạn dường như không nói rõ điều này
TonMedel

@JonathanFrech Đó là một lỗi đánh máy. Đã sửa.
Weijun Zhou

Câu trả lời:


2

Python 2 , 252 245 byte

o,d=input()
D={};s=''
for c,t in o:T=`sorted(t)`;D[T]=D.get(T,0)+c
for t in D:
 c,t=D[t],dict(eval(t))
 if(d in t)*c:e=t[d];c*=e;t[d]=e-1;s+=('%+d '%c)[:~((-2<c<2)*sum(t.values())>0)]+''.join((v+`t[v]`*(t[v]>1))*(t[v]>0)for v in t)
print s or'0'

Hãy thử trực tuyến!

Đưa đầu vào dưới dạng danh sách các hệ số và thuật ngữ lồng nhau:

[
 [coeff1, [[var1_1,exp1_1],
           [var1_2,exp1_2],
           ... ]
 ],
 [coeff2, [[var2_1,exp2_1], ...]],
 ...
]

Ví dụ, ví dụ đầu tiên ( 5z-z2y2-5w3y) được đưa ra là:

[
 [ 5, [['z', 1]          ] ], 
 [-1, [['z', 2], ['y', 2]] ],
 [-5, [['w', 3], ['y', 1]] ]
]

Chân trang chứa một chức năng phân tích cú pháp đầu vào chuỗi thành định dạng đầu vào mong muốn : parse(s).


Biên tập:

  • Đưa đầu vào thay vì chức năng

2

Võng mạc , 249 233 byte

(.)(?=.*¶\1$)
$&_
L`.\w*
G`_
^\b
+
%O`._?\d*
_\d+
*
\b[a-z]
1$&
\b(\d+)(?=.*?(_+))
$1*$2
O$`(.)_+(.+)
$2$1
+`((\+|-)_+)(.*)¶\2(_+\3)\b
$1$4
+`\+_(_*(.*)¶-)_(_*\2\b)
+$1$3
G`\b_
\b_+
$.&
_(__+)
$.1
^\+|¶|(.)__|._
$1
\b1([a-z])
$1
^$
0

Hãy thử trực tuyến! Liên kết bao gồm các trường hợp thử nghiệm. Giải trình:

(.)(?=.*¶\1$)
$&_

Thêm một _sau mỗi lần xuất hiện của biến đã cho.

L`.\w*

Chia đầu vào thành các điều khoản.

G`_

Chỉ giữ các thuật ngữ tham chiếu biến.

^\b
+

Tiền tố a +nếu thuật ngữ đầu tiên không có dấu hiệu.

%O`._?\d*

Sắp xếp từng thuật ngữ theo thứ tự abc. (Dấu hiệu khớp, nhưng đó không phải là vấn đề; dù sao thì nó cũng sắp xếp ngay từ đầu.)

_\d+
*

Chuyển đổi tất cả các số mũ của biến thành unary.

\b[a-z]
1$&

Tạm thời tiền tố 1 cho các điều khoản mà không có số nhân.

\b(\d+)(?=.*?(_+))
$1*$2

Nhân số nhân với số mũ của biến, để lại kết quả là đơn nhất.

O$`(.)_+(.+)
$2$1

Sắp xếp tất cả các điều khoản.

+`((\+|-)_+)(.*)¶\2(_+\3)\b
$1$4

Thêm các điều khoản của cùng một dấu hiệu.

+`\+_(_*(.*)¶-)_(_*\2\b)
+$1$3

Trừ các điều khoản của các dấu hiệu khác nhau.

G`\b_

Xóa các điều khoản đã bị hủy bởi một điều khoản của một dấu hiệu khác.

\b_+
$.&

Chuyển đổi số nhân trở lại thập phân.

_(__+)
$.1

Số mũ giảm dần lớn hơn ba và chuyển đổi thành số thập phân.

^\+|¶|(.)__|._
$1

a) Xóa một +dấu hiệu hàng đầu b) Nối tất cả các thuật ngữ lại với nhau c) chuyển đổi bình phương của biến thành biến đơn giản d) xóa biến nếu nó không có số mũ.

\b1([a-z])
$1

Xóa 1 tạm thời trừ khi nó không còn có gì để nhân lên.

^$
0

Nếu không có điều khoản còn lại thì kết quả bằng không.

Hỗ trợ các thuật ngữ trùng lặp tốn gần một nửa số byte của tôi. Giải pháp 123 byte trước đó không lặp lại các điều khoản:

(.)(?=.*¶\1$)
$&_
L`.\w*
G`_
_\d+
*
\b[a-z]
1$&
\b(\d+)(?=.*?(_+))
$.($1*$2
_(__+)
$.1
^\+|¶|(.)__|._
$1
\b1([a-z])
$1
^$
0

Hãy thử trực tuyến! Giải trình:

(.)(?=.*¶\1$)
$&_

Thêm một _sau mỗi lần xuất hiện của biến đã cho.

L`.\w*

Chia đầu vào thành các điều khoản.

G`_

Chỉ giữ các thuật ngữ tham chiếu biến.

_\d+
*

Chuyển đổi tất cả các số mũ của biến thành unary.

\b[a-z]
1$&

Tạm thời tiền tố 1 cho các điều khoản mà không có số nhân.

\b(\d+)(?=.*?(_+))
$.($1*$2

Nhân số nhân với số mũ của biến.

_(__+)
$.1

Số mũ giảm dần lớn hơn ba và chuyển đổi thành số thập phân.

^\+|¶|(.)__|._
$1

a) Xóa một +dấu hiệu hàng đầu b) Nối tất cả các thuật ngữ lại với nhau c) chuyển đổi bình phương của biến thành biến đơn giản d) xóa biến nếu nó không có số mũ.

\b1([a-z])
$1

Xóa 1 tạm thời trừ khi nó không còn có gì để nhân lên.

^$
0

Nếu không có điều khoản còn lại thì kết quả bằng không.


Ấn tượng, nhưng bạn cần hợp nhất hai thuật ngữ đó trong ví dụ TIO của bạn.
Weijun Zhou

1
@ WeijunZhou Xin lỗi, tôi đã bỏ qua một chút thông số kỹ thuật. Hãy để tôi suy nghĩ về nó ...
Neil

@ WeijunZhou Ugh, nó tiêu tốn của tôi quá nhiều byte, nhưng tôi nghĩ rằng tôi đã làm cho nó hoạt động.
Neil

Cảm ơn bạn rất nhiều vì công việc khó khăn ấn tượng của bạn. Tôi đoán đây là một điểm tốt để tôi bắt đầu học Retina từ đó.
Weijun Zhou


0

Physica , 3 byte

Điều này không sử dụng bất kỳ tính năng mới. và thay thế chỉ ASCII của nó, Differentiateđã được giới thiệu hơn 10 ngày trước .

Bản giới thiệu

Giả sử rằng cả biểu thức và biến được truyền dưới dạng một chuỗi. Mã kiểm tra:

f = ∂

Print[f['2*x*y+4*a*x-5+7*m*x^4-4-7*x^4*m'; 'x']]
Print[f['4*u*p*v+5*u^2*v^3*w^4-4*w^4*u^2*v^3+q*r-v'; 'v']]
Print[f['-a+10*c*a^11*y-1*n*v^3*r*t^3*d-p*o*l*y'; 'a']]

Đầu ra chính xác:

4*a + 2*y
4*p*u + 3*u**2*v**2*w**4 - 1
110*a**10*c*y - 1

Định dạng biểu thức: *cho phép nhân, **cho phép lũy thừa +-cộng và trừ tương ứng.

Physica - Trình diễn trực quan



Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.