ใช้เครื่องคิดเลขกราฟ


12

มีคำถามมากมายที่เกี่ยวข้องกับเครื่องคิดเลข; อย่างไรก็ตามจะไม่ปรากฏว่ามีส่วนเกี่ยวข้องกับการใช้เครื่องคิดเลขกราฟ

ความท้าทาย

คุณต้องเขียนโปรแกรมทั้งหมดที่ใช้หลายสูตรเป็นอินพุตจาก STDIN และกราฟไปยัง STDOUT f1(x)=x^2-x-1การป้อนข้อมูลจะใช้รูปแบบ จะมีการfตามด้วยหมายเลข 0-9 (รวม) ตามด้วย(x)=ตามด้วยสูตรกราฟ โปรแกรมของคุณควรสามารถรับอินพุตกราฟรับอินพุตเพิ่มกราฟและอื่น ๆ ได้

นี่คือรหัสกอล์ฟ

กราฟของคุณควรมีช่วงแกน X ตั้งแต่ -5 ถึง 5 โดยมีความละเอียดอย่างน้อยหนึ่งจุดในทุกๆ 1/2 หน่วย ความต้องการแกน Y เหมือนกัน นี่อาจดูเหมือนเป็นช่วงเล็ก ๆ เมื่อเทียบกับเครื่องคิดเลขที่ทันสมัย ​​แต่ส่วนใหญ่จะเพิ่มขึ้นเล็กน้อย กราฟควรมีแกนที่วาดอยู่กับพวกเขาโดยมีเครื่องหมายถูกในรูปของ+จำนวนเต็ม

ควรประเมินสูตรด้วยลำดับการดำเนินการปกติ จะไม่มีเส้นกำกับ / ภูมิภาคที่ไม่ได้กำหนดในสูตรเหล่านี้ ตัวแปรจะเป็น x เสมอ หากป้อนสองสูตรด้วยหมายเลขสมการเดียวกันสูตรที่เก่าที่สุดควรถูกลบและแทนที่ด้วยสูตรใหม่ สูตรเปล่าควรประเมินเป็นศูนย์ เนื่องจากมีโอกาสที่สูตรจะไม่ให้ผลคูณ 1/2 ที่ดีเสมอคุณจึงต้องปัดเศษ 1/2 ที่ใกล้ที่สุด

เมื่อสูตรเป็นกราฟเส้นของมันควรจะเกิดจากจำนวนของสูตร เมื่อเส้นผ่านแกนหนึ่งแกนควรวาดที่ด้านบน เมื่อสองบรรทัดข้ามกันมันไม่สำคัญว่าจะแสดง

ตัวอย่างอินพุต

f1(x)=x+1

เอาท์พุต

          +       1
          |      1
          +     1
          |    1
          +   1
          |  1
          + 1
          |1
          +
         1|
+-+-+-+-+-+-+-+-+-+-+
       1  |
      1   +
     1    |
    1     +
   1      |
  1       +
 1        |
1         +
          |
          +

อินพุต

f2(x)=(x^2)^0.25

เอาท์พุต

          +       1
          |      1
          +     1
          |    1
          +   1
          |  1
2222      + 1    2222
    222   |1  222
       22 + 22
         2|2
+-+-+-+-+-+-+-+-+-+-+
       1  |
      1   +
     1    |
    1     +
   1      |
  1       +
 1        |
1         +
          |
          +

อินพุต

f1(x)=-x  

(หมายเหตุเป็นที่ยอมรับได้สำหรับโปรแกรมของคุณที่จะปฏิเสธอินพุตนี้และมีเพียงยกเว้น 0-x หรือ x * -1 แต่ควรบันทึกไว้)

เอาท์พุต

1         +
 1        |
  1       +
   1      |
    1     +
     1    |
2222  1   +      2222
    2221  |   222
       22 + 22
         2|2
+-+-+-+-+-+-+-+-+-+-+
          |1
          + 1
          |  1
          +   1
          |    1
          +     1
          |      1
          +       1
          |        1
          +         1

คำตอบ:


5

Perl, 177 ตัวอักษร (สวิตช์บรรทัดคำสั่ง +1)

perl -nE 's!\^!**!g;s!x!(\$k/2-6)!g;s/\d.*=/;/;$f[$&]=$_;my%a;for$k(@x=2..22){$i=0;$a{int 12.5-2*eval}[$k-2]=$i++for@f}$p="|";$$_[10]=$p^=W,$a{12}=[$p."-+"x10],say map$_//$",@$_ for@a{@x}'

ต่อเมตาดาต้าเธรดนี้ฉันเชื่อว่าควรนับรวมเป็น 178 อักขระ

เช่นเดียวกับการแก้ปัญหาทับทิมฉันยังมีการใช้evalและแทนที่ด้วย^**

การแยกวิเคราะห์อินพุตนั้นมีทั้งความเปราะบางอย่างไม่น่าเชื่อและแข็งแกร่งในเวลาเดียวกัน: f1(x)=สามารถเขียนเป็นf 1 ( x ) =หรือfoo 1 bar =แม้กระทั่งเพียง1=แต่สิ่งที่แปลกมากอาจเกิดขึ้นได้หากคุณแทนที่fด้วยสิ่งที่ไม่ถูกต้องคำสั่ง Perl ด้านข้างไม่มีผล คุณได้รับการเตือน

รายละเอียดอื่น ๆ ที่น่าสนใจ ได้แก่ วิธีการที่แกนแนวตั้งจะถูกวาดซึ่งใช้ประโยชน์จากความจริงที่ว่าแฮคเกอร์ค่าที่เหมาะสมของตัวละคร+และเป็น| Wเห็นได้ชัดว่าสิ่งนี้ไม่สามารถใช้ได้กับระบบ EBCDIC

เอาต์พุตถูกเรนเดอร์เป็นแฮชของอาร์เรย์ไม่ใช่อาร์เรย์ของอาร์เรย์ - มันกลับกลายเป็นว่าจะใช้ตัวอักษรจำนวนน้อยลงเพื่อตัดทอนคีย์แฮชให้เป็นจำนวนเต็มอย่างชัดเจนจากนั้นวนลูปของแฮชมากกว่าที่ใช้ จัดทำดัชนีด้วยค่าลบ ฉันสามารถโกนตัวละครเพิ่มได้อีกสองตัวถ้ามันไม่ใช่วิธีที่น่ารำคาญของ Perl จะintตัดค่าลบที่มีค่าเป็นศูนย์ซึ่งบังคับให้ฉันกำหนดจำนวนแถวเอาต์พุตจาก 2 ถึง 22 แทนที่จะเป็น 0 ถึง 20 เพื่อหลีกเลี่ยงการปัดเศษวัตถุที่ขอบด้านบน ของพื้นที่เอาท์พุท

ฉันใช้ประโยชน์จากการแปลงแบบสตริงเป็นตัวเลขจำนวนมากของ Perl ในการแยกวิเคราะห์อินพุตโดยที่ฉันใช้สตริงทั้งหมด1(x)=เป็นดัชนีอาร์เรย์ (มันได้รับการแปลงเป็นเพียง 1)

ฉันยังสามารถบันทึกตัวอักษรสามตัวมากขึ้น (และทำให้แยกออกไปเล็กน้อยที่แข็งแกร่งมากขึ้น) โดยการแทนที่s/\d.*=/;/;$f[$&]=$_ด้วย/\d.*=/;$f[$&]=$'แต่แล้วผมต้องใช้หมายเลขเดียวกันของตัวละครพิเศษในการเขียน$'เป็น$'\''ในสตริงเปลือกเดียวที่ยกมา ฉันคิดว่าในทางเทคนิคแล้วฉันไม่ต้องนับพวกมัน แต่มันให้ความรู้สึกเหมือนการโกง


6

Ruby, 200 ตัวอักษร

f={}
r=0..20
(f[gets[1]]=$_[6..-1].gsub /\^/,'**'
s=r.map{' '*21}
f.map{|n,k|r.map{|y|x=y*0.5-5
v=(2*eval(k)).round
v.abs<11&&y!=10&&s[10-v][y]=n
s[y][10]='+|'[y%2]
s[10][y]='+-'[y%2]}}
puts s)while 1

การใช้ ruby ​​ล้วนๆโดยใช้ตัวประเมินมาตรฐานสำหรับนิพจน์ ( ^จะถูกแทนที่เพื่อให้ตัวอย่างที่ให้ไว้ข้างต้นทำงานได้ดี) มันไม่แข็งแกร่งมากและถือว่าอินพุตตรงตามที่ระบุในคำถาม


ในบรรทัดที่ห้าคุณอาจจะเปลี่ยนy*0.5ไปy/2และกำจัดของตัวละครทั้งสอง? ฉันไม่รู้รูบีดังนั้นฉันอาจไม่ถูกต้อง
PhiNotPi

2
@PhiNotPi น่าเสียดายที่นี่ไม่ได้ y/2การหารจำนวนเต็ม
โฮเวิร์ด

คุณสามารถใช้loop{}แทนได้()while 1หรือไม่?
defhlt

พบสิ่งนี้ผ่านลิงค์ในแถบด้านข้างไปทางด้านขวามือ มันทำได้ค่อนข้างดี ฉันสนุกไปกับการพยายามทำให้มันเล็กลง แต่ฉันพบเพียง 9 ไบต์หนึ่งไบต์ใช้ตัวอักษรเหตุผลที่แนะนำใน ruby ​​2.1 (?)
blutorange

5

Python 2: 320 ตัวอักษร

N=20
r=range(N+1)
d={}
while(1):
 l=raw_input()
 d[l[1]]=l[6:].replace('^','**')
 g=[[' ']*(N+1) for i in r]
 for n,f in d.items():
  for x in r:
   v=N/2+int(round(2*eval(f.replace('x','(%f)'%(x/2.0-N/4)))))
   if 0<=v<=N:g[N-v][x]=n
 for i in r:
  g[i][N/2]='+|'[i%2]
  g[N/2][i]='+-'[i%2]
 for l in g:print''.join(l)

อาจจะสั้นลง แต่ฉันเป็นมือใหม่ที่นี่ :)

การทำให้Nตัวแปรเสีย 9 ตัวอักษร แต่ฉันชอบวิธีนั้นดีกว่า

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