Esempio n. 1
0
/* Find all squares with a single digit allowed -- do not mutate board */
static
void
singles( int el, int (*idx_fn)( int, int ), int hintcode )
{
    int i, j, idx;

    count_set_digits( el, idx_fn );

    for( i = 0 ; i < 9 ; ++i )
    {
        if( 1 == counts[ i ] )
        {
            /* Digit 'i+1' appears just once in the element */
            for( j = 0 ; j < 9 ; ++j )
            {
                idx = (*idx_fn)( el, j );
                if( !DISALLOWED( idx, i + 1 ) && idx_possible < 81 )
                    possible[ idx_possible++ ] = SET_INDEX( idx )
                                               | SET_DIGIT( i + 1 )
                                               | hintcode;
            }
        }
        if( 8 == digits[ i ] )
        {
            /* 8 digits are masked at this position - just one remaining */
            idx = (*idx_fn)( el, i );
            for( j = 1 ; j <= 9 ; ++j )
                if( 0 == ( STATE( idx ) & DIGIT_STATE( j ) ) && idx_possible < 81 )
                    possible[ idx_possible++ ] = SET_INDEX( idx )
                                               | SET_DIGIT( j )
                                               | hintcode;
        }
    }
}
Esempio n. 2
0
File: bigint.c Progetto: Ezlo93/njvm
/*
 * 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);
}
Esempio n. 3
0
File: bigint.c Progetto: Ezlo93/njvm
/*
 * 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();
  }
}
Esempio n. 4
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 ] );
}
Esempio n. 5
0
File: bn_mp_init.c Progetto: asr/uhc
/* init a new mp_int */
int mp_init (mp_int * a)
{
#ifdef __UHC_BUILDS_RTS__
  // all allocation is assumed to be done outside library
  mp_zero(a) ;
  printf( "WARNING: mp_init (%p used=%x alc=%x)\n", a, USED(a), ALLOC(a) ) ;
  // prLTM(a,"mp_init") ;
#else
  int i;

  /* allocate memory required and clear it */
  SET_DIGITS(a, OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * MP_PREC));
  if (DIGITS(a) == NULL) {
    return MP_MEM;
  }

  /* set the digits to zero */
  for (i = 0; i < MP_PREC; i++) {
      SET_DIGIT(a,i,0);
  }

  /* set the used to zero, allocated digits to the default precision
   * and sign to positive */
  SET_USED(a,0);
  SET_ALLOC(a,MP_PREC);
  SET_SIGN(a,MP_ZPOS);
#endif

  return MP_OKAY;
}
Esempio n. 6
0
File: bigint.c Progetto: Ezlo93/njvm
/*
 * 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;
}
Esempio n. 7
0
File: bigint.c Progetto: Ezlo93/njvm
/*
 * 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);
}
Esempio n. 8
0
/* Choose a digit for the given square.
 * The starting digit is passed as a parameter.
 * Returns -1 if no choice possible.
 */
static
int
choose( int idx, int digit )
{
    rb->yield();

    for( ; digit <= 9 ; ++digit )
        if( !DISALLOWED( idx, digit ) )
        {
            board[ idx ] = SET_DIGIT( digit );
            update( idx );
            add_move( idx, digit, CHOICE );
            return digit;
        }

    return -1;
}
Esempio n. 9
0
/* Fill square with given digit, and update state.
 * Returns 0 on success, else -1 on error (i.e. invalid fill)
 */
static
int
fill( int idx, int digit )
{
    assert( 0 != digit );

    if( !IS_EMPTY( idx ) )
        return ( DIGIT( idx ) == digit ) ? 0 : -1;

    if( DISALLOWED( idx, digit ) )
        return -1;

    board[ idx ] = SET_DIGIT( digit );
    update( idx );
    add_move( idx, digit, 0 );

    return 0;
}
Esempio n. 10
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);
}
Esempio n. 11
0
/* Management of the move history - adding a move */
static
void
add_move( int idx, int digit, int choice )
{
    int i;

    if( sizeof( history ) / sizeof( int ) == idx_history )
        compress( 81 );

    /* Never ignore the last move */
    history[ idx_history++ ] = SET_INDEX( idx ) | SET_DIGIT( digit ) | choice;

    /* Ignore all previous references to idx */
    for( i = idx_history - 2 ; 0 <= i ; --i )
        if( GET_INDEX( history[ i ] ) == idx )
        {
            history[ i ] |= IGNORED;
            break;
        }
}
Esempio n. 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);
}
Esempio n. 13
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;
}
Esempio n. 14
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);
}
Esempio n. 15
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);
}
Esempio n. 16
0
File: bigint.c Progetto: Ezlo93/njvm
/*
 * 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
  }