グラフ電卓を実装する


12

電卓に関する多くの質問がありました。ただし、グラフ電卓の実装が関与しているようには見えません。

チャレンジ

STDINからの入力として複数の式を取り、それらをSTDOUTにグラフ化する完全なプログラムを作成します。入力の形式は次のとおりf1(x)=x^2-x-1です。があり、fその後に0〜9の数字(両端を含む)が続き(x)=、が続き、グラフ化する式が続きます。プログラムは、入力、グラフ、入力、グラフなどを取得できる必要があります。

これはコードゴルフです。

グラフのX軸の範囲は-5〜5で、解像度は1/2ユニットごとに少なくとも1ポイントである必要があります。Y軸の要件は同じです。これは、最新の計算機と比べて小さな範囲のように見えるかもしれませんが、これを増やすのはささいなことでしょう。グラフには+、整数の形の目盛りが付いた軸が描かれている必要があります。

式は通常の操作順序で評価する必要があります。これらの式には、垂直漸近線/未定義の領域はありません。変数は常にxです。同じ式番号で2つの式が入力された場合、最も古い式が消去され、新しい式に置き換えられます。空の数式はゼロに評価されるはずです。公式は常に1/2の倍数になるとは限らないので、最も近い1/2に丸める必要があります。

数式がグラフ化されるとき、その線は数式の数から形成される必要があります。線が軸と交差する場合、軸は上に描画される必要があります。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文字とカウントされるはずです。

Rubyソリューションと同様に、私もを使用evalして置き換え^てい**ます。

入力解析は非常に壊れやすく、同時に非常に堅牢f1(x)=です:f 1 ( x ) =またはfoo 1 bar =またはだけ1=で書くこともできますfが、有効な副作用のないPerlステートメントで置き換えた場合、非常に奇妙なことが起こる可能性があります。警告されました。

関心の他の詳細は、文字のビット単位のXOR事実を利用縦軸が描画される方法が含まれる+|あるがW。明らかに、これはEBCDICシステムでは機能しません。

出力は、配列の配列ではなく配列のハッシュにレンダリングされます。ハッシュキーを整数に明示的に切り捨て、配列がそうでないことを確認するよりもハッシュスライスをループする方が少ない文字で済むことがわかります負の値でインデックス付けされます。迷惑な方法ではない場合、Perlがint負の値をゼロに切り捨てないため、さらに2文字を削ることができました。出力エリアの。

入力解析では、Perlの自由な文字列から数値への変換を使用します。この場合、文字列全体を1(x)=配列インデックスとして使用します(1に変換されます)。

私は3つの文字(および解析が少しより堅牢に)置き換えることによって、保存もできたs/\d.*=/;/;$f[$&]=$_/\d.*=/;$f[$&]=$'、その後私は、書き込みに余分な文字の同じ番号を費やす必要があるだろう$'として、$'\''単一引用符で囲まれたシェルの文字列インチ 技術的にはそれらを数える必要はないと思うが、それは一種の不正行為のように感じられる。


6

ルビー、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

式の標準エバリュエーターを使用した単純なルビー実装(^上記の例が正常に機能するように置き換えられます)。これはあまりロバストではなく、質問で指定されたとおりに入力を想定しています。


5行目では、2文字に変更y*0.5y/2て削除できますか?私はRubyを知らないので、私は正しくないかもしれません。
PhiNotPi

2
@PhiNotPi残念ながら、これは機能しません。y/2整数除算を行います。
ハワード

loop{}代わりに使用できます()while 1か?
defhlt

右側のサイドバーのリンクを介してこれを見つけました。これはかなりよくできています。これをもっと小さくしようとして少し楽しかったのですが、9バイトしか見つかりませんでした。1バイトはruby 2.1(?)で導入された合理的なリテラルに依存しています。
ブルトレンジ

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.