OpenVMS Source-Code Demos

SUDOKU1

//================================================================================
// title  : SUDOKU1.C (this is a system performance benchmark)
// author : Jan-Erik Soderholm (code)
// created: 2016.03.15
// source : https://groups.google.com/d/msg/comp.os.vms/yejgRLYuOn4/Tb7x6tAKBgAJ
// edit   : Neil Rieck (notes + added time display)
// compile: HP-C on OpenVMS
//		cc/arch=host/optim=(level=5,tune=host) file.c
//	    HP-CXX on OpenVMS
//		cxx/arch=host/optim=(level=5,tune=host) file.c
//	    Other (UNIX, Linux, CodeBlocks IDE)
//		use the highest level of switch "-O" available
// notes  : 1. this program compiled without errors or warnings on my fully patched
//		OpenVMS-8.4 systems (both Alpha and Itanium) in 2016
//	    2. Final output for reference. Everyone's run should produce this output
//		after 20,000 iterations (it is not a valid Sudoku solution, just the
//		last one tried)
//	+-----+-----+-----+
//	|5|0|0|0|9|3|0|0|6|
//	|0|1|4|0|6|0|5|7|4|
//	|0|3|0|0|0|1|0|0|9|
//	+-----+-----+-----+
//	|4|0|8|0|8|0|5|0|3|
//	|7|3|6|1|6|0|7|5|0|
//	|0|0|0|0|5|0|0|6|1|
//	+-----+-----+-----+
//	|5|5|1|1|0|9|0|0|5|
//	|7|0|0|1|0|9|0|1|0|
//	|0|7|0|0|3|1|9|7|1|
//	+-----+-----+-----+
//	Total solved:9
//=================================================================================
#include <stdio.h>			//
#ifdef __VMS
typedef unsigned int uint32_t;
typedef unsigned long long int uint64_t;
#else
#include <inttypes.h>			//
#endif
#include <time.h>			//

static uint32_t temper(uint32_t x)
{
  x ^= x>>11;
  x ^= x<<7 & 0x9D2C5680;
  x ^= x<<15 & 0xEFC60000;
  x ^= x>>18;
  return x;
}

uint32_t rand()
{
  static uint64_t seed = 533423;
  seed = 6364136223846793005ULL * seed + 1;
  return temper(seed >> 32);
}

int isAvailable(int puzzle[][9], int row, int col, int num)
{
  int rowStart = (row/3) * 3;
  int colStart = (col/3) * 3;
  int i;

  for(i=0; i<9; ++i) {
    if (puzzle[row][i] == num) return 0;
    if (puzzle[i][col] == num) return 0;
    if (puzzle[rowStart + (i%3)][colStart + (i/3)] == num) return 0;
  }
  return 1;
}

int fillSudoku(int puzzle[][9], int row, int col)
{
  int i;
  if(row<9 && col<9)
    {
      if(puzzle[row][col] != 0)
        {
          if((col+1)<9) return fillSudoku(puzzle, row, col+1);
          else if((row+1)<9) return fillSudoku(puzzle, row+1, 0);
          else return 1;
        }
      else
        {
          for(i=0; i<9; ++i)
            {
              if(isAvailable(puzzle, row, col, i+1))
                {
                  puzzle[row][col] = i+1;
                  if((col+1)<9)
                    {
                      if(fillSudoku(puzzle, row, col +1)) return 1;
                      else puzzle[row][col] = 0;
                    }
                  else if((row+1)<9)
                    {
                      if(fillSudoku(puzzle, row+1, 0)) return 1;
                      else puzzle[row][col] = 0;
                    }
                  else return 1;
                }
            }
        }
      return 0;
    }
  else return 1;
}

int main()
{
  int i=0;
  int j=0;
  int k=0;
  int l=0;
  int total_solved=0;
  int puzzle[9][9];
  time_t t;
  //---------------------------------------------
  time(&t);
  printf("Current date and time: %s",ctime(&t));
  for(l=0;l<20000;++l) {

    /* Populate the puzzle */
    for(j=0;j<9;++j) {
      for(k=0;k<9;++k) {
        if (rand()%20<10) {
          puzzle[j][k]=(rand()%9)+1;
        } else
          puzzle[j][k]=0;
      }
    }

    /* Solve it */
    total_solved += fillSudoku(puzzle, 0, 0);
  }

  /* Print the final puzzle results */
  for(i=1; i<9+1; ++i) {
    for(j=1; j<9+1; ++j)
      printf("|%d", puzzle[i-1][j-1]);
    printf("|\n");
    if (i%3 == 0) printf("+-----+-----+-----+\n");
  }
  printf("Total solved:%d\n",total_solved);
  time(&t);
  printf("Current date and time: %s",ctime(&t));
  return 0;
}