東方算程譚

Oriental Code Talk ── επιστημηが与太をこく、弾幕とは無縁のシロモノ。

目次

Blog 利用状況

ニュース

著作とお薦めの品々は

著作とお薦めの品々は
東方熱帯林へ。

あわせて読みたい

わんくま

  1. 東京勉強会#2
    C++/CLI カクテル・レシピ
  2. 東京勉強会#3
    template vs. generics
  3. 大阪勉強会#6
    C++むかしばなし
  4. 東京勉強会#7
    C++むかしばなし
  5. 東京勉強会#8
    STL/CLRによるGeneric Programming
  6. TechEd 2007 @YOKOHAMA
    C++・C++/CLI・C# 適材適所
  7. 東京勉強会#14
    Making of BOF
  8. 東京勉強会#15
    状態遷移
  9. 名古屋勉強会#2
    WinUnit - お気楽お手軽UnitTest

CodeZine

  1. Cで実現する「ぷちオブジェクト指向」
  2. CUnitによるテスト駆動開発
  3. SQLiteで組み込みDB体験(2007年版)
  4. C++/CLIによるCライブラリの.NET化
  5. C# 1.1からC# 3.0まで~言語仕様の進化
  6. BoostでC++0xのライブラリ「TR1」を先取りしよう (1)
  7. BoostでC++0xのライブラリ「TR1」を先取りしよう (2)
  8. BoostでC++0xのライブラリ「TR1」を先取りしよう (3)
  9. BoostでC++0xのライブラリ「TR1」を先取りしよう (4)
  10. BoostでC++0xのライブラリ「TR1」を先取りしよう (5)
  11. C/C++に対応した、もうひとつのUnitTestFramework ─ WinUnit
  12. SQLiteで"おこづかいちょう"
  13. STL/CLRツアーガイド
  14. マージ・ソート : 巨大データのソート法
  15. ヒープソートのアルゴリズム
  16. C++0xの新機能「ラムダ式」を次期Visual Studioでいち早く試す
  17. .NETでマンデルブロ集合を描く
  18. .NETでマンデルブロ集合を描く(後日談)
  19. C++/CLI : とある文字列の相互変換(コンバージョン)
  20. インテルTBBによる選択ソートの高速化
  21. インテルTBB3.0 によるパイプライン処理
  22. Visual C++ 2010に追加されたSTLアルゴリズム
  23. Visual C++ 2010に追加されたSTLコンテナ「forward_list」
  24. shared_ptrによるObserverパターンの実装
  25. .NETでマンデルブロ集合を描く(番外編) ── OpenCLで超並列コンピューティング
  26. StateパターンでCSVを読む
  27. 状態遷移表からStateパターンを自動生成する
  28. 「ソートも、サーチも、あるんだよ」~標準C++ライブラリにみるアルゴリズムの面白さ
  29. インテルTBBの同期メカニズム
  30. なぜsetを使っちゃいけないの?
  31. WPFアプリケーションで腕試し ~C++でもWPFアプリを
  32. C++11 : スレッド・ライブラリひとめぐり
  33. Google製のC++ Unit Test Framework「Google Test」を使ってみる
  34. メールでデータベースを更新するココロミ
  35. Visitorパターンで遊んでみたよ
  36. Collection 2題:「WPFにバインドできる辞書」と「重複を許す検索set」
  37. Visual C++ 2012:stateless-lambdaとSQLiteのぷち拡張
  38. 「Visual C++ Compiler November 2012 CTP」で追加された6つの新機能

@IT

  1. Vista時代のVisual C++の流儀(前編)Vista到来。既存C/C++資産の.NET化を始めよう!
  2. Vista時代のVisual C++の流儀(中編)MFCから.NETへの実践的移行計画
  3. Vista時代のVisual C++の流儀(後編) STL/CLRによるDocument/Viewアーキテクチャ
  4. C++開発者のための単体テスト入門 第1回 C++開発者の皆さん。テスト、ちゃんとしていますか?
  5. C++開発者のための単体テスト入門 第2回 C++アプリケーションの効率的なテスト手法(CppUnit編)
  6. C++開発者のための単体テスト入門 第3回 C++アプリケーションの効率的なテスト手法(NUnit編)

AWARDS


Microsoft MVP
for Visual Developer - Visual C++


Wankuma MVP
for いぢわる C++


Nyantora MVP
for こくまろ中国茶

Xbox

Links

記事カテゴリ

書庫

日記カテゴリ

問題としては面白い、うん。

ネタ元 → やれやれ

「放電曲線を用いたキャパシタの静電容量の推定」
ファイルinputA.txt,inputB.txt,inputC.txtは,次に示すキャパシタ(コンデンサ)の放電に関する実験のデータである:

(1) 最初にキャパシタを電池(3V)に接続して充電しておく.
(2)充電されたキャパシタを抵抗などに接続すると,
キャパシタの+極板から-極板に電流が流れ出す(放電する).
(3)(2)で接続した瞬間,およびそこから5秒経つごとに電流計を見て,流れる電流を記録する.
(4)放電しきるまで(電流計の読み値が0になるまで)記録をとる.
どのファイルにも,ファイルの各行には左から順に
「放電開始からの経過時間(秒)」「電流計の読み値(マイクロアンペア)」
という2つの数値が書かれている.
上の実験において,t-i(t)曲線(放電電流曲線)とt=0,i(t)=0で囲まれる部分の面積は
実験手順(1)でキャパシタに蓄えられた電気量を表しており,
この電気量Qをもとにキャパシタの静電容量Cを次のように求めることができる:
C = Q/V = Q/3 (Vは電池の電圧だから)
電流がマイクロアンペアで書かれているので,
この式からだとキャパシタの静電容量はマイクロファラド単位で求まる.
inputA.txt~inputC.txtからはt-i(t)曲線を正確に得ることはできないので,
隣り合う実験データを結んで得られる折れ線とt=0,i(t)=0で囲まれる部分の面積を計算し,
そこからキャパシタの静電容量のおおよその値を推定するプログラムを書きなさい.

inputA.txt
0 91
5 46
10 23
15 12
20 6
25 3
30 1
35 1
40 0

inputB.txt
0 91
5 66
10 48
15 35
20 25
25 18
30 13
35 10
40 7
45 5
50 4
55 3
60 2
65 1
70 1
75 1
80 1
85 0

inputC.txt
0 91
5 78
10 67
15 58
20 50
25 43
30 37
35 31
40 27
45 23
50 20
55 17
60 15
65 13
70 11
75 9
80 8
85 7
90 6
95 5
100 4
105 4
110 3
115 3
120 2
125 2
130 2
135 2
140 1
145 1
150 1
155 1
160 1
165 1
170 1
175 0

シャレで解いてみた
// trial.cpp
#include <iostream>
#include <fstream>
#include <utility>
#include <vector>
#include <iterator>

typedef std::pair<int,int> record;

namespace std {
  std::istream& operator>>(std::istream& stream, record& rec) {
    return stream >> rec.first >> rec.second;
  }
}

int main(int argc, char* argv[]) {
  for ( int i = 1; i < argc; ++i ) {
    std::ifstream stream(argv[i]);
    std::vector<record> data((std::istream_iterator<record>)(stream), std::istream_iterator<record>());
    double sum = 0;
    for ( int i = 0; i < data.size()-1; ++i ) {
      sum += (data[i].second + data[i+1].second)*(data[i+1].first - data[i].first)/2.0;
    }
    std::cout << sum / 3.0 << std::endl;
  }
}

実行結果
>trial inputA.txt inputB.txt inputC.txt
229.167
475.833
999.167

アホみたく簡単ぢゃん

投稿日時 : 2008年1月6日 0:17

コメントを追加

# re: 問題としては面白い、うん。 2008/01/06 1:34 デフォルトの名無しさん

namespace std にユーザープログラムから宣言を追加してもいいんですか?

# re: 問題としては面白い、うん。 2008/01/06 2:01 επιστημη

いけないんですか?

...てゆーか、VC++は名前空間std内に operator>>
を置かないと lookupに失敗します。

# re: 問題としては面白い、うん。 2008/01/06 2:26 アキラ

んー、基本的にはstdネームスペース内には何も追加してはいけないんですけど

http://d.hatena.ne.jp/Cryolite/20040422
この場合はいいのか悪いのか。。。

# re: 問題としては面白い、うん。 2008/01/06 2:41 はつね

現実世界での問題→コード化ですっきりしたかたちになるという、これなかなか良い問題ですよね。
だからこそちゃんと自分で解かないと全然意味がない気がしますね。

# re: 問題としては面白い、うん。 2008/01/06 2:52 επιστημη

ですよねー♪

おそらく大学での授業程度のC++ではこのコードを示したところで
"ヒエログリフ"と大差ないだろぉし、まんまコピって
提出したらぜーったいバレると目論んで晒してみたりしたりして ^^;

# re: 問題としては面白い、うん。 2008/01/06 20:09 Zクリーナ

ヒエログリフコードかっこいい
おもしろい
まねしたい

# ヒエログリフコードで遊んでみた 2008/01/06 22:54 Zクリーナ

ヒエログリフコード実際に実行してみた
プログラミング言語 C++ 第3版をひっぱり出して調べてみる
いじくってみて遊んでみた
おもしれー

std::vector<record> data((std::istream_iterator<record>)(stream), std::istream_iterator<record>());

これをわかりやすく書くと
こういうことか

std::vector<record> data;
data.assign((std::istream_iterator<record>)(stream), std::istream_iterator<record>());

assignは
引数は入力反復子でなければならない
(先頭,末尾)からのコピー

末尾は末尾じゃなくてもよい
中身空っぽでOK
ということか

namespace stdの問題もおもしろ

namespace std {
typedef std::pair<int,int> record;
std::istream& operator>>(std::istream& stream, record& rec) {
return stream >> rec.first >> rec.second;
}
}

using namespace std;

処理系によってはこう書かないと動かない
動くけどrecordが明らかに規格違反
じっくり考えてないですけど

あとエラー処理してない
まあ仕方ないけど(他人の課題だし)

# re: 問題としては面白い、うん。 2008/01/07 0:30 デフォルトの名無しさん

namespace std の中には標準テンプレートの特殊化以外を除いて
宣言を追加できないってことで、やっぱりダメみたいです。

↓で問題なくなると思います。

struct record : std::pair<int,int> {};

std::istream& operator>>(std::istream& stream, record& rec) {
return stream >> rec.first >> rec.second;
}

# re: 問題としては面白い、うん。 2008/01/07 0:40 επιστημη

いろんなコンパイラで試してみた。

VC++9, BorlandC++5.6.4, DigitalMarsC++8.42n
ではnamespace std内に置かなくてもOKですた。

# re: 問題としては面白い、うん。 2008/01/07 6:59 ゆーち

試してませんが・・・
data.size()-2
のような気がしました。


int i のループでも ++i って書くクセがついちゃったんですね。

# std問題、継承で回避か 2008/01/07 21:44 Zクリーナ

> struct record : std::pair<int,int> {};

実際に実行してみた
うまい解決方法だな
std問題、継承で回避か
つーか僕もこれと似たようなことを
エンディアンクラステンプレートでやってた
エンディアンクラステンプレートでの経験上
継承での解決は
operator T() const operatorキャストまでは継承出来ない
という落とし穴がある(他にもあるかも?)
この場合大丈夫か(と思う)

ヒエログリフも解けたし
stdも解決したし
すっきり

# 「コードがわからない」ではない?コードになる前が問題? 2008/01/08 21:47 何となく Blog by Jitta

「コードがわからない」ではない?コードになる前が問題?

# ヒエログリフコードまねしてみた 2008/01/09 22:44 Zクリーナ

mixiのC/C++の課題丸投げをヒエログリフコードで解いてみた

Sin波の信号を生成し、WAV(48kHz/16bit)フォーマットで書き出せ。
周波数と振幅は適当に決めてよい。

http://mixi.jp/view_bbs.pl?id=26784622&comm_id=602606



#include <iostream>
#include <fstream>
#include <vector>
#include <iterator>
#include <stdexcept>
#include <math.h>

#define loop(n) if(1) for(unsigned long loop_i_=(n)+1; --loop_i_!=0;)

#ifdef __BCPLUSPLUS__
//C++Builder定義済み
#elif _MSC_VER //MS系コンパイラ
//MS系コンパイラ定義済み
#elif __GNUC__ //gcc系コンパイラのマクロ
#define __int16 short
#define __int32 int
#define __int64 long long
#else
#define __int16 short
#define __int32 int
#endif

#include "wave.h"
#include "endian.h"

struct stereo : std::pair<L_endian<__int16>,L_endian<__int16> >{
stereo(const L_endian<__int16>& f,const L_endian<__int16>& s){
STATIC_CHECK(sizeof(stereo)==4,stereo_size);
first = f;
second = s;
}
};
//typedef std::pair<L_endian<__int16>,L_endian<__int16> > stereo;
std::ostream& operator<<(std::ostream& stream, const stereo& ste) {
stream.write(reinterpret_cast<const char*>(&ste),sizeof(ste));
return stream;
}

static const int vol=1024; //音量
static const double fre=0.25; //周波数
static const int sec=10; //秒

using namespace std;
int main()
{
try {
ofstream ofstream_("test.wav",ios::binary);
if(!ofstream_.is_open()){
throw runtime_error("file_open_error");
}
WAVE_HEADER WAVE_HEADER_;
WAVE_HEADER_.bit_(16);
WAVE_HEADER_.channel_(2); //ステレオ
WAVE_HEADER_.rate_(48000); //サンプリング周波数
WAVE_HEADER_.dataSize_(WAVE_HEADER_.bps*sec);

ofstream_.write(reinterpret_cast<const char*>(&WAVE_HEADER_),sizeof(WAVE_HEADER_));
ostream_iterator<stereo> o_iterator_(ofstream_);
int i=0;
loop(WAVE_HEADER_.dataSize/WAVE_HEADER_.bpb){
*o_iterator_=stereo(0,sin(i++*fre)*vol);
++o_iterator_;
}
cout << "no_error\n";
return 0;
}catch(exception& e){
cout << e.what() << "\n";
return -1;
}
}

タイトル
名前
URL
コメント