Zebra puzzle - Constraint Satisfaction in C - c

I'm trying to read up on constraint satisfaction problems and trying to code them to solve a few sample problems. I came across http://rosettacode.org/wiki/Zebra_puzzle#C.2B.2B to solve the classic zebra puzzle. In the C code given in rosetta code website, There was this following function. I have given only a few lines from it. I didn't know what the purpose of the two if statements is and how they worked.
Can someone explain it?
int checkHouses(int ha[5][5])
{
...
int c_add = 0, c_or = 0;
int m_add = 0, m_or = 0;
int d_add = 0, d_or = 0;
int a_add = 0, a_or = 0;
int s_add = 0, s_or = 0;
for (int i = 0; i < 5; i++) {
// Uniqueness tests.
if (ha[i][C] >= 0) {
c_add += (1 << ha[i][C]);
c_or |= (1 << ha[i][C]);
}
if (ha[i][M] >= 0) {
m_add += (1 << ha[i][M]);
m_or |= (1 << ha[i][M]);
}
if (ha[i][D] >= 0) {
d_add += (1 << ha[i][D]);
d_or |= (1 << ha[i][D]);
}
if (ha[i][A] >= 0) {
a_add += (1 << ha[i][A]);
a_or |= (1 << ha[i][A]);
}
if (ha[i][S] >= 0) {
s_add += (1 << ha[i][S]);
s_or |= (1 << ha[i][S]);
}
}
if ((c_add != c_or) || (m_add != m_or) || (d_add != d_or)
|| (a_add != a_or) || (s_add != s_or)) {
return Invalid;
}
if ((c_add != 0b11111) || (m_add != 0b11111) || (d_add != 0b11111)
|| (a_add != 0b11111) || (s_add != 0b11111)) {
return Underfull;
}

The comment actually explains it: they are verifying that there are no duplicate values between ha[0..4][x] for each value of x.
As to how it is doing it: each value is assigned a bit position, such that 1<<ha[i][x] will yield a number with only the bit in that position set. x_or will be the OR of those values, while x_add is their sum. If there is a duplicate value, it will not have an effect on x_or (that bit is already set), but will on x_add; hence, they will be different.

Related

C - convert number string to SQL_NUMERIC_STRUCT

I need help converting a number string to a SQL_NUMERIC_STRUCT value to use decimal and numeric database data types. The SQL_NUMERIC_STRUCT value is a 16-byte hexadecimal unsigned integer. For example, I have a string "12312312899012312890522341231231232198", that contains 38 digits (maximum for SQL SERVER decimal or numeric data types). In other languages such a c# there is a built-in conversion function, but my Visual studio 2019 does not allow me to directly use 128-bit integers in the C++ environment. The Microsoft help page offers example with a small,2-byte integer, unfortunately.
I have found a solution.
bool ConvertToNumericStruct (char* s, SQL_NUMERIC_STRUCT* v){
int sc = (int)strlen(s), scale = 0, i,y, z;
char c, p = 0, d; bool minus = false;
int _tmp, x, carryover;
memset(v->val, 0, 16);
for (i = 0; i < sc; i++) {
c = s[i];
if (i == 0 && c == '-')minus = true;
else if (c == '.') { if (scale == 0)scale = sc - i - 1; else return false; }
else if (c < '0' || c>'9') return false;
else
{
if (p > 38) return false;
d = c - 48;
_tmp = 0;
carryover = d;
y = 0; z = 0;
for (x = sc - 1; x > -1; x--)
{
if (y % 2 == 1)
{
_tmp = (v->val[z] >> 4) * 10 + carryover;
v->val[z] &= 0x0F;
v->val[z] |= ((_tmp % 16) << 4 & 0xF0);
z++;
if (z > 15) break;
}
else {
_tmp = (v->val[z] & 0x0F) * 10 + carryover;
v->val[z] &= 0Xf0;
v->val[z] |= ((_tmp % 16) & 0x0F);
}
y++;
carryover = _tmp / 16;
}
p++;
}
}
v->precision = p;
v->scale = scale;
if (minus) v->sign = 0; else v->sign = 1;
return true;}
If you want to insert data defined by decimal or numeric into database such as MySql via UnixODBC with the function SQLBindParameter,you can just use SQL_C_CHAR for fCtype and SQL_CHAR for fSqltype with a char-string buffer.No need to convert.That would be done implicitly.

Hamming code check parity

I am not sure if I am calculating the parity bit correctly for the the check Parity bit function I wrote. The codeWord is 11 chars long with 4 parity bits and 7 data bits. Does the implementation look good?
void parityCheck(char* codeWord) {
int parity[4] = {0}, i = 0, diffParity[4] = {0}, twoPower = 0, bitSum = 0;
// Stores # of 1's for each parity bit in array.
parity[0] = (codeWord[2] - 48) + (codeWord[4] - 48) + (codeWord[6] - 48) + (codeWord[8] - 48) + (codeWord[10] - 48);
parity[1] = (codeWord[2] - 48) + (codeWord[5] - 48) + (codeWord[6] - 48) + (codeWord[9] - 48) + (codeWord[10] - 48);
parity[2] = (codeWord[4] - 48) + (codeWord[5] - 48) + (codeWord[6] - 48);
parity[3] = (codeWord[8] - 48) + (codeWord[9] - 48) + (codeWord[10] - 48);
// Determines if sum of bits is even or odd, then tests for difference from actual parity bit.
for (i = 0; i < 4; i++) {
twoPower = (int)pow((double)2, i);
if (parity[i] % 2 == 0)
parity[i] = 0;
else
parity[i] = 1;
if ((codeWord[twoPower-1] - 48) != parity[i])
diffParity[i] = 1;
}
// Calculates the location of the error bit.
for (i = 0; i < 4; i++) {
twoPower = (int)pow((double)2, i);
bitSum += diffParity[i]*twoPower;
}
// Inverts bit at location of error.
if (bitSum <= 11 && bitSum > 0) {
if ((codeWord[bitSum-1] - 48))
codeWord[bitSum-1] = '0';
else
codeWord[bitSum-1] = '1';
}
Does the implementation look good?
This very much depends on your measure for “good”. I can confirm that it does get the job done, so at least it is correct. Your code is very verbose, and thus hard to check for correctness. I'd do the following:
int parity_check(int codeWord) {
int parity = 0, codeWordBit, bitPos;
for (bitPos = 1; bitPos <= 11; ++bitPos) {
codeWordBit = ((codeWord >> (bitPos - 1)) & 1);
parity ^= bitPos*codeWordBit;
}
if (parity != 0) {
if (parity > 11)
return -1; // multi-bit error!
codeWord ^= 1 << (parity - 1);
}
return codeWord;
}
Instead of a sequence of digit characters, I treat your whole code word as a single integer, which is a lot more efficient.
Looking at the table at Wikipedia, I see that the columns of that table form binary representations of the sequence 1 … 11. Each code word bit affects exactly those parity bits mentioned in that column, so I take the code word bit (which is zero or one), multiply it by the bit pattern of that column to obtain either that pattern or zero, then XOR this with the current parity bit pattern. The effect of this is that a zero code word bit won't change anything, whereas a non-zero code word bit flips all associated parity bits.
Some care has to be taken because the bit pattern is one-based, whereas the bit position using the right shift trick is zero-based. So I have to subtract one, then shift right by that amount, and then extract the least significant digit in order to obtain the codeWordBit.
Using my implementation for reference, I was able to verify (by complete enumeration) that your code works the same.
Your code works fine AFAIK as it passed test cases I conjured up. Some simplifications were employed, but the OP functionality not changed. Some classic simplifications were made for easier viewing.
void parityCheck(char* cW) {
int parity[4] = { 0 }, i = 0, diffParity[4] = { 0 }, twoPower = 0, bitSum = 0;
// Stores # of 1's for each parity bit in array.
parity[0] = (cW[2] - '0') + (cW[4] - '0') + (cW[6] - '0') + (cW[8] - '0') + (cW[10] - '0');
parity[1] = (cW[2] - '0') + (cW[5] - '0') + (cW[6] - '0') + (cW[9] - '0') + (cW[10] - '0');
parity[2] = (cW[4] - '0') + (cW[5] - '0') + (cW[6] - '0');
parity[3] = (cW[8] - '0') + (cW[9] - '0') + (cW[10] - '0');
// Determines if sum of bits is even or odd, then tests for difference from actual parity bit.
for (i = 0; i < 4; i++) {
//twoPower = (int) pow((double) 2, i);
twoPower = 1 << i;
//if (parity[i] % 2 == 0) parity[i] = 0; else parity[i] = 1;
parity[i] &= 1; // Make 0 even, 1 odd.
if ((cW[twoPower - 1]-'0') != parity[i])
diffParity[i] = 1;
}
// Calculates the location of the error bit.
for (i = 0; i < 4; i++) {
// twoPower = (int) pow((double) 2, i);
twoPower = 1 << i;
bitSum += diffParity[i] * twoPower;
}
// Inverts bit at location of error.
if (bitSum <= 11 && bitSum > 0) {
if ((cW[bitSum - 1]-'0'))
cW[bitSum - 1] = '0';
else
cW[bitSum - 1] = '1';
}
}
void TestP(const char * Test) {
char buf[100];
strcpy(buf, Test);
parityCheck(buf);
printf("'%s' '%s'\n", Test, buf);
}
int main(void) {
TestP("00000000000");
TestP("10011100101");
TestP("10100111001");
}
It would have been useful had the OP posted test patterns.
Here's my implementation. It works. The public is free to use it at no charge.
I used the acronym "secded" as in, "single-error-correcting, double-error-detecting." You can re-wire this as a "triple error detector" if you want that instead. Really, some small part of this is secded and the rest is Hamming 7,4 -- but I named these methods what I did, when I did.
The "strings" here are not NUL-terminated, but counted. This code is excerpted from a Python module written in C. That is the provenance of the string type you see.
A key point here was realizing that there are only 16 Hamming 7,4 codes. I calculated secded_of_nibble() with some Python code, which unfortunately I no longer have.
static const unsigned char secded_of_nibble[] =
{ 0x0, 0xd2, 0x55, 0x87, 0x99, 0x4b, 0xcc, 0x1e, 0xe1, 0x33, 0xb4, 0x66, 0x78, 0
xaa, 0x2d, 0xff };
int fec_secded_encode_cch_bits(const char * strIn, const int cchIn, char * strOu
t, const int cchOut)
{
assert( cchIn * 2 == cchOut);
if( cchIn * 2 != cchOut)
return 0;
if (!strIn || !strOut)
return 0;
int i;
for (i = 0; i < cchIn; i ++)
{
char in_byte = strIn[i];
char hi_byte = secded_of_nibble[(in_byte >> 4) & 0xf];
char lo_byte = secded_of_nibble[in_byte & 0xf];
strOut[i * 2] = hi_byte;
strOut[i * 2 + 1] = lo_byte;
}
return 1;
}
char bv_H[] = {0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0x8};
char val_nibble(char ch)
{
return ((ch & 0x20) >> 2) | ((ch & 0xE) >> 1);
}
char correct_nibble(char ch)
{
char nibble = 0;
int i = 0;
for (i = 0; i < 8; i++)
if (ch & (1 << (7-i)))
nibble ^= bv_H[i];
return nibble;
}
void apply_correct(char nib_correct, char * pbyte, int * pcSec, int *pcDed)
{
if (0 == nib_correct)
return;
if (nib_correct & 0x8)
{
(*pcSec) ++;
int bit = (8 - (nib_correct & 0x7)) & 0x7;
/* fprintf(stderr, "bit %d, %02X\n", bit, 1 << bit);*/
(*pbyte) ^= (1 << bit);
}
else
{
(*pcDed) ++;
}
}
int fec_secded_decode_cch_bits
(
const char * strIn,
const int cchIn,
char * strOut,
const int cchOut,
int * pcSec,
int * pcDed
)
{
assert( cchIn == cchOut *2);
if( cchIn != cchOut * 2)
return 0;
if (!strIn || !strOut)
return 0;
int i;
for (i = 0; i < cchOut; i ++)
{
char hi_byte = strIn[i * 2];
char lo_byte = strIn[i * 2 + 1];
char hi_correct = correct_nibble(hi_byte);
char lo_correct = correct_nibble(lo_byte);
if (hi_correct || lo_correct)
{
apply_correct(hi_correct, &hi_byte, pcSec, pcDed);
apply_correct(lo_correct, &lo_byte, pcSec, pcDed);
/* fprintf(stderr, "Corrections %x %x.\n", hi_correct, lo_correct);*/
}
char hi_nibble = val_nibble(hi_byte);
char lo_nibble = val_nibble(lo_byte);
strOut[i] = (hi_nibble << 4) | lo_nibble;
}
return 1;
}

C code of simple Receiver

I have this code of a transmitter and I have a problem where when I get input from my transmitter I save it in a char array "rec" and after I have finished receiving I compare it with my other arrays and base on that comparison I light up a bulb in portb. But the code gives me no errors and no bulb lights (the connection works I've tried it) it has something to do with the comparing arrays part. Am I doing this right? Thank you
char rec[3];
char cmp1[]= "1000";
char cmp2[]= "1010";
char cmp3[]="1111";
char cmp4[]="1001";
int i=0;
int beginrecord;
void main(void)
{
TRISB=0;
TRISD=0;
TRISC=255;
PORTC=0;
PORTB=0;
while(1)
{
if(PORTC==1)
{
rec[i]=1;
i++;
beginrecord = 1;
delay_ms(1);
}
if (PORTC==0 && beginrecord==1)
{
rec[i]=0;
i++;
delay_ms(1);
}
if(i==4) {
beginrecord = 0;
i = 0;
if(rec == cmp1){
portb = 0x01;}
else if(rec == cmp2){
portb = 0x02;}
else if(rec == cmp3){
portb = 0x04;}
else if(rec == cmp4){
portb = 0x08;}
}
}
}
You must use strcmp(rec, cmp1) == 0 instead of rec == cmp1.
The way you do it now, you compare only the pointers, which are never the same.
And are you sure that your port returns a character 1or 0 and not the values 0/1?
In that case your comparison also wouldn't work.
Some other issues with your code:
I assume that the char form the port is a binary value and not an ASCII character.
If it is indeed an ASCII character and you use strcmp() then you must add a zero byte at the end of the buffer.
If you receive multiple bytes and not bits, you must use memcmp() instead of strcmp(). In that case your intialisation of cmpX would be also wrong. If it are bits you receive, you would want to combine them into bytes before comparing (assuming a serial port).
PORTC is always 0, so it can not become 1 in your code.
You seem to have mixed case PORTB vs. portb.
your variables have no type.
Here you are declare three cmp[] of char type which is a string so it is like "1000". it is 4 byte data. and your rec[3] is only 3 byte. i think you try to compare a int type. like
1001 == 1001 in binary
Declare them as unsigned int then try to compare.
And make all your values full 8 bit like 00001000b not 1000.
or may be i get it wrong.
There are a number of issues that confuse your goal - see above comment, but I've tried to address them below.
Rather than accumulate the rec as an array, the bits are accumulated in an int. This simplifies the compares to your original style.
beginrecord needed initialization. Variables were brought into a local scope.
Cleaned up the indentation.
const int cmp1 = 8; // "1000";
const int cmp2 = 10; // "1010";
const int cmp3 = 15; // "1111";
const int cmp4 = 9; // "1001";
void main(void) {
TRISB = 0;
TRISD = 0;
TRISC = 255;
PORTC = 0;
PORTB = 0;
int i = 0;
int beginrecord = 0;
int rec = 0;
while (1) {
if (PORTC == 1) {
rec <<= 1; /* rec = rec * 2 */
rec |= 1;
beginrecord = 1;
delay_ms(1);
i++;
}
else if (PORTC == 0 && beginrecord == 1) {
rec <<= 1;
delay_ms(1);
i++;
}
if (i == 4) {
if (rec == cmp1) {
PORTB = 0x01;
} else if (rec == cmp2) {
PORTB = 0x02;
} else if (rec == cmp3) {
PORTB = 0x04;
} else if (rec == cmp4) {
PORTB = 0x08;
}
beginrecord = 0;
i = 0;
rec = 0;
}
}
}

Listing prime numbers using Sieve's method using bitmask

I wrote the following code to list all the prime numbers upto 2 billion using Sieve's method. I used bitmasking for flagging purpose. While I am able to get the prime numbers correctly, a few primes in the beginning are missing every time. Please help me find the bug in the program.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdbool.h>
#define MAX 2000000000
char* listPrimes(){
int block = sqrt(MAX);
char* mark = calloc((MAX/8),sizeof(char));
int i = 2;
int j;
char mask[8];
for(j=0;j<8;j++)
mask[j] = 0;
mask[7] = 1;
mask[6] |= mask[7] << 1;
mask[5] |= mask[7] << 2;
mask[4] |= mask[7] << 3;
mask[3] |= mask[7] << 4;
mask[2] |= mask[7] << 5;
mask[1] |= mask[7] << 6;
mask[0] |= mask[7] << 7;
for(j=0;j<8;j++)
printf("%d ",mask[j]);
mark[0] |= mask[0];
mark[0] |= mask[1];
while (i < block){
for (j = 2; i*j <= block; j++)
mark[(i*j) / 8] |= mask[((i*j) % 8 )];
i++;
}
printf("\n");
printf("The block size is\t:\t%d\n",block);
j = 2;
while(j<=block){
if((mark[j / 8] & mask[j]) == 0 ){
for(i = 2;i <= MAX; i++){
if((i%j) == 0){
mark[i / 8] |= mask[(i % 8)];
}
}
}
while((mark[++j / 8] & mask[j % 8]) != 0);
}
for(j=0;j<=MAX;j++)
if((mark[j / 8] & mask[(j % 8)]) == 0)
printf("%d\n", ((8*(j / 8)) + (j % 8)));
return mark;
}
int main(int argc,char* argv[]){
listPrimes();
return 0;
}
As ArunMK said, in the second while loop you mark the prime j itself as a multiple of j. And as Lee Meador said, you need to take the modulus of j modulo 8 for the mask index, otherwise you access out of bounds and invoke undefined behaviour.
A further point where you invoke undefined behaviour is
while((mark[++j / 8] & mask[j % 8]) != 0);
where you use and modify j without intervening sequence point. You can avoid that by writing
do {
++j;
}while((mark[j/8] & mask[j%8]) != 0);
or, if you insist on a while loop with empty body
while(++j, (mark[j/8] & mask[j%8]) != 0);
you can use the comma operator.
More undefined behaviour by accessing mark[MAX/8] which is not allocated in
for(i = 2;i <= MAX; i++){
and
for(j=0;j<=MAX;j++)
Also, if char is signed and eight bits wide,
mask[0] |= mask[7] << 7;
is implementation-defined (and may raise an implementation-defined signal) since the result of
mask[0] | (mask[7] << 7)
(the int 128) is not representable as a char.
But why are you dividing each number by all primes not exceeding the square root of the bound in the second while loop?
for(i = 2;i <= MAX; i++){
if((i%j) == 0){
That makes your algorithm not a Sieve of Eratosthenes, but a trial division.
Why don't you use the technique from the first while loop there too? (And then, why two loops at all?)
while (i <= block){
if ((mark[i/8] & mask[i%8]) == 0) {
for (j = 2; i*j < MAX; j++) {
mark[(i*j) / 8] |= mask[((i*j) % 8 )];
}
}
i++;
}
would not overflow (for the given value of MAX, if that is representable as an int), and produce the correct output orders of magnitude faster.
Change the middle loop to add the modulo:
j = 2;
while(j<=block){
if((mark[j / 8] & mask[j % 8]) == 0 ){
for(i = 2;i <= MAX; i++){
if((i%j) == 0){
mark[i / 8] |= mask[(i % 8)];
}
}
}
}
In the second while loop you are looping through i from 2 onwards and you do an if (i%j == 0). This will be true for i when it is a prime as well. You need to check for (i != j). Also the modulo as reported above. Hence it becomes:
if ((i%j == 0) {
if (i!=j)
mark[i/j] |= mask[i%j];
}

Why does fprintf print extra values

I want to encode tags that will contain a field number and a wire type for the purpose of protocol buffers. The problem that I am having now is that whenever my value for 'tag' is below '8' fprintf writes additional values next to the correct ones. i.e. instead of 38 it prints 38c0 3. If the value of tag is 8 or higher the script works fine. Below is the code with irrelavent lines omitted.
int uint32_pack (uint8_t *fieldnumber, uint32_t value, uint8_t *out);
int main(){
uint32_t initvalue = 2;
int return_rv;
uint8_t *tag = (uint8_t *) malloc(sizeof(uint8_t));
uint8_t *tempout= (uint8_t *) malloc(sizeof(uint32_t));
*tag = 7; //value to be encoded (won't work for values less than 8)
return_rv = uint32_pack (tag, initvalue, tempout);
free(tempout);
}
/* === pack() === */
/* Pack an unsigned 32-bit integer in base-128 encoding, and return the number
of bytes needed: this will be 5 or less. */
int uint32_pack (uint8_t *fieldnumber, uint32_t value, uint8_t *out)
{
unsigned rv = 0;
FILE *wiretypetag;
int secondaryvalue;
wiretypetag = fopen("wiretype.txt","w");
//encodes wire type and the field number
if (*fieldnumber <16){
*fieldnumber <<= 3;
fprintf(wiretypetag,"%x",fieldnumber[0]);
}
if (*fieldnumber < 32 && *fieldnumber > 15){
*fieldnumber <<= 3;
secondaryvalue = 0x01;
fprintf(wiretypetag,"%x %x",fieldnumber[0],secondaryvalue);
}
if (*fieldnumber < 48 && *fieldnumber > 31){
*fieldnumber += 0x10;
*fieldnumber &= 0x1F;
*fieldnumber <<= 3;
secondaryvalue = 0x02;
fprintf(wiretypetag,"%x %x",fieldnumber[0], secondaryvalue);
}
if (*fieldnumber < 64 && *fieldnumber > 47){
*fieldnumber &= 0x1F;
*fieldnumber <<= 3;
secondaryvalue = 0x03;
fprintf(wiretypetag,"%x %x",fieldnumber[0], secondaryvalue);
}
/* assert: value<128 */
out[rv++] = value;
if (rv == 1){
fprintf(outfile,"%x",out[0]);
}
if (rv == 2){
fprintf(outfile,"%x %x",out[0], out[1]);
}
if (rv == 3){
fprintf(outfile,"%x %x %x",out[0],out[1],out[2]);
}
if (rv == 4){
fprintf(outfile,"%x %x %x %x",out[0],out[1],out[2],out[3]);
}
if (rv == 5){
fprintf(outfile,"%x %x %x %x %x",out[0],out[1],out[2],out[3],out[4]);
}
fclose(wiretypetag);
return rv;
}
if (fieldnumber <16){
should be
if (*fieldnumber <16){
You can simplify the code by using else at:
//encodes wire type and the field number
if (*fieldnumber <16){
*fieldnumber <<= 3;
fprintf(wiretypetag,"%d",fieldnumber[0]);
}
if (*fieldnumber < 32 && *fieldnumber > 15){
*fieldnumber <<= 3;
Replace with:
//encodes wire type and the field number
if (*fieldnumber < 16) {
*fieldnumber <<= 3;
fprintf(wiretypetag, "%d", fieldnumber[0]);
}
else if (*fieldnumber < 32) {
*fieldnumber <<= 3;
...
This is a common idiom and one you should use when appropriate - as now. It will improve the legibility of the code.
That may not be the whole problem; it probably isn't.
Explanation of Problem
In fact, using an else if chain corrects the code. Because the first if modifies *fieldnumber with the <<= operator, when the second condition is evaluated, *fieldnumber is no longer 7 but 56, so the condition for
if (*fieldnumber < 64 && *fieldnumber > 47){
is also executed, printing out more information.
The else if chain will resolve that by ensuring that only one alternative is executed.
Since you have:
unsigned rv = 0;
[...]
/* assert: value<128 */
out[rv++] = value;
if (rv == 1){
fprintf(outfile,"%x",out[0]);
}
This fprintf() should be executed, but the following ones for rv equal to 2, 3, 4, 5 should never be executed.

Resources