プログラミングの問題。なんか全然綺麗にかけなかったので記事にする。
問題
今、列A、B、Cがある。ここから2つの組み合わせを選びたい。 どういうふうに選ぶかというと、
- Aから1つ、Bから1つ
- Bから1つ、Cから1つ
- Aから1つ、Cから1つ
- Cから2つ
評価関数compare2 : (X, X) -> (X, X) -> bool
が与えられるときに、最大の組み合わせを選びたい。
ただしA、B、Cの長さは0かもしれず、少なくとも1つの列の長さは0より大きい。
組が作れない場合(例えばAは長さ2、Bは0、Cは0)のときは組ではなくcompare1 : X -> X -> bool
が最大であるものを選ぶ。
要素の重複は認めない。
回答
愚直に書いてもまぁそんなもんか、って感じになった。 綺麗に書きなおしてみたら以外に短かかった、、、、あれれ、、、、、、
これ、実際はAとBの型は同じなんですが、Cは違うのでかなり面倒だった感じでした。
#include <memory> #include <utility> #include <vector> // コンパイル通すために仮にintにしておく using X = int; using answer = std::pair<X*, X*>; extern bool compare2(X*, X*, X*, X*); extern bool compare1(X*, X*); std::unique_ptr<std::pair<X*, X*>> choose(std::vector<X*> A) { X* max = nullptr; for (auto a : A) { if (max == nullptr || compare1 (a, max)) { max = a; } } return std::unique_ptr<answer>(new std::pair<X*, X*>(max, max)); } std::unique_ptr<std::pair<X*, X*>> get_pair(std::vector<X*> A, std::vector<X*> B, std::vector<X*> C) { if ((A.size() == 0 && B.size()) == 0) return choose(C); if ((B.size() == 0 && C.size()) == 0) return choose(A); if ((A.size() == 0 && C.size()) == 0) return choose(B); X* max_a = nullptr; X* max_b = nullptr; auto f = [&](std::vector<X*> M, std::vector<X*> N) { for (auto & a : M) { for (auto & b : N) { if (max_a == nullptr || compare2 (a, b, max_a, max_b)) { max_a = a; max_b = b; } } } }; f (A, B); f (A, C); f (B, C); f (C, C); return std::unique_ptr<answer>(new std::pair<X*, X*>(max_a, max_b)); }