Phân biệt biểu tượng của đa thức


20

Sự khác biệt tượng trưng 1: Đã qua Coefishin '

Bài tập

Viết chương trình lấy đa thức theo x từ stdin (1 <deg (p) <128) và phân biệt nó. Đa thức đầu vào sẽ là một chuỗi có dạng sau:

"a + bx + cx^2 + dx^3 +" ...

trong đó hệ số của mỗi số hạng là một số nguyên (-128 <a <128). Mỗi thuật ngữ được phân tách bằng một khoảng trắng, dấu + và khoảng trắng khác; tuyến tính và các điều khoản liên tục xuất hiện như trên (nghĩa là không x^0hay x^1). Các điều khoản sẽ xuất hiện theo thứ tự tăng dần và những quyền hạn có hệ số 0 được bỏ qua. Tất cả các thuật ngữ có hệ số 1 hoặc -1 hiển thị rõ ràng hệ số đó.

Đầu ra của bạn phải có cùng một hình thức. Lưu ý rằng các hệ số trong đầu ra có thể lớn bằng 127 * 127 == 16129.

Ví dụ

"3 + 1x + 2x^2" ==> "1 + 4x"
"1 + 2x + -3x^2 + 17x^17 + -1x^107" ==> "2 + -6x + 289x^16 + -107x^106"
"17x + 1x^2" ==> "17 + 2x"

Chấm điểm

Điểm của bạn là độ dài chương trình của bạn tính bằng byte, nhân với ba nếu bạn sử dụng một thư viện tích hợp hoặc thư viện có đại số tượng trưng.


Tôi không thể tin rằng chúng tôi chưa có thử thách này ở đây!
flawr

5
@flawr Chúng tôi sắp xếp. (Mặc dù điều đó cũng yêu cầu các chức năng khác và không có quy tắc nghiêm ngặt về định dạng đầu ra.)
Martin Ender

@flawr Tôi cũng nghĩ như vậy ... nhưng tôi không tìm thấy bài đăng liên kết của Martin. À
hYPotenuser

Câu trả lời:


15

Võng mạc , 53 43 42 41 40 35 byte

^[^x]+ |(\^1)?\w(?=1*x.(1+)| |$)
$2

Để đếm các mục đích, mỗi dòng đi trong một tệp riêng biệt, nhưng bạn có thể chạy ở trên dưới dạng một tệp bằng cách gọi Retina bằng -scờ.

Điều này hy vọng các số trong chuỗi đầu vào sẽ được đưa ra một cách đơn nhất và sẽ mang lại đầu ra ở cùng định dạng. Ví dụ

1 + 11x + -111x^11 + 11x^111 + -1x^11111
-->
11 + -111111x + 111111x^11 + -11111x^1111

thay vì

1 + 2x + -3x^2 + 2x^3 + -1x^5
-->
2 + -6x + 6x^2 + -5x^4

Giải trình

Mã này mô tả một sự thay thế regex duy nhất, về cơ bản là 4 sự thay thế được nén thành một. Lưu ý rằng chỉ một trong các nhánh sẽ điền vào nhóm $2vì vậy nếu bất kỳ một trong ba trận đấu còn lại, trận đấu sẽ chỉ bị xóa khỏi chuỗi. Vì vậy, chúng ta có thể xem xét bốn trường hợp khác nhau một cách riêng biệt:

^[^x]+<space>
<empty>

Nếu có thể đạt đến một khoảng trắng từ đầu chuỗi mà không gặp phải xđiều đó có nghĩa là thuật ngữ đầu tiên là thuật ngữ không đổi và chúng tôi xóa nó. Do sự tham lam của +, điều này cũng sẽ phù hợp với không gian cộng và không gian thứ hai sau thời hạn không đổi. Nếu không có thuật ngữ không đổi, phần này sẽ không bao giờ khớp.

x(?= )
<empty>

Điều này khớp với xmột không gian được theo sau bởi một khoảng trắng, tức là xthuật ngữ tuyến tính (nếu nó tồn tại) và loại bỏ nó. Chúng ta có thể chắc chắn rằng có một khoảng trắng sau nó, bởi vì mức độ của đa thức luôn luôn ít nhất là 2.

1(?=1*x.(1+))
$1

Điều này thực hiện phép nhân hệ số theo cấp số nhân. Điều này khớp với một 1hệ số duy nhất và thay thế nó bằng toàn bộ số mũ tương ứng thông qua giao diện.

(\^1)?1(?= |$)
<empty>

Điều này làm giảm tất cả các số mũ còn lại bằng cách khớp với dấu 1(được đảm bảo bởi giao diện). Nếu có thể khớp ^11(và một ranh giới từ), chúng ta sẽ loại bỏ thay vào đó, điều này sẽ giúp hiển thị chính xác thuật ngữ tuyến tính.

Đối với việc nén, chúng tôi nhận thấy rằng hầu hết các điều kiện không ảnh hưởng lẫn nhau. (\^1)?Sẽ không khớp nếu cái nhìn trong trường hợp thứ ba là đúng, vì vậy chúng ta có thể đặt hai cái đó lại với nhau như

(\^1)?1(?=1*x.(1+)| |$)
$2

Bây giờ chúng ta đã có giao diện cần thiết cho trường hợp thứ hai và những trường hợp khác không bao giờ có thể đúng khi khớp x, vì vậy chúng ta có thể chỉ cần khái quát hóa 1cho a \w:

(\^1)?\w(?=1*x.(1+)| |$)
$2

Trường hợp đầu tiên không thực sự có điểm chung với những người khác, vì vậy chúng tôi giữ nó tách biệt.


9

CJam, 43 41 byte

Qleu'^/';*'+/{~:E[*'x['^E(]]E<}/]1>" + "*

Cảm ơn @ jimmy23013 vì đã chỉ ra một lỗi và đánh bại hai byte!

Hãy thử trực tuyến trong trình thông dịch CJam .

Làm thế nào nó hoạt động

Q           e# Leave an empty array on the bottom of the stack.
l           e# Read a line from STDIN.
eu'^/';*    e# Convert to uppercase and replace carets with semicolons.
'+/         e# Split at plus signs.

{           e# For each resulting chunk:
  ~         e#   Evaluate it. "X" pushes 1 and ";" discards.
            e#   For example, "3X" pushes (3 1) and "3X;2" (3 2).
   :E       e#   Save the rightmost integer (usually the exponent) in E.
   [        e#
     *      e#   Multiply both integers.
            e#   For a constant term c, this repeats the empty string (Q) c times.
     'x     e#   Push the character 'x'.
     ['^E(] e#   Push ['^' E-1].
   ]        e#
   E<       e#  Keep at most E elements of this array.
            e#  If E == 1, 'x' and ['^' E-1] are discarded.
            e#  If E == 2, ['^' E-1] is discarded.
            e#  If E >= 3, nothing is discarded.
}/          e#

]           e# Wrap the entire stack in an array.
1>          e# Discard its first element.
            e# If the first term was constant, this discards [""]. ["" 'x']
            e# or ["" 'x' ['^' E-1]], depending on the constant.
            e# In all other cases, it discards the untouched empty array (Q).
" + "*      e# Join all kept array elements, separating by " + ".

5

Perl, 64 63 byte

Mã 62b + 1 dòng lệnh (-p)

Không tuyệt vời vào lúc này, nhưng tôi sẽ tiếp tục cố gắng rút ngắn nó.

s/(\d+)x.(\d+)/$1*$2."x^".($2-1)/eg;s/\^1\b|^\d+ . |x(?!\^)//g

Ví dụ sử dụng:

echo "1 + 2x + 3x^2" | perl -pe 's/(\d+)x.(\d+)/$1*$2."x^".($2-1)/eg;s/\^1\b|^\d+ . |x(?!\^)//g'

Cảm ơn Denis vì -1b


5

Julia, 220 byte

Không có biểu thức chính quy!

y->(A=Any[];for i=parse(y).args[2:end] T=typeof(i);T<:Int&&continue;T==Symbol?push!(A,1):(a=i.args;c=a[2];typeof(a[3])!=Expr?push!(A,c):(x=a[3].args[3];push!(A,string(c*x,"x",x>2?string("^",ex-1):""))))end;join(A," + "))

Điều này tạo ra một hàm lambda chấp nhận một chuỗi và trả về một chuỗi. Các bộ phận bắt chước những gì xảy ra khi mã Julia được đánh giá: một chuỗi được phân tách thành các ký hiệu, biểu thức và các cuộc gọi. Tôi thực sự có thể thử viết một hàm phân biệt biểu tượng đầy đủ của Julia và gửi nó để trở thành một phần của Julia.

Ungolfed + giải thích:

function polyderiv{T<:AbstractString}(y::T)

    # Start by parsing the string into an expression
    p = parse(y)

    # Define an output vector to hold each differentiated term
    A = Any[]

    # Loop through the elements of p, skipping the operand
    for i in p.args[2:end]

        T = typeof(i)

        # Each element will be an integer, symbol, or expression.
        # Integers are constants and thus integrate to 0. Symbols
        # represent x alone, i.e. "x" with no coefficient or
        # exponent, so they integrate to 1. The difficulty here
        # stems from parsing out the expressions.

        # Omit zero derivatives
        T <: Int && continue

        if T == Symbol
            # This term will integrate to 1
            push!(A, 1)
        else
            # Get the vector of parsed out expression components.
            # The first will be a symbol indicating the operand,
            # e.g. :+, :*, or :^. The second element is the
            # coefficient.
            a = i.args

            # Coefficient
            c = a[2]

            # If the third element is an expression, we have an
            # exponent, otherwise we simply have cx, where c is
            # the coefficient.
            if typeof(a[3]) != Expr
                push!(A, c)
            else
                # Exponent
                x = a[3].args[3]

                # String representation of the differentiated term
                s = string(c*x, "x", x > 2 ? string("^", x-1) : "")

                push!(A, s)
            end
        end
    end

    # Return the elements of A joined into a string
    join(A, " + ")
end

3

C, 204 162 byte

#define g getchar()^10
h,e;main(c){for(;!h&&scanf("%dx%n^%d",&c,&h,&e);h=g?g?e?printf(" + "):0,0:1:1)e=e?e:h?1:0,e?printf(e>2?"%dx^%d":e>1?"%dx":"%d",c*e,e-1):0;}

Về cơ bản phân tích từng thuật ngữ và in ra các thuật ngữ khác biệt theo trình tự. Khá đơn giản.


2

JavaScript ES6, 108 byte

f=s=>s.replace(/([-\d]+)(x)?\^?(\d+)?( \+ )?/g,(m,c,x,e,p)=>x?(c*e||c)+(--e?x+(e>1?'^'+e:''):'')+(p||''):'')

Đoạn trích ES5:

// ES5 version, the only difference is no use of arrow functions.
function f(s) {
  return s.replace(/([-\d]+)(x)?\^?(\d+)?( \+ )?/g, function(m,c,x,e,p) {
    return x ? (c*e||c) + (--e?x+(e>1?'^'+e:''):'') + (p||'') : '';
  });
}

[
  '3 + 1x + 2x^2',
  '1 + 2x + -3x^2 + 17x^17 + -1x^107',
  '17x + 1x^2'
].forEach(function(preset) {
  var presetOption = new Option(preset, preset);
  presetSelect.appendChild(presetOption);
});

function loadPreset() {
  var value = presetSelect.value;
  polynomialInput.value = value;
  polynomialInput.disabled = !!value;
  showDifferential();
}

function showDifferential() {
  var value = polynomialInput.value;
  output.innerHTML = value ? f(value) : '';
}
code {
  display: block;
  margin: 1em 0;
}
<label for="presetSelect">Preset:</label>
<select id="presetSelect" onChange="loadPreset()">
  <option value="">None</option>
</select>
<input type="text" id="polynomialInput"/>
<button id="go" onclick="showDifferential()">Differentiate!</button>
<hr />
<code id="output">
</code>


2

Python 2, 166 byte

Chàng trai, điều này có vẻ dài hơn nó nên được.

S=str.split
def d(t):e="^"in t and int(S(t,"^")[1])-1;return`int(S(t,"x")[0])*(e+1)`+"x"[:e]+"^%d"%e*(e>1)
print" + ".join(d(t)for t in S(raw_input()," + ")if"x"in t)

Hàm dlấy một số hạng không đổi tvà trả về đạo hàm của nó. Lý do tôi defchức năng thay vì sử dụng lambda là vì vậy tôi có thể gán số mũ trừ 1 cho số eđó, sau đó được sử dụng bốn lần nữa. Điều khó chịu chính là phải truyền qua lại giữa các chuỗi và ints, mặc dù toán tử backtick của Python 2 giúp điều đó.

Sau đó, chúng tôi chia đầu vào thành các thuật ngữ và gọi dtừng từ có "x"trong đó, do đó loại bỏ các thuật ngữ không đổi. Các kết quả được nối lại với nhau và được in.


2

CJam, 62 57 55 49 byte

Chà, Dennis khiến điều này trở nên xấu hổ trước khi tôi nhận thấy rằng trang web đã được sao lưu. Nhưng dù sao đây cũng là sáng tạo của tôi:

lS/{'x/:T,({T~1>:T{~T~*'xT~(:T({'^T}&}&" + "}&}/;

Phiên bản mới nhất lưu một vài byte với các phím tắt được đề xuất bởi @Dennis (sử dụng các biến và phân tách tại không gian thay vì +).

Dùng thử trực tuyến


1
Lưu trong một biến ngắn hơn popping trong khối khác. Ví dụ, _({'^a\}{;}?dài hơn 1 byte :T({T'^a\}&.
Dennis

1
Nếu bạn phân tách tại các khoảng trắng thay vì dấu cộng, bạn không cần ~khối còn lại và cũng có thể loại bỏ dấu đó.
Dennis

@Dennis Điều đó hoạt động, cảm ơn. Ban đầu tôi muốn loại bỏ các dấu cộng, nhưng dù sao chúng cũng bỏ đi khi tôi kiểm tra sự hiện diện của x. Tôi tìm thấy một số cải tiến hơn trong khi tôi đang ở đó. Hầu hết, vì bây giờ tôi có các giá trị trong các biến, tôi có thể nhớ chúng ở nơi tôi thực sự cần chúng, lưu một số thao tác ngăn xếp. Tôi cũng đã có một asự cố nên bị xóa khi tôi tối ưu hóa việc tạo đầu ra trước đó.
Reto Koradi

1

Bình thường, 62 byte

jJ" + "m::j"x^",*Fdted"x.1$"\x"x.0"kftTmvMcd"x^"c:z"x ""x^1 "J

Giải pháp khá xấu xí, sử dụng một số thay thế regex.


1

Python 3, 176 byte

s=input().split(' + ')
y='x'in s[0]
L=map(lambda x:map(int,x.split('x^')),s[2-y:])
print(' + '.join([s[1-y][:-1]]+['x^'.join(map(str,[a*b,b-1])).rstrip('^1')for a,b in L]))

Thật vậy, sự khó chịu chính là phải chuyển đổi giữa các chuỗi và ints. Ngoài ra, nếu một thuật ngữ không đổi được yêu cầu, mã sẽ chỉ có 153 byte.


Câu trả lời đầu tiên, là bắn để đánh DLosc, không hoàn toàn đến đó.
El'endia Starman

0

Python 2, 229 byte

import os
print' + '.join([i,i[:-2]][i[-2:]=='^1'].replace('x^0','')for i in[`a*b`+'x^'+`b-1`for a,b in[map(int,a.split('x^'))for a in[[[i+'x^0',i+'^1'][i[-1]=='x'],i]['^'in i]for i in os.read(0,9**9).split(' + ')]]]if i[0]!='0')

0

Python 2, 174 byte

print' + '.join(['%d%s%s'%(b[0]*b[1],'x'*(b[1]>1),'^%d'%(b[1]-1)*(b[1]>2))for b in[map(int,a.split('x^')if 'x^'in a else[a[:-1],1])for a in input().split(' + ')if 'x'in a]])

Thật không may, thủ thuật của DLosc để đổi tên phương thức phân tách và thực hiện phân biệt trong một chức năng cụ thể không rút ngắn mã của tôi ...

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.