Exemple #1
0
/*
 * big integer unsigned division by single digit divisor
 *
 * dividend in bip.rem, divisor in parameter
 * quotient in bip.rem, remainder is returned
 */
static unsigned char bigUdiv1(unsigned char divisor) {
  ObjRef tmp;
  int nd;
  int i;
  unsigned short d, r;
  unsigned short aux;

  /* get size of dividend */
  nd = GET_ND(bip.rem);
  /* check for division by zero */
  d = (unsigned short) divisor;
  if (d == 0) {
    fatalError("internal library error #3 - THIS SHOULD NEVER HAPPEN!");
  }
  /* allocate result */
  tmp = newBig(nd);
  /* tmp = dividend / divisor, r = dividend % divisor */
  r = 0;
  for (i = nd - 1; i >= 0; i--) {
    aux = (r << 8) | (unsigned short) GET_DIGIT(bip.rem, i);
    SET_DIGIT(tmp, i, aux / d);
    r = aux % d;
  }
  /* determine actual size of quotient */
  i = nd;
  while (--i >= 0 && GET_DIGIT(tmp, i) == 0) ;
  SET_ND(tmp, i + 1);
  /* store quotient */
  bip.rem = tmp;
  /* return remainder */
  return (unsigned char) r;
}
Exemple #2
0
/*
 * big integer unsigned multiplication
 *
 * operands in bip.op1 and bip.op2
 * result in bip.res
 */
static void bigUmul(void) {
  int nd1;
  int nd2;
  int i, j, k;
  unsigned short carry;
  unsigned short aux;

  /* get sizes of operands */
  nd1 = GET_ND(bip.op1);
  nd2 = GET_ND(bip.op2);
  /* allocate result */
  bip.res = newBig(nd1 + nd2);
  /* reset lower nd1 digits of result */
  for (i = 0; i < nd1; i++) {
    SET_DIGIT(bip.res, i, 0);
  }
  /* res = op1 * op2 */
  for (j = 0; j < nd2; j++) {
    carry = 0x00;
    for (k = j, i = 0; i < nd1; k++, i++) {
      aux = (unsigned short) GET_DIGIT(bip.op1, i) *
            (unsigned short) GET_DIGIT(bip.op2, j) +
            (unsigned short) GET_DIGIT(bip.res, k) +
            carry;
      SET_DIGIT(bip.res, k, aux & 0xFF);
      carry = aux >> 8;
    }
    SET_DIGIT(bip.res, k, carry);
  }
  /* determine actual size of result */
  i = nd1 + nd2;
  while (--i >= 0 && GET_DIGIT(bip.res, i) == 0) ;
  SET_ND(bip.res, i + 1);
}
Exemple #3
0
/*
 * big integer unsigned addition
 *
 * operands in bip.op1 and bip.op2
 * result in bip.res
 */
static void bigUadd(void) {
  int nd1;
  int nd2;
  int i;
  unsigned short carry;
  unsigned short aux;
  int xchgFlag;

  /* make sure op1 has at least as many digits as op2 */
  nd1 = GET_ND(bip.op1);
  nd2 = GET_ND(bip.op2);
  if (nd1 < nd2) {
    /* exchange operands */
    bigXchg();
    i = nd1;
    nd1 = nd2;
    nd2 = i;
    xchgFlag = 1;
  } else {
    /* don't exchange operands */
    xchgFlag = 0;
  }
  /* allocate result */
  bip.res = newBig(nd1 + 1);
  /* copy op2 to result */
  for (i = 0; i < nd2; i++) {
    SET_DIGIT(bip.res, i, GET_DIGIT(bip.op2, i));
  }
  /* fill result with 0 up to size of op1 */
  for (; i < nd1; i++) {
    SET_DIGIT(bip.res, i, 0);
  }
  /* res = op1 + res */
  carry = 0x00;
  for (i = 0; i < nd1; i++) {
    aux = (unsigned short) GET_DIGIT(bip.op1, i) +
          (unsigned short) GET_DIGIT(bip.res, i) +
          carry;
    SET_DIGIT(bip.res, i, aux & 0xFF);
    carry = aux >> 8;
  }
  SET_DIGIT(bip.res, i, carry);
  /* determine actual size of result */
  i = nd1 + 1;
  while (--i >= 0 && GET_DIGIT(bip.res, i) == 0) ;
  SET_ND(bip.res, i + 1);
  /* restore operands */
  if (xchgFlag) {
    bigXchg();
  }
}
Exemple #4
0
std::tuple<vector<unsigned int>, vector<unsigned int>, vector<unsigned int>> compute_G_P_L_EI_arrays(const vector<T> &lst,
                                                                                                     const vector<vector<unsigned int>> &prefix_summed_bucket_table,
                                                                                                     const vector<unsigned int> &t_primes_summed,
                                                                                                     const vector<unsigned int> &t_primes_exscanned,
                                                                                                     unsigned int (*key_func)(const T&),
                                                                                                     const unsigned int k,
                                                                                                     const unsigned int offset) {

    vector<unsigned int> G_EI(lst.size(), 0),
                         P_EI(lst.size(), 0),
                         L_EI(lst.size(), 0);

    for (int i=0; i < lst.size(); ++i) {
        // Get the current digit
        unsigned int key = key_func(lst[i]);
        unsigned int d_i = GET_DIGIT(key, k, offset);

        // Sum up the T''s to get the total number of elements with digit smaller than the current digit
        for (int j=0; j < d_i; ++j) {
            G_EI[i] += t_primes_summed[j];
        }

        // Get the number of elements with the same digit, but on processors with smaller rank
        P_EI[i] = t_primes_exscanned[d_i];

        // Get the number of elements with the same digit on the same processor and LEFT of this element (hence the -1)
        L_EI[i] = prefix_summed_bucket_table[d_i][i] - 1;
    }

    return make_tuple(G_EI, P_EI, L_EI);
}
Exemple #5
0
static
int
choice( void )
{
    int i, n;

    rb->yield();

    for( n = i = 0 ; i < 81 ; ++i )
        if( IS_EMPTY( i ) )
        {
            possible[ n ] = SET_INDEX( i ) | SET_DIGIT( numset( board[ i ] ) );

            /* Inconsistency if square unknown, but nothing possible */
            if( 9 == GET_DIGIT( possible[ n ] ) )
                return -2;
            ++n;
        }

    if( 0 == n )
        return -1;      /* All squares known */

    rb->qsort( possible, n, sizeof( possible[ 0 ] ), cmp );
    return GET_INDEX( possible[ 0 ] );
}
Exemple #6
0
int
bcd2_add(long *bcd_low, long *bcd_high, long addend)
{
    long tmp_lo, tmp_hi, carry, res;
    int digit;

    bin_bcd2(addend, &tmp_lo, &tmp_hi);
    carry = 0;
    for (digit=0; digit < 14; digit++)
        {
        res = GET_DIGIT(digit, *bcd_low, *bcd_high); 
        res += GET_DIGIT(digit, tmp_lo, tmp_hi);
        res += carry;
        carry = res / 10;
        res %= 10;
        SET_DIGIT(res, digit, bcd_low, bcd_high);
        }
    return(carry);
}
Exemple #7
0
/*
 * big integer unsigned subtraction
 *
 * operands in bip.op1 and bip.op2
 * result in bip.res, must not be negative
 */
static void bigUsub(void) {
  int nd1;
  int nd2;
  int i;
  unsigned short carry;
  unsigned short aux;

  /* op1 must have at least as many digits as op2 */
  nd1 = GET_ND(bip.op1);
  nd2 = GET_ND(bip.op2);
  if (nd1 < nd2) {
    /* unsigned subtraction would yield negative result */
    fatalError("internal library error #1 - THIS SHOULD NEVER HAPPEN!");
  }
  /* allocate result */
  bip.res = newBig(nd1);
  /* copy op2 to result */
  for (i = 0; i < nd2; i++) {
    SET_DIGIT(bip.res, i, GET_DIGIT(bip.op2, i));
  }
  /* fill result with 0 up to size of op1 */
  for (; i < nd1; i++) {
    SET_DIGIT(bip.res, i, 0);
  }
  /* res = op1 - res */
  carry = 0x01;
  for (i = 0; i < nd1; i++) {
    aux = (unsigned short) GET_DIGIT(bip.op1, i) -
          (unsigned short) GET_DIGIT(bip.res, i) +
          carry + 0xFF;
    SET_DIGIT(bip.res, i, aux & 0xFF);
    carry = aux >> 8;
  }
  if (carry != 0x01) {
    /* unsigned subtraction would yield negative result */
    fatalError("internal library error #2 - THIS SHOULD NEVER HAPPEN!");
  }
  /* determine actual size of result */
  i = nd1;
  while (--i >= 0 && GET_DIGIT(bip.res, i) == 0) ;
  SET_ND(bip.res, i + 1);
}
Exemple #8
0
/* Refresh board state, given move history. Note that this can yield
 * an incorrect state if the user has made errors - return -1 if an
 * incorrect state is generated; else return 0 for a correct state.
 */
static
int
reapply( void )
{
    int digit, idx, j;
    int allok = 0;
    rb->memset( board, 0x00, sizeof( board ) );
    for( j = 0 ; j < idx_history ; ++j )
        if( !( history[ j ] & IGNORED ) && 0 != GET_DIGIT( history[ j ] ) )
        {
            idx = GET_INDEX( history[ j ] );
            digit = GET_DIGIT( history[ j ] );
            if( !IS_EMPTY( idx ) || DISALLOWED( idx, digit ) )
                allok = -1;
            board[ idx ] = SET_DIGIT( digit );
            if( history[ j ] & FIXED )
                board[ idx ] |= FIXED;
            update( idx );
        }
    return allok;
}
Exemple #9
0
int
bcd2_sub(long *bcd_low, long *bcd_high, long subend)
{
    long tmp_lo, tmp_hi, carry, res;
    int digit;

    bin_bcd2(subend, &tmp_lo, &tmp_hi);
    carry = 0;
    for (digit=0; digit < 14; digit++)
        {
        res = GET_DIGIT(digit, *bcd_low, *bcd_high); 
        res -= GET_DIGIT(digit, tmp_lo, tmp_hi);
        res -= carry;
        if (res < 0) 
			{
			res += 10;
			carry = 1;
			}
        SET_DIGIT(res, digit, bcd_low, bcd_high);
        }
    return(carry);
}
Exemple #10
0
/*
 * big integer unsigned comparison
 *
 * operands in bip.op1 and bip.op2
 * result is < 0, = 0, or > 0 if and only if the
 * same relation holds for bip.op1 and bip.op2
 */
static int bigUcmp(void) {
  int nd1;
  int nd2;
  int diff;

  /* compare sizes */
  nd1 = GET_ND(bip.op1);
  nd2 = GET_ND(bip.op2);
  if (nd1 != nd2) {
    /* sizes are different: we know the bigger number */
    return nd1 - nd2;
  }
  /* sizes are equal: we must look at the digits */
  while (nd1--) {
    diff = (int) GET_DIGIT(bip.op1, nd1) -
           (int) GET_DIGIT(bip.op2, nd1);
    if (diff != 0) {
      return diff;
    }
  }
  /* the numbers are equal */
  return 0;
}
Exemple #11
0
int
bcd2_mul(long *bcd_low, long *bcd_high, long multiplier)
{
    long tmp_lo, tmp_hi, carry, m_lo, m_hi, m1, m2;
    int udigit, ldigit, res;

    tmp_lo = *bcd_low;
    tmp_hi = *bcd_high;
    bin_bcd2(multiplier, &m_lo, &m_hi);
    *bcd_low = 0;
    *bcd_high = 0;
    carry = 0;
    for (ldigit=0; ldigit < 14; ldigit++)
    {
        m1 = GET_DIGIT(ldigit, m_lo, m_hi); 
        carry = 0;
        for (udigit=0; udigit < 14; udigit++)
        {
            m2 = GET_DIGIT(udigit, tmp_lo, tmp_hi);
            res = m1 * m2;
            res += carry;
            if (udigit + ldigit < 14)
            {
                carry = GET_DIGIT(udigit + ldigit, *bcd_low, *bcd_high);
                res += carry;
	    }
            carry = res / 10;
            res %= 10;
            if (udigit + ldigit < 14)
	    {
                SET_DIGIT(res, udigit + ldigit, bcd_low, bcd_high);
	    }
	}
    }
    return(carry);
}
Exemple #12
0
int
bcd2_div(long *bcd_low, long *bcd_high, long divisor)
{
    long tmp_lo, tmp_hi, carry, d1, res, digit;
    

    carry = 0;
    tmp_lo = *bcd_low;
    tmp_hi = *bcd_high;
    *bcd_low = *bcd_high = 0;
    for (digit=13; digit >= 0; digit--)
        {
        d1 = GET_DIGIT(digit, tmp_lo, tmp_hi);
        d1 += 10 * carry; 
        res = d1 / divisor;
        carry = d1 % divisor;
        SET_DIGIT(res, digit, bcd_low, bcd_high);
        }
    return(carry);
}
Exemple #13
0
/* Deterministic solver; return 0 on success, else -1 on error.
 */
static
int
deterministic( void )
{
    int i, n;

    rb->yield();

    n = allmoves( );
    while( 0 < n )
    {
        ++pass;
        for( i = 0 ; i < n ; ++i )
            if( -1 == fill( GET_INDEX( possible[ i ] ),
                            GET_DIGIT( possible[ i ] ) ) )
                return -1;
        n = allmoves( );
    }
    return 0;
}
Exemple #14
0
/* Backtrack to a previous choice point, and attempt to reseed
 * the search. Return -1 if no further choice possible, or
 * the index of the changed square.
 *
 * Assumes that the move history and board are valid.
 */
static
int
backtrack( void )
{
    int digit, idx;

    rb->yield();

    for( ; 0 <= --idx_history ; )
        if( history[ idx_history ] & CHOICE )
        {
            /* Remember the last choice, and advance */
            idx = GET_INDEX( history[ idx_history ] );
            digit = GET_DIGIT( history[ idx_history ] ) + 1;
            reapply( );
            if( -1 != choose( idx, digit ) )
                return idx;
        }

    return -1;
}
Exemple #15
0
main()
{
long bin, low_bcd, high_bcd;
int i;

bin = MAXINT;
printf("%ld\n", bin);
bin_bcd2(bin, &low_bcd, &high_bcd);
printf("%ld  %ld\n", high_bcd, low_bcd);
bin = 0;
bcd2_bin(&bin, high_bcd);
bcd2_bin(&bin, low_bcd);
printf( "%ld\n", bin);
for (i=9; i >= 0; i--)
    printf("%dth digit in %d is %d\n", 
        i, bin, GET_DIGIT(i, low_bcd, high_bcd));
bcd2_add(&low_bcd, &high_bcd, MAXINT);
bin = 0;
bcd2_bin(&bin, high_bcd);
high_bcd = bin;
bin = 0;
bcd2_bin(&bin, low_bcd);
low_bcd = bin;
printf( "%ld%07ld\n", high_bcd, low_bcd);
bin_bcd2(14, &low_bcd, &high_bcd);
bcd2_mul(&low_bcd, &high_bcd, 23L);
bin = 0;
bcd2_bin(&bin, high_bcd);
bcd2_bin(&bin, low_bcd);
printf( "%ld\n", bin);
bcd2_div(&low_bcd, &high_bcd, 10L);
bin = 0;
bcd2_bin(&bin, high_bcd);
bcd2_bin(&bin, low_bcd);
printf( "%ld\n", bin);
}
Exemple #16
0
static PRESULT sudoku_key_proc(UINT32 vkey, UINT8 key_repeat_cnt, UINT8 key_status)
{
	PRESULT ret = PROC_LOOP;
	UINT8   back_saved;
	UINT8	pos;
	UINT8 i;
	if (key_status == PAN_KEY_PRESSED)
	{
		switch (vkey)
		{
			case V_KEY_UP:
			case V_KEY_DOWN:
			case V_KEY_LEFT: 
			case V_KEY_RIGHT: 
				sudoku_draw_grid(cur_row, cur_col);
				if (vkey == V_KEY_UP)
				{
				cur_row = cur_row == 0 ? 8 : cur_row - 1;
				}
				else if (vkey == V_KEY_DOWN)
				{
				cur_row = cur_row == 8 ? 0 : cur_row + 1;
				}
				else if (vkey == V_KEY_LEFT)
				{
				cur_col = cur_col == 0 ? 8 : cur_col - 1;
				}
				else if (vkey == V_KEY_RIGHT)
				{
				cur_col = cur_col == 8 ? 0 : cur_col + 1;
				}
				sudoku_draw_cursor(cur_row, cur_col);
				break;

			case V_KEY_0:
				pos = cur_row*BOARD_COLS+cur_col;
				if(!IS_FIXED(pos))
				{
					if(pboard[pos]!=' ')
					{
						pboard[pos]=' ';
    					sudoku_draw_cursor(cur_row, cur_col);
					}
				}
				break;
				
			case V_KEY_1:	case V_KEY_2:	case V_KEY_3:
			case V_KEY_4:	case V_KEY_5:	case V_KEY_6:	case V_KEY_7:
			case V_KEY_8:	case V_KEY_9:
				pos = cur_row*BOARD_COLS+cur_col;
				if(!IS_FIXED(pos))
				{
					pboard[pos]=(vkey-V_KEY_0)+0x30;
    				sudoku_draw_cursor(cur_row, cur_col);
				}
				for (i=0;i<81 ;i++ )
					if(pboard[i]==' ')
						break;
				if(i==81)
				{
					for (i=0;i<81 ;i++ )
						if(pboard[i]!=(GET_DIGIT(solved_board[i])+0x30))
							break;
				}
	
				if(i==81)
				{
					completed=1;
					win_compopup_init(WIN_POPUP_TYPE_OK);
					win_compopup_set_frame(GAME_MSG_LEFT,   GAME_MSG_TOP, GAME_MSG_WIDTH,GAME_MSG_HEIGHT);
					win_compopup_set_msg(NULL, NULL, RS_GAME_YOU_WIN);
					if (win_compopup_open_ext(&back_saved) == WIN_POP_CHOICE_YES)
					{
                        sudoku_draw_board();
						//sudoku_draw_grid(cur_row, cur_col);
						OSD_SetAttr((POBJECT_HEAD)&txt_newgame, C_ATTR_ACTIVE);
						OSD_ChangeFocus((POBJECT_HEAD)&game_sudoku_con, 1, \
						C_UPDATE_FOCUS | C_DRAW_SIGN_EVN_FLG);
					}
				}
				break;
			case V_KEY_MENU:
			case V_KEY_EXIT:
				win_compopup_init(WIN_POPUP_TYPE_OKNO);
				win_compopup_set_frame(GAME_MSG_LEFT,   GAME_MSG_TOP, GAME_MSG_WIDTH,GAME_MSG_HEIGHT);
				win_compopup_set_msg(NULL, NULL, RS_GAME_MSG_DO_YOU_QUIT);
				if (win_compopup_open_ext(&back_saved) == WIN_POP_CHOICE_YES)
				{
                    sudoku_draw_board();
					//sudoku_draw_grid(cur_row, cur_col);
					OSD_SetAttr((POBJECT_HEAD)&txt_newgame, C_ATTR_ACTIVE);
					OSD_ChangeFocus((POBJECT_HEAD)&game_sudoku_con, 1, \
					C_UPDATE_FOCUS | C_DRAW_SIGN_EVN_FLG);
				}
                else
                {
                    sudoku_draw_board();
					sudoku_draw_cursor(cur_row, cur_col);
                }
				break;
			default :
				ret = PROC_PASS;
				break;
		}
	}

	return ret;
}
Exemple #17
0
/*
 * big integer unsigned division
 *
 * dividend in bip.op1, divisor in bip.op2
 * quotient in bip.res, remainder in bip.rem
 */
static void bigUdiv(void) {
  ObjRef tmp;
  int nd1;
  int nd2;
  int nd3;
  int i, j, k, l;
  unsigned char r;
  unsigned short scale;
  unsigned short carry;
  unsigned short aux;
  unsigned short qhat;
  unsigned short v1, v2;
  unsigned short uj0, uj1, uj2, two;

  /* get sizes of operands */
  nd1 = GET_ND(bip.op1);
  nd2 = GET_ND(bip.op2);
  /* check for division by zero */
  if (nd2 == 0) {
    fatalError("division by zero");
  }
  /* check for small dividend */
  if (bigUcmp() < 0) {
    /* res = 0 */
    bip.res = newBig(0);
    SET_ND(bip.res, 0);
    /* rem = op1; BUT THIS HAS TO BE A COPY! */
    bip.rem = newBig(nd1);
    for (i = 0; i < nd1; i++) {
      SET_DIGIT(bip.rem, i, GET_DIGIT(bip.op1, i));
    }
    SET_ND(bip.rem, nd1);
    return;
  }
  /* check for single digit divisor */
  if (nd2 == 1) {
    /* yes - use simple division by single digit divisor */
    bip.rem = bip.op1;
    r = bigUdiv1(GET_DIGIT(bip.op2, 0));
    bip.res = bip.rem;
    if (r == 0) {
      bip.rem = newBig(0);
      SET_ND(bip.rem, 0);
    } else {
      bip.rem = newBig(1);
      SET_ND(bip.rem, 1);
      SET_DIGIT(bip.rem, 0, r);
    }
    return;
  }
  /*
   * now for the general case
   */
#if DIV_CHK_01
  printf("div_chk #01: division, general case\n");
  printf("             dividend = ");
  bigDump(stdout, bip.op1);
  printf("\n");
  printf("             divisor  = ");
  bigDump(stdout, bip.op2);
  printf("\n");
#endif
  /* determine scale factor for normalization */
  scale = (unsigned short) 256 /
          ((unsigned short) GET_DIGIT(bip.op2, nd2 - 1) + 1);
#if DIV_CHK_02
  printf("div_chk #02: scale factor = %02X\n", scale);
#endif
  /* normalize dividend, result is in bip.rem */
  bip.rem = newBig(nd1 + 1);
  carry = 0x00;
  for (i = 0; i < nd1; i++) {
    aux = (unsigned short) GET_DIGIT(bip.op1, i) * scale +
          carry;
    SET_DIGIT(bip.rem, i, aux & 0xFF);
    carry = aux >> 8;
  }
  SET_DIGIT(bip.rem, i, carry);
  SET_ND(bip.rem, nd1 + 1);
#if DIV_CHK_03
  printf("div_chk #03: normalized dividend = ");
  bigDump(stdout, bip.rem);
  printf("\n");
#endif
  /* normalize divisor, result is in bip.res */
  bip.res = newBig(nd2);
  carry = 0x00;
  for (i = 0; i < nd2; i++) {
    aux = (unsigned short) GET_DIGIT(bip.op2, i) * scale +
          carry;
    SET_DIGIT(bip.res, i, aux & 0xFF);
    carry = aux >> 8;
  }
  if (carry != 0x00) {
    /* overflow in divisor normalization */
    fatalError("internal library error #4 - THIS SHOULD NEVER HAPPEN!");
  }
  SET_ND(bip.res, nd2);
#if DIV_CHK_04
  printf("div_chk #04: normalized divisor  = ");
  bigDump(stdout, bip.res);
  printf("\n");
#endif
  /* allocate quotient */
  nd3 = nd1 - nd2 + 1;
  tmp = newBig(nd3);
  /* extract the two most significand digits of divisor */
  v1 = (unsigned short) GET_DIGIT(bip.res, nd2 - 1);
  v2 = (unsigned short) GET_DIGIT(bip.res, nd2 - 2);
  /* loop on digits of dividend and compute digits of quotient */
  /* j is index into dividend, k is index into quotient */
  for (j = nd1, k = nd3 - 1; k >= 0; j--, k--) {
#if DIV_CHK_05
    printf("div_chk #05: j = %d, k = %d\n", j, k);
#endif
    /* calculate qhat */
    uj0 = (unsigned short) GET_DIGIT(bip.rem, j);
    uj1 = (unsigned short) GET_DIGIT(bip.rem, j - 1);
    uj2 = (unsigned short) GET_DIGIT(bip.rem, j - 2);
    two = (uj0 << 8) | uj1;
    if (uj0 == v1) {
      qhat = (unsigned short) 255;
#if DIV_CHK_06
      printf("div_chk #06a: qhat = %02X\n", qhat);
#endif
    } else {
      qhat = two / v1;
#if DIV_CHK_06
      printf("div_chk #06b: qhat = %02X\n", qhat);
#endif
    }
    while (qhat * v2 > (((two - qhat * v1) << 8) | uj2)) {
      qhat--;
#if DIV_CHK_07
      printf("div_chk #07: qhat decremented, is now %02X\n", qhat);
#endif
    }
    /* multiply and subtract */
    /* l is index into dividend, i is index into divisor */
    carry = 0xFF;
    for (l = j - nd2, i = 0; i < nd2; l++, i++) {
      aux = (unsigned short) GET_DIGIT(bip.rem, l) -
            (unsigned short) GET_DIGIT(bip.res, i) * qhat +
            carry + 0xFE01;
      SET_DIGIT(bip.rem, l, aux & 0xFF);
      carry = aux >> 8;
    }
    aux = (unsigned short) GET_DIGIT(bip.rem, l) +
          carry + 0xFE01;
    SET_DIGIT(bip.rem, l, aux & 0xFF);
    carry = aux >> 8;
#if DIV_CHK_08
    printf("div_chk #08: remainder = ");
    bigDump(stdout, bip.rem);
    printf("\n");
#endif
    /* test remainder and possibly add back */
    if (carry != 0xFF) {
      /* qhat is one too large */
      qhat--;
#if DIV_CHK_09
      printf("div_chk #09: qhat final correction, is now %02X\n", qhat);
#endif
      /* add back */
      /* l is index into dividend, i is index into divisor */
      carry = 0x00;
      for (l = j - nd2, i = 0; i < nd2; l++, i++) {
        aux = (unsigned short) GET_DIGIT(bip.rem, l) +
              (unsigned short) GET_DIGIT(bip.res, i) +
              carry;
        SET_DIGIT(bip.rem, l, aux & 0xFF);
        carry = aux >> 8;
      }
      aux = (unsigned short) GET_DIGIT(bip.rem, l) +
            carry;
      SET_DIGIT(bip.rem, l, aux & 0xFF);
      carry = aux >> 8;
      if (carry != 0x01) {
        /* missing carry in add-back sum */
        fatalError("internal library error #5 - THIS SHOULD NEVER HAPPEN!");
      }
#if DIV_CHK_10
      printf("div_chk #10: remainder = ");
      bigDump(stdout, bip.rem);
      printf("\n");
#endif
    }
    /* store quotient digit */
    SET_DIGIT(tmp, k, qhat);
#if DIV_CHK_11
    printf("div_chk #11: quotient digit = %02X\n", qhat);
#endif
  }
Exemple #18
0
/* Return index of square for choice.
 *
 * If no choice is possible (i.e. board solved or inconsistent),
 * return -1.
 *
 * The current implementation finds a square with the minimum
 * number of unknown digits (i.e. maximum # masked digits).
 */
static
int
cmp( const void * e1, const void * e2 )
{
    return GET_DIGIT( *(const int *)e2 ) - GET_DIGIT( *(const int *)e1 );
}
Exemple #19
0
/* Return number of hints. The hints mechanism should attempt to find
 * 'easy' moves first, and if none are possible, then try for more
 * cryptic moves.
 */
int
findhints( void )
{
    int i, n, mutated = 0;

    rb->yield();

    n = findmoves( );
    if( n < 2 )
    {
        /* Each call to pairs() can mutate the board state, making the
         * hints very, very cryptic... so later undo the mutations.
         */
        for( i = 0 ; i < 9 ; ++i )
        {
            count_set_digits( i, idx_row );
            pairs( i, idx_row );

            count_set_digits( i, idx_column );
            pairs( i, idx_column );

            count_set_digits( i, idx_block );
            pairs( i, idx_block );
        }
        mutated = 1;
        n = findmoves( );
    }
    if( n < 2 )
    {
        for( i = 0 ; i < 9 ; ++i )
        {
            block( i );
            common( i );
        }
        mutated = 1;
        n = findmoves( );
    }

    /* Sort the possible moves, and allow just one hint per square */
    if( 0 < n )
    {
        int i, j;

        rb->qsort( possible, n, sizeof( int ), cmpindex );
        for( i = 0, j = 1 ; j < n ; ++j )
        {
            if( GET_INDEX( possible[ i ] ) == GET_INDEX( possible[ j ] ) )
            {
                /* Let the user make mistakes - do not assume the
                 * board is in a consistent state.
                 */
                if( GET_DIGIT( possible[i] ) == GET_DIGIT( possible[j] ) )
                    possible[ i ] |= possible[ j ];
            }
            else
                i = j;
        }
        n = i + 1;
    }

    /* Undo any mutations of the board state */
    if( mutated )
        reapply( );

    return n;
}