東方算程譚

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

記事カテゴリ

書庫

日記カテゴリ

週末のコード遊び: Hit&Blow

ヌメロンとかいうテレビ番組があるらしい。
つまりは古典的数当てゲーム「Hit&Blow」なんだね。

- 出題者は1~9から重複なしに3つ選び、3桁の数(正解)を作る
- 解答者はその数を推理し3桁の数(答案)を宣言する
- 出題者は正解と答案とを比較し、
  数も桁も一致している数(Hit) と
  数は合っているが桁の異なる数(Blow) を返す

これを繰り返し、少ない回数で正解を導く、と。

計算機ゲームとしては計算機が出題者となるんだろうけども、
ここでは計算機に回答者を演じてもらおう...

#include <iostream>
#include <string>
#include <array>
#include <vector>
#include <numeric>
#include <algorithm>
#include <utility>
#include <iterator>
#include <cassert>

using namespace std;

const int N = 3;
typedef array<int,N> number;
typedef pair<int,int> hb;
typedef pair<number,hb> hint;

// 各桁に0を含まず、重複のないことを確認する
bool is_good(number n) {
  if ( find(begin(n),end(n),0) != end(n) ) return false;
  sort(begin(n),end(n));
  return unique(begin(n),end(n)) == end(n);
}

// 1~9を重複なくN個選ぶ
void init_candidates(vector<number>& candidates) {
  array<int,9> digits;
  iota(begin(digits), end(digits), 1);
  array<bool,9> bits;
  fill(begin(bits),end(bits),false);
  fill_n(begin(bits), N, true);
  do {
    int c = 0;
    number tmp;
    for ( int i = 0; i < 9; ++i ) {
      if ( bits[i] ) tmp[c++] = i+1;
    }
    assert(is_good(tmp));
    do {
      candidates.push_back(tmp);
    } while ( next_permutation(begin(tmp),end(tmp)) );
  } while ( prev_permutation(begin(bits),end(bits)) );
}

// hit/blow数を勘定する
hb judge(const number& actual, const number& guess) {
  int hit = 0;
  int blow = 0;
  for ( int i = 0; i < N ; ++i ) {
    for ( int j = 0; j < N; ++j ) {
      if ( actual[i] == guess[j] ) {
        if ( i == j ) ++hit; else ++blow;
      }
    }
  }
  return hb(hit,blow);
}

ostream& operator<<(ostream& stream, const number& n) {
  for_each(begin(n),end(n),[&](int n) { stream << n;});
  return stream;
} 

ostream& operator<<(ostream& stream, const hb& h) {
  return stream << h.first << "Hit / " << h.second << "Blow";
} 

int main() {
  number answer;
  while ( true ) {
    cout << "各桁が1~9である" << N << "桁の数を入力してほしい。各桁で数が重複するのは避けてくれ" << endl;
    string str; cin >> str;
    const string digits = "123456789";
    if ( str.size() == N && all_of(begin(str),end(str),[&](char c) { return digits.find(c) != string::npos;}) ) {
      transform(begin(str), end(str), begin(answer), [](char c) { return c - '0';});
      if ( is_good(answer) ) break;
    }
  }    
  cout << "君が選んだのは " << answer << " だね。では僕がその数を推理しよう。" << endl;

  int trial = 0;
  vector<number> candidates;
  init_candidates(candidates);
  random_shuffle(begin(candidates),end(candidates));

  vector<hint> hints;
  while ( true ) {
    cout << ++trial << "回目:"
         << " 正解となる数の候補は " << candidates.size() << " あるが... ";
    number candidate = candidates.front();
    cout << candidates.front() << " ではないかな?" << endl;
    hb result = judge(answer, candidate);
    cout << result << endl;
    if ( result.first == N ) break; // 正解ならばloopを抜ける
    hints.push_back(hint(candidate,result)); // 判定結果をhintsに追加する

    // これまでに得られたhintsから候補を絞り込む
    vector<number> new_candidates;
    // 候補となる数 n について:
    for ( number n : candidates ) {
      // nがこれまでに得られたhintと矛盾がないならば、それは正解かもしれないので候補に残す
      if ( all_of(begin(hints),end(hints),[&](hint h) { return judge(n,h.first) == h.second;}) ) {
        new_candidates.push_back(n);
      }
    }
    candidates = new_candidates;
  }
}
 
/* --- 実行結果 ---
各桁が1~9である3桁の数を入力してほしい。各桁で数が重複するのは避けてくれ
918
君が選んだのは 918 だね。では僕がその数を推理しよう。
1回目: 正解となる数の候補は 504 あるが... 978 ではないかな?
2Hit / 0Blow
2回目: 正解となる数の候補は 18 あるが... 976 ではないかな?
1Hit / 0Blow
3回目: 正解となる数の候補は 10 あるが... 378 ではないかな?
1Hit / 0Blow
4回目: 正解となる数の候補は 4 あるが... 928 ではないかな?
2Hit / 0Blow
5回目: 正解となる数の候補は 3 あるが... 918 ではないかな?
3Hit / 0Blow
*/

投稿日時 : 2012年12月23日 21:43

コメントを追加

# re: 週末のコード遊び: Hit&Blow 2012/12/23 21:51 επιστημη

あ...init_candidates() のアタマ2行は要らないわ。

# re: 週末のコード遊び: Hit&Blow 2012/12/24 7:23 επιστημη

候補の絞り込みンとこ、イケてないので以下のごとく修正:

// 候補の中から、これまでに得られたhintと矛盾があるものを除外する
candidates.erase(
remove_if(begin(candidates),end(candidates),
[&](number n) {
return any_of(begin(hints),end(hints),
[&](hint h) {
return judge(n,h.first) != h.second;
});
}),
end(candidates));

# koXZvGXiuTyBzRheb 2021/07/03 4:42 https://www.blogger.com/profile/060647091882378654

You got a really useful blog I have been here reading for about an hour. I am a newbie and your success is very much an inspiration for me.

# Heya i'm for the first time here. I came across this board and I find It really useful & it helped me out much. I'm hoping to present something again and help others like you aided me. 2021/07/27 5:26 Heya i'm for the first time here. I came across th

Heya i'm for the first time here. I came across this board and I find
It really useful & it helped me out much. I'm hoping to present something again and help others like you aided me.

# Heya i'm for the first time here. I came across this board and I find It really useful & it helped me out much. I'm hoping to present something again and help others like you aided me. 2021/07/27 5:29 Heya i'm for the first time here. I came across th

Heya i'm for the first time here. I came across this board and I find
It really useful & it helped me out much. I'm hoping to present something again and help others like you aided me.

# Heya i'm for the first time here. I came across this board and I find It really useful & it helped me out much. I'm hoping to present something again and help others like you aided me. 2021/07/27 5:32 Heya i'm for the first time here. I came across th

Heya i'm for the first time here. I came across this board and I find
It really useful & it helped me out much. I'm hoping to present something again and help others like you aided me.

# Heya i'm for the first time here. I came across this board and I find It really useful & it helped me out much. I'm hoping to present something again and help others like you aided me. 2021/07/27 5:35 Heya i'm for the first time here. I came across th

Heya i'm for the first time here. I came across this board and I find
It really useful & it helped me out much. I'm hoping to present something again and help others like you aided me.

# Good day! This post could not be written any better! Reading through this post reminds me of my old room mate! He always kept chatting about this. I will forward this page to him. Fairly certain he will have a good read. Many thanks for sharing! 2021/08/04 8:17 Good day! This post could not be written any bette

Good day! This post could not be written any better!
Reading through this post reminds me of my old room mate!
He always kept chatting about this. I will forward this page to him.
Fairly certain he will have a good read. Many thanks for sharing!

# re: ????????: Hit&Blow 2021/08/08 2:49 define chloro

chloroguine https://chloroquineorigin.com/# hydroxychloroquine

# yumcgdpndkwj 2022/06/03 4:03 yoizejnc

http://erythromycin1m.com/# erythromycin ophth oint 3.5gm

タイトル
名前
URL
コメント