財産分け問題を解く

日経ソフトウェアに財産分け問題という問題が掲載されていたので解いてみた。以下、ソースです。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ncurses.h>
#include <unistd.h>

void print_map(char data[][12])
{
  int i;

  for(i = 1; i < 11; i++) {
    mvprintw(i, 0, "%s\n", &data[i][1]);
  }
  refresh();
  usleep(3 * 1000 * 100);

}

void read_map(char data[][12])
{
  FILE *fp;
  int i, j;
  char buff[12];

  if((fp = fopen("data.dat", "r")) == NULL) {
    printf("file open error\n");
    exit(1);
  }

  /* 初期化 */
  for(i = 0; i < 12; i++) {
    for(j = 0; j < 12; j++) {
      data[i][j] = ' ';
    }
  }
  
  for(i = 1; i < 11; i++) {
    fscanf(fp, "%s", buff);
    strcpy(&data[i][1], buff);
  }
  
  fclose(fp);
}

int walk(char map[][12], int i, int j, char c)
{
  map[i][j] = ' ';

  if(map[i+1][j] == c) walk(map, i+1, j    , c);
  if(map[i][j+1] == c) walk(map, i,   j + 1, c);
  if(map[i-1][j] == c) walk(map, i-1, j    , c);
  if(map[i][j-1] == c) walk(map, i,   j  -1, c);

  return 1;
}

int count_kukaku(char map[][12])
{
  int sum = 0;
  int i, j;

  for(i = 1; i < 11; i++) {
    for(j = 1;j < 11; j++) {
      if(map[i][j] != ' ') {
	sum += walk(map, i, j, map[i][j]);
	print_map(map);
      }
    }
  }
  return sum;
}

int main()
{
  char map[12][12];
  int ret;

  initscr();

  read_map(map);
  print_map(map);
  ret = count_kukaku(map);
  mvprintw(0, 0, "kukaku = %d\n", ret);
  refresh();
  usleep(3 * 1000 * 1000);
  endwin();

  return 0;
}

あまりソースを晒さないので新鮮だ。ソースを晒すとよりプログラムに精通した人から何らかの指摘をしてもらうことができ、結果として自分のレベルが上がると思うので、これからは積極的に晒して行こうと思う。