Bir Grafik Hesap Makinesi Uygulama


12

Hesap makineleri ile ilgili birçok soru olmuştur; ancak, herhangi bir grafik hesap makinesinin uygulanmasını içermediği görülmemektedir.

Meydan okuma

Birden çok formülü STDIN'den girdi olarak alan ve bunları STDOUT'a grafikleyen eksiksiz bir program yazmalısınız. Girdi formu alacaktır f1(x)=x^2-x-1. Bir olacaktır f, ardından bir sayı 0-9 (dahili), ardından (x)=, grafik formül takip eder. Programınız girdi, grafik, daha fazla girdi, grafik vb. Alabilmelidir.

Bu kod golf.

Grafiğinizin X ekseni aralığı -5 ile 5 arasında olmalı ve her 1/2 birimde en az bir nokta çözünürlüğe sahip olmalıdır. Y ekseni gereksinimleri aynıdır. Bu, modern hesap makinelerine kıyasla küçük bir aralık gibi görünebilir, ancak büyük olasılıkla bunu arttırmak önemsiz olacaktır. Grafik, +üzerinde tamsayılar şeklinde onay işaretleri bulunan eksen üzerinde çizilmelidir .

Formül normal çalışma sırası ile değerlendirilmelidir. Bu formüllerde dikey asimptot / tanımlanmamış bölge olmayacaktır. Değişken her zaman x olacaktır. Aynı denklem numarasıyla iki formül girilirse, en eski formül silinmeli ve yeni formülle değiştirilmelidir. Boş formüller sıfır olarak değerlendirilmelidir. Formülün her zaman 1/2 'nin güzel bir katını vermemesi muhtemel olduğundan, en yakın 1/2' ye yuvarlamanız gerekir.

Bir formül çizildiğinde, çizgisi formülün sayısından oluşturulmalıdır. Bir çizgi bir ekseni geçtiğinde, eksen üstüne çizilmelidir. İki çizgi birbirini geçtiğinde, hangisinin gösterildiği önemli değildir.

Örnek Giriş

f1(x)=x+1

Çıktı

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

Giriş

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

Çıktı

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

Giriş

f1(x)=-x  

(not edin, programınızın bu girişi reddetmesi kabul edilebilir ve yalnızca 0-x veya x * -1 hariç, ancak bu belgelenmelidir)

Çıktı

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

Yanıtlar:


5

Perl, 177 karakter (+1 komut satırı anahtarı)

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}'

Başına Bu meta iplik , bu toplamda 178 karakter olarak saymak gerektiğine inanıyoruz.

Yakut çözümü gibi ben de kullanıyorum evalve değiştirme ^ile **.

Giriş ayrıştırma hem inanılmaz derecede kırılgan hem de inanılmaz derecede sağlamdır: ya da hatta sadece f1(x)=yazılabilir , ancak geçerli, yan etkisi olmayan bir Perl ifadesi olmayan bir şeyle değiştirirseniz çok garip şeyler olabilir . Uyarıldın.f 1 ( x ) =foo 1 bar =1=f

İlgilenilen diğer detaylar, dikey eksenin çizilme şeklini içerir, bu da karakterlerin bitsel XOR'unun +ve |olduğu gerçeğinden yararlanır W. Açıkçası, bu EBCDIC sistemlerinde çalışmaz.

Çıktı bir dizi dizisine değil, bir karma dizisine dönüştürülür - karma anahtarlarını tamsayılara açık bir şekilde kısaltmak ve daha sonra bir dizinin olmadığından emin olmak için bir karma dilim üzerinde döngü yapmak için daha az karakter gerektirdiği ortaya çıkar. negatif değerlerle endekslenmiştir. Can sıkıcı bir şekilde olmasaydı iki karakteri daha tıraş edebilirdim, Perl'in intnegatif değerleri sıfıra doğru keser, bu da beni üst kenarlarda yuvarlama yapaylıklarından kaçınmak için çıkış sıralarını 0 ila 20 yerine 2 ila 22 arasında numaralandırmaya zorladı çıktı alanı.

1(x)=Bir dizi dizini (sadece 1 dönüştürülür) olarak tüm dizeyi kullanmak giriş ayrıştırma Perl liberal dize-sayı dönüşüm yararlanmak.

I could da tasarruf üç karakter (ve ayrıştırma biraz daha sağlam hale) değiştirerek s/\d.*=/;/;$f[$&]=$_ile /\d.*=/;$f[$&]=$'ama sonra yazma için ekstra karakterler aynı sayıda geçirmek olurdu $'olarak $'\''tek tırnaklı kabuk dizede. Teknik olarak bunları saymak zorunda kalmayacağımı sanıyorum, ama bir şekilde hile gibi geliyor.


6

Ruby, 200 karakter

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

İfadeler için standart değerlendiriciyi kullanan düz bir yakut uygulaması ( ^yukarıda verilen örnekler iyi çalışacak şekilde değiştirilecektir). Çok sağlam değildir ve girdiyi tam olarak soruda belirtildiği gibi varsayar.


Beşinci satırda, değişebilir y*0.5için y/2ve iki karakter kurtulmak? Ruby'yi bilmiyorum, bu yüzden doğru olmayabilirim.
PhiNotPi

2
@PhiNotPi Maalesef bu işe yaramayacak. y/2tamsayı bölme yapar.
Howard

loop{}Bunun yerine kullanabilir misin ()while 1?
17'de defhlt

Bunu sağ taraftaki yan çubuktaki bağlantı üzerinden buldum. Bu oldukça iyi. Bu küçük almak için biraz eğlendim, ama sadece 9 bayt buldum , yakut 2.1 (?) 'De rasyonel değişmezlere dayanan bir bayt.
blutorange

5

Python 2: 320 karakter

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)

Muhtemelen daha kısa yapılabilir, ama bu konuda biraz acemi var :)

Yapımı Ndeğişken atıklar böyle 9 karakter ama ben böyle daha iyi.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.