2010年01月11日

人材獲得作戦・4 試験問題

人材獲得作戦・4 試験問題というのがあったのでやってみました。

60分で以下のコードができました。
内訳は以下の通り。

入力ファイルを読み込んでメモリに落とすコード10分
最小値を検索するコード(関数FindRoot)29分
最小ルートを$に置き換える関数(関数MapRoot)10分
空白マップのときの処理時間が長いことに気がついて修正8分
不要なコード削除、入出力周り整理3分

入出力周りや、細かいバグで結構時間を取られました。 こういうのを30分以下でできる人は凄いと思います。

コード
#include <iostream>
#include <fstream>
#include <string>
#include <vector>

using namespace std;

int StartX = 0;
int StartY = 0;
int GoalX = 0;
int GoalY = 0;
vector<string> Maze;
vector<basic_string<int> > Answer;

void FindRoot(int x, int y, int level);
void MapRoot(int x, int y);

int main(int argc, char* argv[])
{
  for (size_t y = 0; !cin.eof(); ++y) {
    string line;
    getline(cin, line);
    for (size_t x = 0; x < line.size(); ++x) {
      switch (line[x]) {
      case 'S':
        StartX = x;
        StartY = y;
        break;
      case 'G':
        GoalX = x;
        GoalY = y;
        break;
      }
    }
    basic_string<int> answer(line.size(), 0);
    Maze.push_back(line);
    Answer.push_back(answer);
  }

  FindRoot(StartX, StartY, 1);
  MapRoot(GoalX, GoalY);

  for (size_t y = 0; y < Maze.size(); y++) {
    cout << Maze[y] << endl;
  }
  return 0;
}

void FindRoot(int x, int y, int level)
{
  Answer[y][x] = 1;
  for (int level = 1, goal = 0; !goal; ++level) {
    for (size_t y = 0; y < Maze.size(); ++y) {
      for (size_t x = 0; x < Maze[y].size(); ++x) {
        if (Answer[y][x] == level) {
          for (int xp = -1, yp = 0, i = 0; i < 4; xp += yp, yp = xp - yp, xp = yp - xp, ++i) {
            char c = Maze[y + yp][x + xp];
            int a = Answer[y + yp][x + xp];
            if (c != '*' && (a == 0 || level < a)) {
              Answer[y + yp][x + xp] = level + 1;
              if (x + xp == GoalX && y + yp == GoalY) {
                goal = 1;
              }
            }
          }
        }
      }
    }
  }
}

void MapRoot(int x, int y)
{
  int a = Answer[y][x];
  for (int xp = -1, yp = 0, i = 0; i < 4; xp += yp, yp = xp - yp, xp = yp - xp, ++i) {
    if (x + xp == StartX && y + yp == StartY) {
      break;
    }
    int b = Answer[y + yp][x + xp];
    if (Answer[y + yp][x + xp] == a - 1) {
      Maze[y + yp][x + xp] = '$';
      MapRoot(x + xp, y + yp);
      break;
    }
  }
}

関数とか使わなくてもできましたね。

出力例
**************************
*S* *$$$$                *
*$* *$ *$ *************  *
*$*$$$* $  ************  *
*$$$ *  $$$$$$$          *
**************$***********
* $$$$$$$$$$$$$          *
**$***********************
* $$$  *$$$$$$$$$$$$$$G  *
*  *$$$$$ *********** *  *
*    *        ******* *  *
*       *                *
**************************
**************************
*S                       *
*$                       *
*$                       *
*$                       *
*$                       *
*$                       *
*$                       *
*$                       *
*$                       *
*$                       *
*$$$$$$$$$$$$$$$$$$$$$$$G*
**************************

2010年01月09日

日本「半導体」敗戦

日本「半導体」敗戦 という本を読みましたので感想を書いておきます。

1990年頃は世界シェアトップだった日本の半導体産業が、その後10年位で韓国や台湾に追い抜かれてしまった原因を分析した本です。
ざっくりと要約すると、昔のコンピュータは大型で高価なものが主流であり、日本が製造する高品質で高価な半導体と合うものだったのですが、 コンピュータの低価格化が始まっていくと、韓国や台湾の低品質で安価な半導体の方が売れてしまったというお話です。
日本の半導体メーカは、低品質で安価な半導体を作ることができなかったのです。 その理由の一つとしては、筆者は、既存製品より品質を落とせない企業体質を挙げています。
私も、既存製品以下の品質だとダメと言われる場面に遭遇したことは何度もありますので、 身につまされました。
結局のところ、品質を上げるコストが品質ロスコストを上回った時点で、品質を上げる取り組みはストップするべきなのでしょう。 あとは、それぞれのコストの見積もり精度を高めていけば、ベストなストップポイントが見つかるのではないかと思います。

品質向上の取り組みを延々と続けることに疑念を持っている方にはお勧めの一冊です。