Pad an matrix by replicating the edge values - c

My program creates a matrix. It moves and centers it into a bigger one. Now I want to fill the border created with the edge values of the first matrix to make it look like this:
So far I have the following code, but it seems that it is not working as it should (let's consider the matrix as an image with width,height and border):
/////////////////////////Up/Down Fill////////////////////////////
for(i=border;i<(width+border);i++){
for(j=0;j<(height+2*border);j++){
if(j<border){
fmatr[i][j]=fmatr[i][border];
}
else if(j>(height+border)){
fmatr[i][j]=fmatr[i][(height+border)];
}
}
}
/////////////////////////Left/Right//////////////////////////////
for(i=0;i<(width+2*border);i++){
for(j=0;j<(height+2*border);j++){
if(i<border){
fmatr[i][j]=fmatr[border][j];
}
else if(i>(width+border)){
fmatr[i][j]=fmatr[(width+border)][j];
}
}
}
Could anyone point me in the right direction how to do that?

You are a victim of an off-one error.
Generally in C, to iterate a sequence you use the start index and the next_to_last index, in this way:
for (i = first; i < next_to_last; ++i)
And that is handy because the next_to_last index is the first plus the length:
for (i = first; i < first + length; ++i)
If you want to know if an index is out of bounds you use < and >=:
out_of_bounds = i < first || i >= next_to_last;
out_of_bounds = i < first || i >= first + length;
All this is cool because when you have two contiguous sequences you do not have to do any adjustment when you go from one to the other:
for (i = 0; i < a; ++i) ...;
for (; i < b; ++i) ...;
for (; i < c; ++i) ...;
But if you want to access the last element of a sequence you have to remember to substract one:
last = array[next_to_last - 1];
last = array[first + length - 1];
So when you say:
else if(j>(height+border)){
fmatr[i][j] = fmatr[i][(height+border)];
}
You probably mean:
else if(j >= height + border){
fmatr[i][j] = fmatr[i][height + border - 1];
}
And the same with the witdh run.
That said I would write the inner loop as two loops. IMO your intention is clearer this way:
for (j = 0; j < border; ++j)
fmatr[i][j] = fmatr[i][border];
for (j = height + border; j < height + 2 * border; ++j)
fmatr[i][j]=fmatr[i][height + border - 1];
And the same with the width run.

Related

Finding maximum bitwise and value in a two faced card

There are a list of cards with two numbers on it, one on the front and one on the back. I need to maximize the bitwise-and (&) by either taking the front or back of each card. And yes it should be done in minimum flips possible, as initially the cards are facing front and when I pick the number at the back, I am making a flip. I have solved this problem using the following code:
for(int bit = 1<<30;bit > 0;bit>>=1){
bool possible = true;
//Setting state to '0' for not flipping and '1' for flipping.'-1' means unset
for(int i = 0;i < n;i++){
if(state[i]==0 && !(A[i]&bit))possible = false;//A is the array to store front value
else if(state[i]==1 && !(B[i]&bit))possible = false;// B is the array to store back value
else if(!(A[i]&bit) &&!(B[i]&bit))possible = false;
}
if(!possible)continue;
for(int i = 0;i < n;++i){**//SNIPPET TO REPLACE START**
if (state[i] != -1)continue;
if (!(A[i]&bit))state[i] = 1;
else if (!(B[i]&bit))state[i] = 0;//SNIPPET TO REPLACE END
}
/*USING THIS SNIPPET GIVED WRONG ANSWER
for(int i = 0;i < n;++i){
if(state[i]!=-1)continue;
if(A[i] & bit)state[i]=0;
else if(B[i] & bit)state[i]=1;
}
*/
}
int ans;
int count_ = 0;
ans = (1 << 30) - 1;
for(int i = 0;i < n;i++){
if(state[i]==1){
ans&=B[i];
count_++;
}
else ans&=A[i];
}
As explained in the comments of the code, I feel the both snippet should work just fine. I maybe missing some edge case why the snippet I commented does not work as the one I actually used in the code for execution.

(double) for-loop with variable indexing in C

I have a buffer with IDs which looks like this
InBuffer={ID1,ID2,ID3,...}
I need to iterate through, every time using the ID in a function that returns pointers to the Data assigned to this ID and the size of the Data. I then need to fill in another buffer with the result which is of the form
OutBuffer={ID1,SIZE1,DATA1.WORD1,...,DATA1.WORDSIZE1,
ID2,SIZE2,DATA2.WORD1,...,DATA2.WORDSIZE2,
...,
IDN,SIZEN,DATAN.WORD1,...,DATAN.WORDSIZEN
}
I am having problems with forming the whole for-loop for this and the indexing of it, mainly because each SIZE variable can be different. It should be simple but I can't seem to make it work.
Thanks in advance for any help.
// For example
// Iterate through the remaining of the Request Buffer (m=0,1 already set)
for (m = 2; m < InBuffer; m++)`
{
OutBuffer[m] = InBuffer[m];
returnPointersToDataAndSizeFunction(InBuffer[m], &SIZE, &DATA);
OutBuffer[m + 1] = SIZE; // e.g. SIZE = 2, therefore DATA has 2 fields
OutBuffer[m + 2] = DATA.1; // first field
OutBuffer[m + 3] = DATA.2; // second field
// and so on
}
The first thing I notice is that you're using m to index both buffers:
for (m = 2; m < InBuffer; m++)
{
OutBuffer[m]=InBuffer[m];
but then you're using offsets from m for the additional data in OutBuffer:
OutBuffer[m+1]=SIZE;
OutBuffer[m+2]=DATA;
So, what you do think is going to happen in the next iteration of the loop? Say you go through the loop the first time, so that m is 2. The next time, it's m++, i.e. 3, and you make this assignment again:
OutBuffer[m]=InBuffer[m];
But you already assigned something at m[3], and that's the SIZE value from the previous iteration. You also assigned DATA at m[4], and that's going to be overwritten by the SIZE value in this iteration. Eventually, you'll end up with OutBuffer containing exactly what's in InBuffer, plus the SIZE and DATA values for the very last ID.
You need to use a different variable to index OutBuffer, something like:
for (m = 2, n = m; m < InBuffer; m++) {
OutBuffer[n++] = InBuffer[m];
returnPointersToDataAndSizeFunction(InBuffer[m],&SIZE,&DATA);
OutBuffer[n++] = SIZE;
OutBuffer[n++] = DATA;
}
There are some other problems as well. For example, the condition in the for loop shouldn't compare m to InBuffer, but should instead compare m and the number of entries in InBuffer. But just straightening out your indexing should be a big step forward.
Update: I just noticed that the data for each ID is larger than just one field. You'll need another loop inside the first one, then, so that you end up with something like this:
for (m = 2, n = m; m < InBuffer; m++) {
OutBuffer[n++] = InBuffer[m];
returnPointersToDataAndSizeFunction(InBuffer[m],&SIZE,&DATA);
OutBuffer[n++] = SIZE;
for (i = 0; i < SIZE; i++) {
OutBuffer[n++] = DATA[i];
}
}
If DATA is a structure with fields rather than an array, then you may need a series of if statements to check whether each field should be included or not. You can't use the value of a variable like i as the name of a field, i.e. you can't say DATA.i where i is a variable. I don't think a C structure can have field names that are numbers -- identifiers generally have to start with a letter or underscore, so trying to do that won't make much sense anyway. If you have control over the type of DATA, you should make it an array instead of a structure. So your loop would look more like this:
for (m = 2, n = m; m < InBuffer; m++) {
OutBuffer[n++] = InBuffer[m];
returnPointersToDataAndSizeFunction(InBuffer[m],&SIZE,&DATA);
OutBuffer[n++] = SIZE;
i = 0;
if (i++ < SIZE) { OutBuffer[n++] = DATA.field1; }
if (i++ < SIZE) { OutBuffer[n++] = DATA.field2; }
// and so on for each field in DATA's type
}
As Caleb pointed out you should use one variable for each array.
If you're saying that DATA can contain more than one element then you should increase the variable for outBuffer by SIZE each iteration. Also use a loop to asign DATAs fields to OutBuffer
int n = XXX; // set n to the first element you need to assign an ID to
for (m = 2; m < ElementsInBuffer; m++)
{
OutBuffer[n] = InBuffer[m];
returnPointersToDataAndSizeFunction(InBuffer[m],&SIZE,&DATA);
OutBuffer[n + 1] = SIZE;
for (int i = 0; i < SIZE; i++)
{
OutBuffer[n + 2 + i] = DATA[i]; // works for array only see Calebs answer to see how it works for structs
}
n += SIZE + 1; // +1 to also skip the field for SIZE
}

Out of bounds 2D array error in C

Im stuck on this one part and I was hoping to get some help. I have a project that is basically a word search. The program reads in a file that contains the Rows and columns followed by the word search puzzle itself. You are required to create possible combinations of strings from the word search and check those combinations with a dictionary that is provided as another text document.
Here's an example of the file read in 1st is Rows and 2nd is Cols followed by the word search puzzle:
4 4
syrt
gtrp
faaq
pmrc
So I have been able to get most of the code to work except for the function that creates strings for the above file. Basically It needs to search the wordsearch and create strings, each created string gets passed on to another function to check if it's in the dictionary. However my code keeps going out of bounds when creating the strings, and it's continuing to cause Seg faults which is really frustrating.
Theses are the constants that are declared, its every possible direction to go while searching the word search puzzle for possible string combinations
const int DX_SIZE = 8;
const int DX[] = {-1,-1,-1,0,0,1,1,1};
const int DY[] = {-1,0,1,-1,1,-1,0,1};
This is the function I have to create the strings:
int strCreate(char** puzzle, char** dictionary, int n, int rows, int col){
int x, y;
int nextX, nextY, i;
char str[20] = {0};
int length = 1;
for(x = 0; x < rows; x++)
{
for(y = 0; y < col; y++)
{
//Grabs the base letter
str[0] = puzzle[x][y];
length = 1;
for(i = 0; i < DX_SIZE; i++)
{
while(length < MAX_WORD_SIZE)
{
nextX = x + DX[i]*length;
nextY = y + DY[i]*length;
// Checking bounds of next array
//This is where I'm having trouble.
if((x + nextX) < 0 || (nextX + x) > (col-1)){
printf("Out of bounds\n");
break;
}
if((y + nextY) < 0 || (nextY + y) > (rows-1)){
printf("Out of bounds\n");
break;
}
str[length] = puzzle[nextX][nextY];
//search for str in dictionary
checkStr(str, dictionary, n);
length++;
}
memset(&str[1], '\0', 19);
}
}
}
return 0;
}
I know i'm not checking the bounds properly I just can't figure out how to. When X = 1 and nextX = -1, that passes the bounds check, however say the array is at puzzle[0][0] nextX would put puzzle[-1][0] which is out of bounds causing the seg fault.
Thank you for taking the time to read, and I appreciate any help at all.
nextX and nextY are the indices used to access the array puzzle. Then the array bound check should also include the same. But the array bound check includes for example x+nextX.
// Checking bounds of next array
//This is where I'm having trouble.
if((x + nextX) < 0 || (nextX + x) > (col-1)){
printf("Out of bounds\n");
break;
}
Example:
if( nextX < 0)
printf("Out of bounds...\n");

Issue with displaying vertical and diagonal letters - C Programming

I'm totally new to C Programming and I'm trying to create a Word Search .
I've got a list of words , where only 4 are randomly picked. These 4 words than are to be printed in a grid horizontally, vertically or diagonally, however I can only get them to print horizontally. I also must add that I have no idea on how the piece of code works so I really appreciate if someone kind enough can actually help me. So can anybody help me in the right direction to create the random words in a vertical and diagonal alignment ?
http://imgur.com/VSrXf4C
void putHorizzontalWord(char word[10])
{
int rRow, rCol , ok , i;
do
{
rRow = rand() % 10;
rCol = rand() % 10;
ok = 1;
if(rCol + strlen(word) < 10)
{
for(i = 0;i < strlen(word);i++)
{
if(puzzle[rRow][rCol + i] == ' ' ||
puzzle[rRow][rCol + i] == word[i])
{
puzzle[rRow][rCol + i] = word[i];
}
else
{
ok = 0;
}
}
}
else
{
ok = 0;
}
}
while(ok == 0);
}
Here are some comments aimed to explain you what does that code does:
// This function takes a string as input then puts that string
// at a random "open" location in a 2D grid (puzzle) in an
// horizontal manner
//
// This function expects the size of the string to be at most = 10
void putHorizontalWord(char word[10])
{
int rRow, rCol , ok , i;
do
{
// Randomly select a location
rRow = rand() % 10;
rCol = rand() % 10;
// For now, assume that this location is "ok", i.e. is open
ok = 1;
// Check that the word fits inside the grid from (rRow, rCol)
if(rCol + strlen(word) < 10)
{
// If it does, then try to put the word at this location
// Thus, we need to process the word character by character
for(i = 0;i < strlen(word);i++)
{
// We are inside the for loop
// The current character to process is word[i]
// And the current cell to fill is (rRow, rCol + i)
//
// If current cell is empty || is same as the current character
// then this cell is "open" i.e. we can use it
if(puzzle[rRow][rCol + i] == ' ' ||
puzzle[rRow][rCol + i] == word[i])
{
puzzle[rRow][rCol + i] = word[i];
}
else
{
// The cell is not open
// => (rRow, rCol) is not "ok"
ok = 0;
}
}
}
else
{
// word not fits inside the grid from the location
// => (rRow, rCol) is not "ok"
ok = 0;
}
}
while(ok == 0); // Exit loop while not found a good location
}
If you have understood, then you can now modify this to write your vertical and diagonal versions. If you still have not understood, let me know what is still not clear.

Need some suggestions on how to print a histogram more neatly

I'm writing a program that will read input and then give back a histogram of the character count from K & R - Ex. 1.13
Any suggestions on how I can improve my code? Does it matter whether or not if I test for status in condition or out first? I have noticed in my examples people test to see if c is a blank or tab first.
I think I need to revisit my histogram. It doesn't really scale the results. It just draws a hyphen based on the length.
Revised to make a little bit more readable I think.
// Print a histogram of the length of words in it's input.
#include <stdio.h>
#define IN 1
#define OUT 2
#define MAX 99
int main(){
int c; // the character
int countOfLetters = 0;
int insideWord = OUT;
int frequencyOfLengths[MAX];
int longestWordCount = 0;
int i, j; // Counters
for (i = 0; i < MAX; i++){
frequencyOfLengths[i] = 0;
}
while ((c = getchar()) != EOF){
if (c == ' ' || c == '\n' || c == '\t'){
if (insideWord == IN){
if (countOfLetters > MAX){
return 1;
}
++frequencyOfLengths[countOfLetters];
if (countOfLetters >= longestWordCount) longestWordCount = countOfLetters;
}
countOfLetters = 0;
}
else {
countOfLetters++;
insideWord = IN;
}
}
for (i = 1; i <= longestWordCount; i++){
printf("%3i : %3i ", i, frequencyOfLengths[i]);
for (j = 0; j < frequencyOfLengths[i]; j++){
printf("*");
}
printf("\n");
}
return 0;
}
Definitely scale results, check out my Character Histogram that does a horizontal scaling histogram.
Also, you could benefit a y-axis label. It's hard to tell which bar is for which kind of word length. I have no idea which bar is for what word length.
I added this code right before you display the histogram, it basically halves every value, which does throw off your bar number labels. You can figure it out!
// Iterates and tells us the most frequent word length
int mostFrequent = 0;
for (i = 1; i < MAXWORD; i++)
if (charCount[i] > mostFrequent)
mostFrequent = charCount[i];
// If the bar will be too big, cut every value in half
while (mostFrequent > 60) {
for (i = 1; i < MAXWORD; i++)
if (charCount[i] > 0) {
charCount[i] /= 2;
charCount[i] |= 1;
}
// Check again to find the most frequent word length category
mostFrequent = 0;
for (i = 1; i < MAXWORD; i++)
if (charCount[i] > mostFrequent)
mostFrequent = charCount[i];
}
Honestly the bars are hard to read, maybe just use a single row of characters such as █ !
Great book so far, we're practically reading it together and are on the same page!
Cheers

Resources