Saturday, May 16, 2009

[PC]Where's Wardorf?

3n+1이후 2문제의 WA로 은근히 맘고생이였는데, 동현님 입/출력 처리를 보고 Solve하여 자신감이 붙었네요.

동현님이 사용한 8방향에 대한 참조테이블을 이용하는 방법같은 작지만 효율적인 기법에 대해서는 수련을 더 해야 할 듯.

그리고 스터디 시간에 잠시 이야기했지만, 보충하자면...

STL 경우 컨테이너 변경시 로직 변경을 최소화할 수 있는 것과 같이, 함수 입/출력을 잘 설계하면 자료 구조(1차원배열, 2차원배열 심지어 vector<string> 등등) 변경시 수정을 최소화 시킬 수 있을 것입니다.

단위테스트도 쉬워질 것이고요.

결국 입/출력 설계를 잘 하는 것이 테스트 가능한 프로그램을 만드는 것이고 재사용 가능한 모듈을 만들 수 있다는 것입니다.

HFSD 스터디랑 겹치고 있네요ㅡㅜ

#include <iostream>
#include <vector>
#include <string>
#include <string.h>

#define ONLINE_JUDGE

using namespace std;

#define MAX_INPUT 50

enum direction
{
 direction_right = 0,
 direction_rightdown,
 direction_down,
 direction_leftdown,
 direction_left,
 direction_leftup,
 direction_up,
 direction_rightup
};

char input[MAX_INPUT][MAX_INPUT] = {0x00};
char word[MAX_INPUT][MAX_INPUT] = {0x00};

char charbypos(int row, int col)
{
 return input[row][col];
}

void rightstring(int row, int col, int maxrow, int maxcol, string& out)
{
 for(int i=col; i<maxcol; ++i)
  out.push_back(charbypos(row, i));
}

void rightdownstring(int row, int col, int maxrow, int maxcol, string& out)
{
 int i, j;
 for(i=col, j=row; i<maxcol && j<maxrow; ++i, ++j)
  out.push_back(charbypos(j, i));
}

void downstring(int row, int col, int maxrow, int maxcol, string& out)
{
 for(int i=row; i<maxrow; ++i)
  out.push_back(charbypos(i, col));
}

void leftdownstring(int row, int col, int maxrow, int maxcol, string& out)
{
 int i, j;
 for(i=col, j=row; 0<=i && j<maxrow; --i, ++j)
  out.push_back(charbypos(j, i));
}

void leftstring(int row, int col, int maxcol, int maxrow, string& out)
{
 for(int i=col; 0<=i; --i)
  out.push_back(charbypos(row, i));
}

void leftupstring(int row, int col, int maxrow, int maxcol, string& out)
{
 int i, j;
 for(i=col, j=row; 0<=i && 0<=j; --i, --j)
  out.push_back(charbypos(j, i));
}

void upstring(int row, int col, int maxrow, int maxcol, string& out)
{
 for(int i=row; 0<=i; --i)
  out.push_back(charbypos(i, col));
}

void rightupstring(int row, int col, int maxrow, int maxcol, string& out)
{
 int i, j;
 for(i=col, j=row; i<maxcol && 0<=j; ++i, --j)
  out.push_back(charbypos(j, i));
}

void stringbypos(int row, int col, int maxrow, int maxcol, direction direct, string& out)
{
 switch(direct)
 {
 case direction_right:
  rightstring(row, col, maxrow, maxcol, out);
  break;
 case direction_rightdown:
  rightdownstring(row, col, maxrow, maxcol, out);
  break;
 case direction_down:
  downstring(row, col, maxrow, maxcol, out);
  break;
 case direction_leftdown:
  leftdownstring(row, col, maxrow, maxcol, out);
  break;
 case direction_left:
  leftstring(row, col, maxrow, maxcol, out);
  break;
 case direction_leftup:
  leftupstring(row, col, maxrow, maxcol, out);
  break;
 case direction_up:
  upstring(row, col, maxrow, maxcol, out);
  break;
 case direction_rightup:
  rightupstring(row, col, maxrow, maxcol, out);
  break;
 }
}

void positionbyword(char* word, int maxrow, int maxcol, int& x, int& y)
{
 for(int i=0; i<maxrow; ++i)
 {
  for(int j=0; j<maxcol; ++j)
  {
   if(word[0] == charbypos(i, j))
   {
    for(int d=0; d<=(int)direction_rightup; ++d)
    {
     string out;
     stringbypos(i, j, maxrow, maxcol, (direction)d, out);
     if(0 == strncmp(word, out.c_str(), strlen(word)))
     {
      x = i;
      y = j;
      return;
     }
    }
   }
  }
 }
}

void strlower(char* in, char*& out)
{
 int len = strlen(in);
 for(int i=0; i<len; ++i)
 {
  out[i] = in[i];
 }
}

#ifdef ONLINE_JUDGE

int main(int argc, char **argv)
{
 int casecount = 0;
 cin >> casecount;

 while(casecount--)
 {
  int row = 0;
  int col = 0;
  int count = 0;

  memset(input, 0x00, MAX_INPUT*MAX_INPUT);
  memset(word, 0x00, MAX_INPUT*MAX_INPUT);

  cin >> row >> col;

  for(int i=0; i<row; ++i)
  {
   char in[MAX_INPUT] = {0x00};
   cin >> in;
   int n = strlen(in);
   for(int j=0; j<n; ++j)
   {
    input[i][j] = tolower(in[j]);
   }
  }

  cin >> count;

  for(int i=0; i<count; ++i)
  {
   char in[MAX_INPUT] = {0x00};
   cin >> in;
   
   int n = strlen(in);
   for(int j=0; j<n; ++j)
   {
    word[i][j] = tolower(in[j]);
   }
  }

  for(int i=0; i<count; ++i)
  {
   int x = 0;
   int y = 0;
   positionbyword(&word[i][0], row, col, x, y);

   cout << x+1 << " " << y+1 << endl;
  }

  if(0 < casecount)
   cout << endl;
 }

 return 0;
}

#else

#include <gtest/gtest.h>
#pragma comment(lib, "gtest")

class testinput : public ::testing::Test
{
protected:
 ~testinput()
 {
 }
 virtual void SetUp()
 {
  strcpy(&input[0][0], "abcDEFGhigg");
  strcpy(&input[1][0], "hEbkWalDork");
  strcpy(&input[2][0], "FtyAwaldORm");
  strcpy(&input[3][0], "FtsimrLqsrc");
  strcpy(&input[4][0], "byoArBeDeyv");
  strcpy(&input[5][0], "Klcbqwikomk");
  strcpy(&input[6][0], "strEBGadhrb");
  strcpy(&input[7][0], "yUiqlxcnBjf");
 }
};

TEST_F(testinput, rightupdirection)
{
 string out;
 rightupstring(0, 0, 8, 11, out);
 ASSERT_STREQ("a", out.c_str());

 out = "";
 rightupstring(0, 10, 8, 11, out);
 ASSERT_STREQ("g", out.c_str());

 out = "";
 rightupstring(4, 0, 8, 11, out);
 ASSERT_STREQ("btykE", out.c_str());

 out = "";
 rightupstring(7, 0, 8, 11, out);
 ASSERT_STREQ("ytcAmalh", out.c_str());

 out = "";
 rightupstring(7, 8, 8, 11, out);
 ASSERT_STREQ("Brk", out.c_str());
}


TEST_F(testinput, updirection)
{
 string out;
 upstring(0, 0, 8, 11, out);
 ASSERT_STREQ("a", out.c_str());

 out = "";
 upstring(0, 10, 8, 11, out);
 ASSERT_STREQ("g", out.c_str());

 out = "";
 upstring(4, 10, 8, 11, out);
 ASSERT_STREQ("vcmkg", out.c_str());

 out = "";
 upstring(7, 5, 8, 11, out);
 ASSERT_STREQ("xGwBraaF", out.c_str());
}

TEST_F(testinput, leftupdirection)
{
 string out;
 leftupstring(0, 0, 8, 11, out);
 ASSERT_STREQ("a", out.c_str());

 out = "";
 leftupstring(0, 10, 8, 11, out);
 ASSERT_STREQ("g", out.c_str());

 out = "";
 leftupstring(4, 10, 8, 11, out);
 ASSERT_STREQ("vrODG", out.c_str());

 out = "";
 leftupstring(7, 10, 8, 11, out);
 ASSERT_STREQ("froDLaWD", out.c_str());

 out = "";
 leftupstring(7, 8, 8, 11, out);
 ASSERT_STREQ("BdiBmAbb", out.c_str());
}

TEST_F(testinput, leftdirection)
{
 string out;
 leftstring(0, 0, 8, 11, out);
 ASSERT_STREQ("a", out.c_str());

 out = "";
 leftstring(0, 10, 8, 11, out);
 ASSERT_STREQ("ggihGFEDcba", out.c_str());

 out = "";
 leftstring(4, 10, 8, 11, out);
 ASSERT_STREQ("vyeDeBrAoyb", out.c_str());

 out = "";
 leftstring(7, 5, 8, 11, out);
 ASSERT_STREQ("xlqiUy", out.c_str());
}

TEST_F(testinput, leftdowndirection)
{
 string out;
 leftdownstring(0, 0, 8, 11, out);
 ASSERT_STREQ("a", out.c_str());

 out = "";
 leftdownstring(0, 10, 8, 11, out);
 ASSERT_STREQ("grOqewBq", out.c_str());

 out = "";
 leftdownstring(4, 10, 8, 11, out);
 ASSERT_STREQ("vmhn", out.c_str());

 out = "";
 leftdownstring(0, 5, 8, 11, out);
 ASSERT_STREQ("FWAsyK", out.c_str());
}

TEST_F(testinput, downdirection)
{
 string out;
 downstring(0, 0, 8, 11, out);
 ASSERT_STREQ("ahFFbKsy", out.c_str());

 out = "";
 downstring(5, 10, 8, 11, out);
 ASSERT_STREQ("kbf", out.c_str());

 out = "";
 downstring(7, 10, 8, 11, out);
 ASSERT_STREQ("f", out.c_str());
}

TEST_F(testinput, rightdowndirection)
{
 string out;
 rightdownstring(0, 0, 8, 11, out);
 ASSERT_STREQ("aEyirwan", out.c_str());

 out = "";
 rightdownstring(0, 5, 8, 11, out);
 ASSERT_STREQ("Fldsyk", out.c_str());

 out = "";
 rightdownstring(0, 3, 8, 11, out);
 ASSERT_STREQ("DWaLDorf", out.c_str());
}

TEST_F(testinput, rightdirection)
{
 string out;
 rightstring(0, 0, 8, 11, out);
 ASSERT_STREQ("abcDEFGhigg", out.c_str());

 out = "";
 rightstring(0, 10, 8, 11, out);
 ASSERT_STREQ("g", out.c_str());

 out = "";
 rightstring(7, 10, 8, 11, out);
 ASSERT_STREQ("f", out.c_str());
}

TEST_F(testinput, accessinput)
{
 ASSERT_EQ('a', charbypos(0, 0));
 ASSERT_EQ('g', charbypos(0, 10));
 ASSERT_EQ('h', charbypos(1, 0));
 ASSERT_EQ('k', charbypos(1, 10));
 ASSERT_EQ('y', charbypos(7, 0));
 ASSERT_EQ('f', charbypos(7, 10));
}

int main(int argc, char **argv) 
{
 ::testing::InitGoogleTest(&argc, argv);
 return RUN_ALL_TESTS();
}

#endif

No comments:

Post a Comment