Mở rộng đại số cơ bản


8

Vấn đề

Tôi đã có một chương trình mới TUYỆT VỜI sẽ thay đổi cách chúng ta suy nghĩ về toán học trong điện toán, tiếp nhận các chuỗi hàm đại số và thực hiện những điều TUYỆT VỜI với chúng! Vấn đề duy nhất, là tôi chỉ có thể phân tích đại số cụ thể, nếu không vũ trụ tự gấp lại, điều đó thật tệ. May mắn thay, tôi chỉ cần một vài thao tác cơ bản trong đầu vào chương trình mới tuyệt vời này, nhưng tôi vẫn cần nó mở rộng!

Quy tắc

  • Một câu trả lời phải có thể đơn giản hóa các biểu thức sau đây

    • 2+2 nên giảm xuống 4
    • (5+x)+6 nên giảm xuống x+11
    • (x+2)^2 nên giảm xuống x^2+4*x+4
    • (x-5)*(3+7*x) nên giảm xuống 7*x^2-32*x-15
    • 5*x+9*x nên giảm xuống 14*x
    • (2*x^2)*x^3 nên giảm xuống 2*x^5
  • Câu trả lời phải có thể HOÀN TOÀN loại bỏ dấu ngoặc đơn, ngụ ý rằng tất cả phân phối phải diễn ra.

  • Câu trả lời phải có thể xử lý tất cả các toán tử và mã thông báo sau:

    • + (Hàm bổ sung)
    • - (Hàm trừ)
    • * (Hàm nhân)
    • ( (Dấu ngoặc trái, được sử dụng để chỉ một nhóm)
    • ) (Dấu ngoặc đơn bên phải, được sử dụng để chỉ sự kết thúc của nhóm bắt đầu cuối cùng)
    • x (Biến tiêu chuẩn)
    • [0-9]+ (số không âm)
  • Câu trả lời phải có khả năng bình phương tối thiểu, sử dụng ký hiệu expr ^ 2, bao gồm (expr) ^ 2 theo cách đệ quy, vì (expr) tự nó là một biểu thức;)

  • Một giải pháp phải nằm trong ký hiệu infix tiêu chuẩn, không có gì vô nghĩa RPN!

  • Không có chức năng thư viện như Mathicala's Simplifyđể làm điều này cho bạn.

  • Giải pháp phải là một hàm nhận một đối số duy nhất và trả về phiên bản mở rộng

Vì đây là môn đánh gôn, câu trả lời với số lần đánh (khóa) ít nhất sẽ thắng, 1 tuần từ OP.

Ghi chú

Tất nhiên, không có không gian trong thế giới toán học này! Chỉ dấu ngoặc đơn.

Vì vậy, không có bộ phận được yêu cầu để tiết kiệm từ bao thanh toán

Thứ tự tiêu chuẩn của hoạt động áp dụng.

Tôi biết rằng một số những gì tôi đang hỏi là đơn giản hóa (ví dụ 2+2=4), nơi các bộ phận khác thực sự là điều ngược lại, chẳng hạn như mở rộng (x+1)^2được x^2+2x+1. Đây là cố ý. :)

-25 nét cho một giải pháp có thể làm (expr) ^ n thay vì chỉ (expr) ^ 2

-15 nét cho một giải pháp có thể đánh giá phép nhân xen kẽ, chẳng hạn như 4x+5x== 9x, hoặc 4(x+1)=4x+4

-5 nét cho một giải pháp có thể xử lý nhiều biến (Một biến chính xác là một ký tự chữ cái viết thường)

-5 nét cho một giải pháp có thể loại bỏ hàng đầu 0 ( 007chỉ 7[Không phải hôm nay, Bond!] [Bây giờ tôi cảm thấy như mình đang viết Lisp])


Tôi tin rằng (x-5) * (3 + 7 * x) là (1 * x + -5) * (7 * x + 3) là 7 * x ^ 2 + (3-35) * x + - 15 hoặc 7 * x ^ 2-32 * x-15
Jeff Grigg

Nên cung cấp đầu vào như thế nào? Đối số dòng lệnh? Tiêu chuẩn đầu vào? Có lẽ nên được chỉ định.
Frxstrem

@JeffGrigg Đây là lý do tại sao tôi cần chương trình;) Hehe Tôi thực sự đã thêm 7 * x để hiển thị phức tạp hơn và quên cập nhật giải pháp. Cảm ơn! Và tôi có thể đã thề rằng tôi đã bao gồm rằng họ nên được coi là một đối số cho một chức năng
Christopher Wirt

1
Tôi gần như có một giải pháp làm việc cho điều này trong J, tôi chỉ cần phân tích chính xác các số âm. Đây có lẽ là điều xấu nhất, tồi tệ nhất tôi từng viết, nhưng may mắn là nó đã gần hết.
thuật toán

1
@ssdecontrol không phân chia, chúng ta đang nói về đa thức. Thêm bộ phận và đó là một điều rất khác biệt
edc65

Câu trả lời:


2

J - 350 char - 25 = 325 điểm

Hãy tha thứ cho tôi, Roger Hui, vì tôi đã phạm tội.

x=:0 1
f=:(('+_';'-';'_';'-')rplc~' '-.~'+'}.@,@|.@,.s(}.@]`(,&":)@.t'*x'"_`('*x^',":)`(''"_)@.t=.*@<:@[)/"1@#~0~:0{|:@s=.,.i.@#)@p=:(0{::'()'+/@,:&,e'+'@((+/@,:&,-)~e'-')@(*/a e'*')@('^'(*/(a=.+//.@)/@#,:e=:2 :'(<@; ::({:u/&.>{.)/.~i.@#-i.@#(>+>:)(<,v){.@i.~])^:_'))@:(([^:(''-:])". ::])&.>)@([-.~;@]<@(p^:(1<#));.1~1,0=2*/\[:+/\(*0,}:@)1 _1 0{~i.)&;:])

Sự quái dị ở trên xác định một số biến, trong đó biến flà một hàm thỏa mãn các ràng buộc trong câu hỏi trên. Tôi yêu cầu phần thưởng "expr ^ n" cho 25 điểm.

Đây là sân golf đang hoạt động tại J REPL.

   x=:0 1
   f=:(('+_';'-';'_';'-')rplc~' '-.~'+'}.@,@|.@,.s(}.@]`(,&":)@.t'*x'"_`('*x^',":)`(''"_)@.t=.*@<:@[)/"1@#~0~:0{|:@s=.,.i.@#)@p=:(0{::'()'+/@,:&,e'+'@((+/@,:&,-)~e'-')@(*/a e'*')@('^'(*/(a=.+//.@)/@#,:e=:2 :'(<@; ::({:u/&.>{.)/.~i.@#-i.@#(>+>:)(<,v){.@i.~])^:_'))@:(([^:(''-:])". ::])&.>)@([-.~;@]<@(p^:(1<#));.1~1,0=2*/\[:+/\(*0,}:@)1 _1 0{~i.)&;:])

   f '2+2'
4
   f '(5+x)+6'
x+11
   f '(x+2)^2'
x^2+4*x+4
   f '(x-5)*(3+7*x)'
7*x^2-32*x-15
   f '5*x+9*x'
14*x
   f '(2*x^2)*x^3'
2*x^5
   f '(2*x+3)^(2+3)*2^3'   NB. bonus
256*x^8+1920*x^7+5760*x^6+8640*x^5+6480*x^4+1944*x^3

Đây là ý chính của những gì đang diễn ra.

  • '()'...@([-.~;@]<@(p^:(1<#));.1~1,0=2*/\[:+/\(*0,}:@)1 _1 0{~i.)&;:- Phân tách đệ quy biểu thức dựa trên các biểu thức con được ngoặc đơn của nó và đánh giá chúng ( ...bit, sẽ được mô tả bên dưới) khi chúng sẵn sàng. ;:thực hiện mã thông báo.
  • (([^:(''-:])". ::])&.>)- Đánh giá các nguyên tử. Nếu nguyên tử là số, nó được biến thành số vô hướng. Nếu nguyên tử là một toán tử, nó được giữ nguyên. Nếu nguyên tử là biến x, nó được biến thành vectơ 0 1. (Đó là lý do tại sao chúng tôi xác định x=:0 1khi bắt đầu.) Nói chung, chúng tôi lưu trữ đa thức a*x^n + b*x^(n-1) + ... + c*x + ddưới dạng n+1danh sách -item d c ... b a.
  • e=:2 :'(<@; ::({:u/&.>{.)/.~i.@#([->+>:){.@i.&(<,v))^:_'- Sự kết hợp tò mò này có một động từ ở bên trái và một nhân vật ở bên phải. Nó tìm thấy phiên bản đầu tiên của ký tự đó trong đầu vào được mã hóa, không có mã hóa và đánh giá nó với các đối số xung quanh nó và lặp lại cho đến khi không còn tìm thấy các ký tự như vậy nữa. Vì vậy, chúng tôi lặp lại đơn giản hóa biểu thức, với thứ tự các hoạt động được kiểm soát theo thứ tự áp dụng e.
  • Và sau đó tất cả những thứ ở phía trước chỉ là đầu ra in đẹp. rplclà một chức năng thư viện tiêu chuẩn để thay thế chuỗi con. Chúng tôi có thể lưu ba ký tự khác nếu chúng tôi được phép đặt các điều khoản mức độ thấp nhất trước tiên thay vì cao nhất, bằng cách xóa @|..

Tôi thực sự không chắc chắn liệu tôi có thể ép thêm bất kỳ nhân vật nào ra khỏi sân golf này không. Tôi không thể nghĩ ra bất kỳ cách tiếp cận nào khác không yêu cầu số lượng áp đảo tương tự, nhưng điều đó không có nghĩa là không có cách tiếp cận nào. Dù bằng cách nào, tôi khá chắc chắn rằng mình đã vắt tất cả các nhân vật rõ ràng ra khỏi phiên bản này.


Bravo! Và bạn có thể thoát khỏi sửa chữa số âm, vì -mã thông báo chỉ được ghi chú là hàm trừ. :)
Christopher Wirt

@ChristopherWirt Không nắm bắt được điều đó. Dù bằng cách nào, đã xong.
thuật toán

(2*x+3)^(2+3)*2^3Nên cho 256x^5+1920x^4+5760x^3+8640x^2+6480x+1944hay tôi đang thiếu thứ gì?
edc65

2

JavaScript (EcmaScript 6) 698 (tiền thưởng 748-50) 725 780 1951

Được chơi golf . Nhưng tôi tự hào nó hoạt động.
(Chỉnh sửa: sửa lỗi, sự cố với dấu ngoặc và dấu trừ)
(Chỉnh sửa2: đánh gôn nhiều hơn, sửa lỗi đầu ra)
(Chỉnh sửa 3: đánh golf một lần nữa, lần trước tôi hứa)

Bình luận

Về cơ bản, hàm X là một máy tính infix hoạt động trên các đa thức nghĩa đen.
Mỗi đa thức được lưu trữ dưới dạng đối tượng js, khóa là thuật ngữ (x ^ 3y ^ 2) và giá trị là hệ số. Hàm A, M và E được cộng, nhân và lũy thừa.

Mã Golf

(Có lẽ không thể đánh gôn nhiều hơn ...) Lưu ý: không tính các dòng mới được thêm vào cho (ehm ...) khả năng đọc

K=x=>Object.keys(x).sort(),
A=(p,q,s,t,c)=>[(c=(s+1)*q[t]+~~p[t])?p[t]=c:delete(p[t])for(t in q)],
M=(p,q,t,c,o,u,f,r,v={})=>([A(v,(r={},[(c=p[f]*q[t])&&(r[o={},(u=f+t)&&(u.match(/[a-z]\^?\d*/ig).map(x=>o[x[0]]=~~o[x[0]]+(~~x.slice(2)||1)),K(o,u=k).map(i=>u+=o[i]>1?i+'^'+o[i]:i)),u]=c)for(f in p)],r),k)for(t in q)],v),
E=(p,n)=>--n?M(p,E(p,n)):p,
O=n=>{for(l=0;h(o=s.pop())>=h(n);)a=w.pop(b=w.pop()),o=='*'?a=M(a,b):o>d?a=E(a,b[k]):A(a,b,o),w.push(a);s.push(o,n)},
X=e=>(l=k='',w=[],s=[d='@'],h=o=>'@)+-*^('.indexOf(o),
(e+')').match(/\D|\d+/g).map(t=>(u=h(t))>5?(l&&O('*'),s.push(d)):u>1?O(t):~u?s.pop(s.pop(O(t)),l=1):(l&&O('*'),l=1,w.push(v={}),t<d?v[k]=t|0:v[t]=1)),
K(p=w.pop()).map(i=>(k+=(c=p[i])>1?s+c+i:c<-1?c+i:(c-1?'-':s)+(i||1),s='+')),k||0)

Kiểm tra trong bảng điều khiển FireFox

['2+2','(5+x)+6','(x+2)^2','(a+b)(a-b)','(a+b)*(a-b)','(a-b)(a-b)', '(x-5)*(3+7*x)','5*x+9*x','(2*x^2)*x^3','(2*x+3)^(2+3)*2^3']
.map(x => x + ' => ' + X(x)).join('\n')

Đầu ra

2+2 => 4
(5+x)+6 => 11+x
(x+2)^2 => 4+4x+x^2
(a+b)(a-b) => a^2-b^2
(a+b)*(a-b) => a^2-b^2
(a-b)(a-b) => a^2-2ab+b^2
(x-5)*(3+7*x) => -15-32x+7x^2
5*x+9*x => 14x
(2*x^2)*x^3 => 2x^5
(2*x+3)^(2+3)*2^3 => 1944+6480x+8640x^2+5760x^3+1920x^4+256x^5

Tiền thưởng

25: 2*x+3)^(2+3)*2^3 => 1944+6480x+8640x^2+5760x^3+1920x^4+256x^5
15: 4x+5x => 9x
5: 007x+05x^(06+2) => 7x+5x^8
5: (a+b)(a-b) => a^2-b^2

Mã bị đánh cắp

Show=(p)=>(
  Object.keys(p).sort().map(i=>(c=p[i])-1?c+1?c+i:'-'+i:i).join('+').replace(/\+-/g,'-')
)
AddMonoTo=(poly, term, coeff, c)=>(
  (c = coeff + ~~poly[term]) ? poly[term]= c : delete(poly[term])
)
AddPolyTo=(p1, p2, s, t)=>(
  [ AddMonoTo(p1, t, (s+1)*p2[t]) for (t in p2)]
)
MulTerm=(t1, t2, o={})=>(
  (t1+=t2)&&
  (t1.match(/[a-z](\^\d+)?/g).every(x=>o[x[0]]=(~~x.slice(2)||1)+(~~o[x[0]])),
  Object.keys(o,t1='').sort().every(i=>t1+=o[i]>1?i+'^'+o[i]:i)),
  t1  
)
MulMono=(poly, term, coeff, c, r={}, t)=>(
  [(c = poly[p]*coeff) && (r[MulTerm(p,term)] = c) for (p in poly) ],r
)  
MulPoly=(p1, p2, r={}, p)=>(
  [AddPolyTo(r,MulMono(p2, p, p1[p]),'') for (p in p1)],r
)
ExpPoly=(p,n,r=p)=>{
  for(;--n;)r=MulPoly(r,p);
  return r
}
Expand=ex=>
{
  var tokens = ex.match(/\D|\d+/g).push(')')
  var t,a,b,v,LastV=0
  var vstack=[]
  var ostack=['_']
  var op={ '+': 3, '-':3, '*':4, '^':6, '(':8, _: 1, ')':2}
  var OPush=o=>ostack.push(o)
  var OPop=_=>ostack.pop()
  var VPush=v=>vstack.push(v)
  var VPop=v=>vstack.pop()

  var Scan=i=>
  {
    LastV=0 ;
    for (; (t=tokens[i++]) && (t != ')'); )
    {
      if (t == '(')  
      {
        if (LastV) CalcOp('*')
        OPush('_'), i=Scan(i)
      }
      else if (op[t])
        LastV=0, CalcOp(t)
      else
      {
        if (LastV) CalcOp('*')
        LastV = 1
        VPush(v={})
        t < 'a' ? v[''] = t|0 : v[t] = 1
      }
    }
    CalcOp(t);
    OPop();
    OPop();
    LastV=1;
    return i;
  }
  var CalcOp=nop=>
  {
    for (; op[po = OPop()] >= op[nop];)
      b=VPop(), a=VPop(), CalcV(a,b,po);
    OPush(po), OPush(nop);
  }
  var CalcV=(a,b,o)=>
  {
    if (op[o] < 4) 
      AddPolyTo(a,b,o)
    else if (o == '*')
      a=MulPoly(a,b)
    else // ^
      a=ExpPoly(a,b['']) // only use constant term for exp
    VPush(a)
  }
  Scan(0)

  return Show(vstack.pop())
}

yu chỉ sử dụng dấu chấm phẩy ở một số nơi? Có phải vì thiếu khung mà bạn cần chúng? Tôi không tuân thủ EcmaScript lắm với JS của tôi;)
Christopher Wirt

Dấu phẩy riêng biệt, dấu chấm phẩy riêng biệt. Nó rõ ràng hơn trong for(i1,i2,i3; c1,c2; s1,s2,s3). Tôi chỉ có một dấu chấm phẩy trong trò chơi đánh gôn để đóng một câu lệnh bên trong một for (hàm O). Tại sao dấu phẩy? hai nhị phân phải được nhóm với {} trong khi hai hoặc nhiều biểu thức có thể được liệt kê đơn giản.
edc65

1

Toán học: 56 - 25 - 15 - 5 - 5 = 6

Tất nhiên không có chức năng thư viện như Expandhoặc Distribute, chỉ thay thế mẫu. Mathematica làm hầu hết mọi thứ cho chúng tôi (hax!), Những gì còn lại chỉ là quy tắc để phân phối và mở rộng sức mạnh. Các ví dụ không tầm thường do đó là (x-5)*(3+7*x)(x+2)^2.

f=#//.{x_ y_Plus:>(x #&/@y),x_Plus^n_:>(x #&/@x)^(n-1)}&

Ví dụ

(x-5)*(3+7*x) // f
-15 - 32 x + 7 x^2

(x + 2)^2 // f
4 + 4 x + x^2

Bạn có một số nhân vật rất lạ trong cả hai ví dụ của bạn. Bạn có thể làm sạch nó?
edc65

@ edc65 M10 hành động lạ với sao chép / dán tôi đoán.
swish

Tôi có lẽ đã nên cấm toán học tất cả;) công việc tốt, mặc dù vậy
Christopher Wirt
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.