Commit 29db56eb authored by Seblu's avatar Seblu
Browse files

No commit message

No commit message
parent dd5dd234
Loading
Loading
Loading
Loading

grids/easy/metro-224

0 → 100644
+9 −0
Original line number Diff line number Diff line
0 6 0 3 0 0 0 0 7
0 0 0 1 0 0 0 5 9
8 7 0 9 0 0 0 0 0
0 9 0 6 5 0 2 0 1
0 0 0 0 0 0 0 0 0
5 0 1 0 2 7 0 4 0
0 0 0 0 0 6 0 3 2
3 8 0 0 0 4 0 0 0
4 0 0 0 0 9 0 6 0

grids/easy/metro-225

0 → 100644
+9 −0
Original line number Diff line number Diff line
3 0 0 6 1 2 0 0 9
0 0 0 0 0 8 6 0 0
0 6 9 4 0 0 8 0 0
1 9 0 2 0 6 7 0 4
5 0 0 0 0 0 0 0 6
6 0 8 9 0 7 0 1 2
0 0 1 0 0 5 3 4 0
0 0 6 8 0 0 0 0 0
8 0 0 3 2 9 0 0 7
+27 −11
Original line number Diff line number Diff line
#ifndef BLOCK_HXX_
# define BLOCK_HXX_

inline Block::Block()
{
  Block(0);
}

inline Block::Block(int value) {
inline Block::Block(int value = 0) {
  value_ = value;
  for (int i = 0; i < GRID_SIDE; ++i)
    forbidden_[i] = false;
}

inline bool Block::is_forbidden(int value) const {
  assert(value > 0 && value <= GRID_SIDE);
  if (!(value > 0 && value <= GRID_SIDE))
    throw std::string("Invalid is_forbidden value");
  return forbidden_[value - 1];
}

@@ -21,22 +17,32 @@ inline bool Block::is_set() const {
  return value_ != 0;
}

inline int Block::value_get() const
inline int Block::get() const
{
  return value_;
}

inline void Block::set(int val)
{
  assert(val > 0 && val <= GRID_SIDE);
  if (!(val > 0 && val <= GRID_SIDE))
    throw std::string("Invalid value");
  if (value_ != 0)
    throw std::string("Value already set");
  if (forbidden_[val - 1])
    throw std::string("Set a forbidden value");
  value_ = val;
  for (int i = 0; i < GRID_SIDE; ++i)
  for (register int i = 0; i < GRID_SIDE; ++i)
    forbidden_[i] = true;
}

inline void Block::forbid(int val) {
  assert(val > 0 && val <= GRID_SIDE);
  if (!(val > 0 && val <= GRID_SIDE))
    throw std::string("Invalid forbid value");
  if (value_ != 0)
    throw std::string("Try to forbid whereas case is set");
  forbidden_[val - 1] = true;
  if (forbidden_count() == GRID_SIDE)
    throw std::string("All possibilities are forbidden.");
}

inline std::ostream &operator<<(std::ostream &stream, const Block &blk) {
@@ -47,4 +53,14 @@ inline std::ostream &operator<<(std::ostream &stream, const Block &blk) {
  return stream;
}

inline int Block::forbidden_count() const
{
  int count = 0;

  for (int i = 0; i < GRID_SIDE; ++i)
    if (forbidden_[i])
      ++count;
  return count;
}

#endif
+61 −15
Original line number Diff line number Diff line
@@ -17,15 +17,12 @@ int Grid::load(const char *filename)
  for (int y = 0; y < GRID_SIDE; ++y)
    for (int x = 0; x < GRID_SIDE; ++x) {
      fs >> std::dec >> val;
//       if (val > 0)
// 	std::cout << "(" << x << "," << y << ")" << " " << val << std::endl;
      if (val < 0 || val > 9) {
	std::cerr << "Invalid value in file: " << val << std::endl;
	exit(EXIT_LOADFAIL);
      }
      if (val > 0)
	pose(x, y, val);
      //block_[i][j].set(val);
    }
  fs.close();
  return 1;
@@ -45,20 +42,67 @@ void Grid::pose(int x, int y, int v)
    std::cerr << "Double positionning: " << x << ", " << y << std::endl;
    exit(EXIT_INV_VAL);
  }
  try {
    block_[x][y].set(v);
  }
  catch (std::string s) {
    std::cerr << "Unable to pose " << v << " in (" << x << "," << y << "): "
	      << s << std::endl;
    throw 2;
  }
  for (int i = 0; i < GRID_SIDE; ++i) {
    try {
      block_[x][i].forbid(v);
    }
    catch (std::string s) {
      std::cerr << "Unable to forbid " << v << " in (" << x << "," << y << "): "
		<< s << std::endl;
    }
    try {
      block_[i][y].forbid(v);
    }
    catch (std::string s) {
      std::cerr << "Unable to forbid " << v << " in (" << x << "," << y << "): "
		<< s << std::endl;
    }
  }
  for (int i = 0; i < 3; ++i)
    for (int j = 0; j < 3; ++j)
      {
      std::cout << "forbid x:"<< x << ", y:" << y << ",i:" <<i <<",j;" <<j <<std::endl;
      block_[(x / 3) * 3 + i][(y / 3) * 3 + j].forbid(v);

      }
}

void Grid::resolve()
{
  int posed;

  if (Grid::verbose)
    std::cout << "Resolving..." << std::endl;
  do {
    posed = 0;
    for (int y = 0; y < GRID_SIDE; ++y)
      for (int x = 0; x < GRID_SIDE; ++x) {
	if (block_[x][y].is_set())
	  continue;
	//check for complete block
	int count = 0, lastval;
	for (int i = 1; i <= GRID_SIDE; ++i)
	  if (!block_[x][y].is_forbidden(i)) {
	    ++count;
	    lastval = i;
	}
	if (count == 1) {
	  pose(x, y, lastval);
	  if (Grid::verbose)
	    std::cout << "posed " << lastval << " to " << x << ","<< y << std::endl;
	  ++posed;
	}
      }
  }
  while (posed > 0);
}

void Grid::print() const
@@ -76,7 +120,7 @@ void Grid::print() const
	    std::cout << "| ";
	  std::cout << "|";
	  for (int j = i * 3 + 1; j <= i * 3 + 3; ++j)
	    if (block_[x][y].value_get() == j)
	    if (block_[x][y].get() == j)
	      std::cout << "\033[0;32m" << j << "\033[0m";
	    else if (block_[x][y].is_forbidden(j))
	      std::cout << "\033[0;31m" << j << "\033[0m";
@@ -102,7 +146,7 @@ bool Grid::is_done() const
{
  for (int i = 0; i < GRID_SIDE; ++i)
    for (int j = 0; j < GRID_SIDE; ++j)
      if (block_[i][j].value_get() == 0)
      if (block_[i][j].get() == 0)
	return false;
  return true;
}
@@ -119,12 +163,12 @@ bool Grid::verify() const
      horizontal_line[j] = vertical_line[j] = false;
    for (int j = 0; j < GRID_SIDE; ++j) {
      //horizontals
      tmp = block_[i][j].value_get() - 1;
      tmp = block_[i][j].get() - 1;
      if (tmp < 0 || horizontal_line[tmp])
	return false;
      horizontal_line[tmp] = true;
      //verticals
      tmp = block_[j][i].value_get() - 1;
      tmp = block_[j][i].get() - 1;
      if (tmp < 0 || vertical_line[tmp] == true)
	return false;
      vertical_line[tmp] = true;
@@ -133,6 +177,7 @@ bool Grid::verify() const
      if (!vertical_line[j] || !horizontal_line[j])
	return false;
  }
  std::cout << "sex" << std::endl;
  // check nine blocks (use vertical_block)
  for (int j = 0; j < GRID_SIDE; ++j)
    vertical_line[j] = false;
@@ -140,11 +185,12 @@ bool Grid::verify() const
    for (int j = 0; j < GRID_SIDE; j += 3)
      for (int k = 0; k < 3; ++k)
	for (int l = 0; l < 3; ++l) {
	  tmp = block_[i + k][j + l].value_get() - 1;
	  tmp = block_[i + k][j + l].get() - 1;
	  if (tmp < 0 || vertical_line[tmp] == true)
	    return false;
	  vertical_line[tmp] = true;
	}
  std::cout << "city" << std::endl;
  for (int j = 0; j < GRID_SIDE; ++j)
    if (!vertical_line[j])
      return false;
+27 −14
Original line number Diff line number Diff line
#include <stdlib.h>
#include <unistd.h>
#include "sudoku.hh"

inline static void usage();

int main(int argc, char *argv[])
{
  int found;
  int opt;

  if (argc != 2 && argc !=3) {
    std::cerr << "Usage: sudoku [-v] file" << std::endl;
    return EXIT_USAGE;
  if (argc != 2 && argc !=3)
    usage();
  while ((opt = getopt(argc, argv, "vx")) != -1)
    switch (opt) {
    case 'v': Grid::verbose = true; break;
    case 'x': Grid::advprint = true; break;
    default: usage();
    }
  if (argc == 3 && argv[1] == (std::string) "-v")
    Grid::verbose = true;
  if (argc == 3 && argv[1] == (std::string) "-p")
    Grid::advprint = true;
  Grid *grid = new Grid();
  if (!grid->load(argv[Grid::verbose || Grid::advprint ? 2 : 1])) {
  if (!grid->load(argv[optind])) {
    std::cerr << "Loading failed !" << std::endl;
    return EXIT_LOADFAIL;
  }
@@ -23,10 +26,20 @@ int main(int argc, char *argv[])
    grid->print();
  }
  grid->resolve();
  found = grid->verify() ? EXIT_FOUND : EXIT_NOTFOUND;
  if (found == EXIT_FOUND && Grid::verbose > 0)
    std::cout << "Solution found." << std::endl;
  grid->print();
  return found;
  if (grid->verify()) {
    if (Grid::verbose)
      std::cout << "Solution found." << std::endl;
    return EXIT_FOUND;
  }
  std::cout << "No suitable solution found." << std::endl;
  return EXIT_NOTFOUND;
}

inline static void usage()
{
  std::cerr << "Usage: sudoku [-vx] file" << std::endl;
  std::cerr << "Options:   -v: Verbose mode" << std::endl;
  std::cerr << "           -x: eXtended print mode" << std::endl;
  exit(EXIT_USAGE);
}
Loading