โปรแกรมวิชวลไลเซชันสมการศิลปะ ASCII


10

การจัดการกับสมการเมื่อไม่มีตัวแก้ไขสมการที่ดีนั้นยุ่งและไม่เป็นที่พอใจ ตัวอย่างเช่นถ้าฉันต้องการแสดงอินทิกรัลและวิธีแก้ปัญหามันอาจมีลักษณะดังนี้:

ส่วนประกอบ [x ^ 3 e ^ (- mx ^ 2 b / 2), dx] = - ((2 + b m x ^ 2) / (b ^ 2 * e ^ ((b m x ^ 2) / 2) M * ^ 2))

ที่integrals.wolfram.comสิ่งนี้เรียกว่า "รูปแบบการป้อนข้อมูล" ไม่มีใครชอบเห็นสมการใน "รูปแบบการป้อนข้อมูล" วิธีที่เหมาะในการแสดงภาพสมการนี้คือ:

ป้อนคำอธิบายรูปภาพที่นี่

(วุลแฟรมเรียกสิ่งนี้ว่า "รูปแบบดั้งเดิม")

สำหรับ codegolf นี้ให้เขียนโปรแกรมที่จะใช้สมการใน "รูปแบบการป้อนข้อมูล" เป็นรูปแบบการป้อนข้อมูลและเห็นภาพของสมการในรูปแบบดั้งเดิมของ "รูปแบบดั้งเดิม" ดังนั้นสำหรับตัวอย่างนี้เราอาจได้รับสิ่งนี้:

       /\      3
       |      x
       | ------------  dx = 
       |       2
      \/   (m x  b)/2
          e

              2
     2 + b m x
-(-----------------)
            2
   2  (b m x )/2  2
  b  e           m

ที่ต้องการ:

  1. อย่าสับเปลี่ยนให้ง่ายขึ้นหรือจัดเรียงอินพุตใหม่ในทางใดทางหนึ่ง แสดงผลในรูปแบบเดียวกันที่อธิบายโดยอินพุต
  2. สนับสนุนการดำเนินการทางคณิตศาสตร์สี่ขั้นพื้นฐาน (+, -, *, /) เมื่อไม่คูณสองหมายเลขที่อยู่ติดกันสัญลักษณ์ * จะถูกบอกเป็นนัยและควรละเว้น
  3. ไม่จำเป็นต้องรองรับการรวม (ดังแสดงในตัวอย่างด้านบน) ความสามารถในการรองรับการป้อนข้อมูลด้วยฟังก์ชันเช่นอินทิเกรต [... ] หรือ Sqrt [... ] เป็นโบนัส
  4. กำลังสนับสนุนตามที่แสดงในตัวอย่างข้างต้น (รูทที่ n สามารถสร้างแบบจำลองได้โดยการเพิ่มกำลังไฟที่ 1 / nth)
  5. เครื่องหมายวงเล็บที่ซ้ำซ้อน (เช่นที่อยู่รอบตัว denomentator และตัวเศษของเศษส่วนขนาดใหญ่ในตัวอย่างด้านบน) ควรละเว้น
  6. นิพจน์ในตัวส่วนและตัวเศษของเศษส่วนควรอยู่กึ่งกลางด้านบนและด้านล่างเส้นแบ่งแนวนอน
  7. คุณสามารถเลือกได้ว่าจะเริ่มบรรทัดใหม่หลังจากเครื่องหมายเท่ากับหรือไม่ ในตัวอย่างข้างต้นบรรทัดใหม่จะเริ่มขึ้น
  8. ลำดับของการดำเนินการจะต้องเหมือนกันในผลลัพธ์เช่นเดียวกับที่อยู่ในอินพุต

ตัวอย่างของอินพุตและเอาต์พุตที่เกี่ยวข้องสำหรับการทดสอบโซลูชันของคุณ:

การป้อนข้อมูล:

1/2 + 1/3 + 1/4

เอาท์พุท:

1   1   1
- + - + -
2   3   4

การป้อนข้อมูล:

3x^2 / 2 + x^3^3

เอาท์พุท:

   2     3
3 x     3
---- + x   
 2

การป้อนข้อมูล:

(2 / x) / (5 / 4^2)

เอาท์พุท:

2
-
x
--
5
--
 2
4

การป้อนข้อมูล:

(3x^2)^(1/2)

เอาท์พุท:

    2 1/2
(3 x )

โดยทั่วไปคำถามของคุณควรมีแท็กที่แสดงว่าเป็นการแข่งขันประเภทใด ฉันได้เพิ่มเสรีภาพในการเพิ่มเพราะคุณพูดว่า "codegolf" ในข้อความ
dmckee --- ผู้ดูแลอดีตลูกแมว

3
ปัญหานี้คลุมเครือเกินไปที่จะเขียนโคด คุณไม่ได้พูดว่าโครงสร้างอะไรที่ต้องรองรับหรือสิ่งที่พวกมันต้องมีหน้าตา จะรองรับ +, -, * และ / เพียงพอหรือไม่ ซิกมาต้องได้รับการสนับสนุนหรือไม่? แล้วตัวอักษรกรีกล่ะ? วิธีแก้ปัญหาที่เป็นไปได้สำหรับคำถามที่คุณโพสต์อาจมีความหลากหลายในการใช้งานที่จะเปรียบเทียบกับความยาวของรหัส
MtnViewMark

@MtnViewMark ฉันเพิ่ม "ข้อกำหนด" บางอย่าง ... แจ้งให้เราทราบหากสนามกอล์ฟดีขึ้นในขณะนี้
Ami

@Ami - ใช่มาก
MtnViewMark

ฉันเห็นด้วยกับ MtnViewMark ดูเหมือนว่าจะเปิดกว้างและคลุมเครือ บางทีคุณอาจจะดีกว่าที่จะ จำกัด การป้อนข้อมูลและการส่งออกไปยังชุดทดสอบที่กำหนดไว้อย่างดีสำหรับวัตถุประสงค์ของการเล่นกอล์ฟ คุณใช้การอ้างอิงเสร็จแล้วหรือยัง
gnibbler

คำตอบ:


10

Python 2, 1,666 ตัวอักษร

เลย์เอาต์นั้นง่ายมาก - เป็นการแยกวิเคราะห์อินพุตที่เป็นความเจ็บปวดของราชวงศ์ ฉันยังไม่แน่ใจว่ามันถูกต้องทั้งหมด

import re,shlex
s=' '
R=range

# Tokenize.  The regex is because shlex doesn't treat 3x and x3 as two separate tokens.  The regex jams a space in between.                                                 
r=r'\1 \2'
f=re.sub
x=shlex.shlex(f('([^\d])(\d)',r,f('(\d)([^\d])',r,raw_input())))
T=[s]
while T[-1]:T+=[x.get_token()]
T[-1]=s

# convert implicit * to explicit *                                                                                                                                          
i=1
while T[i:]:
 if(T[i-1].isalnum()or T[i-1]in')]')and(T[i].isalnum()or T[i]in'('):T=T[:i]+['*']+T[i:]
 i+=1

# detect unary -, replace with !                                                                                                                                            
for i in R(len(T)):
 if T[i]=='-'and T[i-1]in'=+-*/^![( ':T[i]='!'
print T

# parse expression: returns tuple of op and args (if any)                                                                                                                   
B={'=':1,',':2,'+':3,'-':3,'*':4,'/':4,'^':5}
def P(t):
 d,m=0,9
 for i in R(len(t)):
  c=t[i];d+=c in'([';d-=c in')]'
  if d==0and c in B and(B[c]<m or m==B[c]and'^'!=c):m=B[c];r=(c,P(t[:i]),P(t[i+1:]))
 if m<9:return r
 if'!'==t[0]:return('!',P(t[1:]))
 if'('==t[0]:return P(t[1:-1])
 if'I'==t[0][0]:return('I',P(t[2:-1]))
 return(t[0],)

# parenthesize a layout                                                                                                                                                     
def S(x):
 A,a,b,c=x
 if b>1:A=['/'+A[0]+'\\']+['|'+A[i]+'|'for i in R(1,b-1)]+['\\'+A[-1]+'/']
 else:A=['('+A[0]+')']
 return[A,a+2,b,c]

# layout a parsed expression.  Returns array of strings (one for each line), width, height, centerline                                                                      
def L(z):
 p,g=z[0],map(L,z[1:])
 if p=='*':
  if z[1][0]in'+-':g[0]=S(g[0])
  if z[2][0]in'+-':g[1]=S(g[1])
 if p=='^'and z[1][0]in'+-*/^!':g[0]=S(g[0])
 if g:(A,a,b,c)=g[0]
 if g[1:]:(D,d,e,f)=g[1]
 if p in'-+*=,':
  C=max(c,f);E=max(b-c,e-f);F=C+E;U=[s+s+s]*F;U[C]=s+p+s;V=3
  if p in'*,':U=[s]*F;V=1
  return([x+u+y for x,u,y in zip((C-c)*[s*a]+A+(E-b+c)*[s*a],U,(C-f)*[s*d]+D+(E-e+f)*[s*d])],a+d+V,F,C)
 if'^'==p:return([s*a+x for x in D]+[x+s*d for x in A],a+d,b+e,c+e)
 if'/'==p:w=max(a,d);return([(w-a+1)/2*s+x+(w-a)/2*s for x in A]+['-'*w]+[(w-d+1)/2*s+x+(w-d)/2*s for x in D],w,b+e+1,b)
 if'!'==p:return([' -  '[i==c::2]+A[i]for i in R(b)],a+2,b,c)
 if'I'==p:h=max(3,b);A=(h-b)/2*[s*a]+A+(h-b+1)/2*[s*a];return(['  \\/|/\\  '[(i>0)+(i==h-1)::3]+A[i]for i in R(h)],a+3,h,h/2)
 return([p],len(p),1,0)

print'\n'.join(L(P(T[1:-1]))[0])

สำหรับการป้อนข้อมูลขนาดใหญ่ในคำถามฉันได้รับ:

 /\         2                     2 
 |     - m x  b          2 + b m x  
 |     --------    = - -------------
 |  3      2                    2   
\/ x  e         dx         b m x    
                           ------   
                        2     2    2
                       b  e       m 

ต่อไปนี้เป็นกรณีทดสอบที่ยุ่งยากมากขึ้น:

I:(2^3)^4
O:    4
  / 3\ 
  \2 / 

I:(2(3+4)5)^6
O:             6
  (2 (3 + 4) 5) 

I:x Integral[x^2,dx] y
O:   /\ 2     
  x  | x  dx y
    \/        

I:(-x)^y
O:     y
  (- x) 

I:-x^y
O:     y
  (- x)

อันสุดท้ายนั้นผิดพลาดข้อผิดพลาดบางอย่างใน parser


ไม่ควรพื้นฐานของการโต้แย้งแบบรวมเป็นศูนย์กลางอย่างแท้จริงหลังจากอินทิกรัล? ปัจจุบันดูเหมือนว่าตัวห้อยจะเป็นอินทิกรัล
Joey

ไม่ยากที่จะเปลี่ยนแปลง แต่มันจะเสียพื้นที่บางส่วน ขณะนี้ฉันทำเครื่องหมายอินทิกรัลขนาดใหญ่พอที่จะครอบคลุมการโต้แย้งของมัน (โดยมีค่าต่ำสุด 3 ค่าสูง)
Keith Randall

Slight golf: ใช้แท็บแทนการเว้นวรรคสองครั้ง
CalculatorFeline
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.