カメヲラボ

主にプログラミングとお勉強全般について書いてます

Bode Plot(1)

公式の導出方法がわからーんと喚いたところ、smlyさんが説明してくださいました。
http://d.hatena.ne.jp/smly/20061030
うんうんなるほろ。。。

で、私が何を悩んでたのかっちゅうと、問題の中にある記述だけでどうやって導出するんだーーーという所なのですが、やはり最低限の予備知識が必要ということなのでしょうね。
抵抗とコンデンサを直列につないだ回路では、コンデンサインピーダンスが周波数に反比例するので、コンデンサの部分のインピーダンスZcは、Zc=1/wcと表す事ができる、と。いろいろ調べていたら、http://nkiso.u-tokai.ac.jp/phys/exp/titles/impede.htmに結構わかりやすい資料を発見したので一応解決っちゅうことにしときましょ。

ではでは本題に。
この1045番の問題は、実のところGCC拡張についてちょっと説明するのに手ごろな問題かなあとおもって選んだわけです。
具体的にコードを書いてみます。
まずは単純に

float v,r,c,w;
main(){
  for(scanf("%f%f%f%*d",&v,&r,&c);~scanf("%f",&w);)
    printf("%.3f\n",v/sqrt(r*r+1/w/w/c/c)*r);
}

公式をそのまま使って、読み込みもごく普通に。これで110バイト。
id:xatm092doraさんのコードで思い出しましたが、hypotを使えば

float v,r,c,w;
main(){
  for(scanf("%f%f%f%*d",&v,&r,&c);~scanf("%f",&w);)
    printf("%.3f\n",v/hypot(r,1/w/c)*r);
}

これで107バイト。

ここからさらに短縮するためには、scanfを一つにするという方法が考えられます。GCC拡張を使えば三項演算子の代入文が簡単に書けるので、私はこれを使ってみました。


f?a=x:(b=x)
と通常書くところを、GCC拡張により
f?a:b=x
短く書くことができます
これは色んなコードに使えるので、ショートコーダーには必須のテクニックなのですが、これを使って先ほどのコードをさらに短縮します。

float t,v,r,c,w;
main(){
  for(;~scanf("%f",&w);)
    v?r?c?t?printf("%.3f\n",v/hypot(r,1/w/c)*r),w:t:c:r:v=w;
}

単純に、v,r,cがゼロなら順に代入しています。難点は、4つ目のデータ(wの個数)を無駄に読み込まなければならないところ。これで102バイト。とか考えてたら、どうやら配列でまとめて読み込んだほうが短くなるみたいでした^^;
http://d.hatena.ne.jp/xatm092dora/20061031#c
えーん。。。