I am generating random values and parsing into arrays.
Any idea which part is causing the problem?
Thank you all in advance! :)
for(x=0; x<numberOfSboxes; x++)
{
vecCheck.clear();
for (y=0;y<sbox_Size; y++)
{
int secondTemp = y;
int firstTemp;
firstTemp = rand() % numberRange;
int mycount = (int) std::count (vecCheck.begin(), vecCheck.end(), y); // count if number is in vector
if( (mycount==1) || (firstTemp==y) )
{
continue;
}
else
{
if(vecCheck.size()==0)
{
vecCheck.push_back(firstTemp); // first number
sBox[x][y] = firstTemp;
sBox[x][firstTemp] = secondTemp;
vecCheck.push_back(secondTemp); //second number
}
else
{
int mycount = (int) std::count (vecCheck.begin(), vecCheck.end(), firstTemp); // count if number is in vector
if(mycount==1)
{
//if number generated is found, then break loop and restart
--y;
continue;
}
else
{
//if number generated is not found
sBox[x][y] = firstTemp; // first number generated
sBox[x][firstTemp] = secondTemp;
vecCheck.push_back(firstTemp); //push back to record
vecCheck.push_back(secondTemp); //push back to record
}
}
}
}
}
It does not always generate garbage values but sometimes it does.
An example is to be shown below.
sBox[0][16] = {9,12,15,5,7,3,12765952,4,13,0,11,10,1,8,12688216,2};
sBox[1][16] = {6,11,3,2,8,10,0,15,4,134514593,5,1,14,-1075,0,78827,12,7};
sBox[2][16] = {3,4,7,0,1,13,11,2,10,14,8,6,15,5,9,12};
I do not think it has a problem on the rand().
EDIT:
firstTemp generation has no issues. the numbers are always in the range of 0-15.
anyone knows why the output of the values tend to be of such stated above?
Related
A kyu on codewars asks for the following:
Complete the method which accepts an array of integers, and returns
one of the following:
"yes, ascending" - if the numbers in the array are sorted in an
ascending order "yes, descending" - if the numbers in the array are
sorted in a descending order "no" - otherwise You can assume the array
will always be valid, and there will always be one correct answer.
I put together the following but run into "Caught unexpected signal: SIGSEGV (11). Invalid memory access" when testing. Can someone please explain the error to me and what part of the script triggers it?
#include <stdio.h>
char* isSortedAndHow(int* array, int arrayLength)
{
// Create an empty array where ascending or descending test results will be stored
int results[] = {};
int i;
// If the value is greater than the previous one add a 1, if smaller add a 0, if equal, add 1000
for (i = 1; array[i]; i++){
if (array[i] < array[i-1]){
results[i-1] = 0;
} else if (array[i] > array[i-1]) {
results[i-1] = 1;
} else {
results[i-1] = 1000;
}
}
// Add the value of all values in the results array and return the answer
int sum = 0;
for (i=0; results[i]; i++) {
sum = sum + results[i];
} if (sum == 0) {
return "yes, descending";
} else if (sum == (arrayLength - 1)) {
return "yes, ascending";
} else {
return "no";
}
}
The culprit is the line
int results[] = {};
You declare an array of int with a size of zero. Further down the code you try to write into that array: BOOM!
One possible solution is to allocate the array with the size arrayLength. But as commenters said, you don't need this array at all. Rethink your algorithm.
else {
masterNum[3] = guess % 10; //checks integers in their respective positions
masterNum[2] = ((guess - guess%10)/10)%10;
masterNum[1] = ((guess - guess % 100)/100)%10;
masterNum[0] = (guess - guess % 1000)/1000;
masterDigit(guess, masterNum);
}
//}
//This method determines the total number of correct digits but not
//necessarily in the correct position
public static int masterDigit (int [] guess,int [] code) //int [] guess
{
int i,j,k,number;
int [] tempGuess = new int [4]; //an array to hold a copy of a code
boolean found;
number = 0;
for(k=0; k<4; k++) //copies code to tempGuess so code
//doesn't get changed (you can't just assign code to tempGuess)
tempGuess[k] = code[k];
for(i = 0; i < 4; i++)
{
j=0;
found = false;
while(j < 4 && found == false) // a while loop instead of a
// for loop so duplicates are only counted once
{
if(guess[i] == tempGuess[j])
{
found = true;
tempGuess[j] = -1; // fills up tempGuess with an impossible
// value so that index only gets
// counted once
number++;
}
j++;
}
}
return number;
}
This code is for a Mastermind game with integers. Upon running through the compiler, there is an error saying that integer "guess" cannot be converted to an array. How can I get my guess (defined as an integer scanner console) to go into this method that will check which numbers are correct?
I have to request user input for 10 different numbers. I have to see if the user input is less than the last number entered (which was added to an array). I'm having trouble comparing it, as my logic seems sound but for whatever reason it wont keep lower numbers inputted earlier in the loop. Maybe you guys can take a look and see where the issue lies in my if statement. The getNum() function just gets user input and returns it if your curious. Thanks in advance!
#include <stdio.h> //including for the use of printf
/* == FUNCTION PROTOTYPES == */
int getNum(void);
/* === COMPILER DIRECTIVE - to ignore the sscanf() warning === */
#pragma warning(disable: 4996)
int main(void)
{
// defining varibles
int myArray[11] = { 0 };
int counter = 0;
int indexTracker = -1;
int numInput = 0;
int lowestNum = 0;
int lowestNumPlace = 0;
// printing as to why I need 10 numbers
printf("I require a list of 10 numbers to save the world!\n");
// while loop
// while 'counter' is less than or equal to 9, loop
while (counter <= 9)
{
// adding 1 to each varible, everytime the program loops
indexTracker += 1;
counter += 1;
// printing to request a number, giving which number they are
// inputting
// out of the list of 10
// calling getNum() for input, saving the number into the array
printf("Please enter a number for #%d: ", counter, "spot\n");
numInput = getNum();
myArray[indexTracker] = numInput;
if (numInput <= myArray[indexTracker])
{
lowestNum = numInput;
lowestNumPlace = indexTracker;
}
}
// printing the lowest value and its index
printf("The lowest number is: %d at index [%d].", lowestNum,
lowestNumPlace);
return 0;
}
You're always assigning a new value to lowestNum
numInput = getNum();
myArray[indexTracker] = numInput;
if (numInput <= myArray[indexTracker])
{
lowestNum = numInput;
lowestNumPlace = indexTracker;
}
... because after doing A=B, B<=A will logically always be true.
Try this instead:
numInput = getNum();
myArray[indexTracker] = numInput;
if (numInput <= lowestNum) // note, comparing to the lowest number, not the current one
{
lowestNum = numInput;
lowestNumPlace = indexTracker;
}
I am given 2 arrays, Input and Output Array. The goal is to transform the input array to output array by performing shifting of 1 value in a given step to its adjacent element. Eg: Input array is [0,0,8,0,0] and Output array is [2,0,4,0,2]. Here 1st step would be [0,1,7,0,0] and 2nd step would be [0,1,6,1,0] and so on.
What can be the algorithm to do this efficiently? I was thinking of performing BFS but then we have to do BFS from each element and this can be exponential. Can anyone suggest solution for this problem?
I think you can do this simply by scanning in each direction tracking the cumulative value (in that direction) in the current array and the desired output array and pushing values along ahead of you as necessary:
scan from the left looking for first cell where
cumulative value > cumulative value in desired output
while that holds move 1 from that cell to the next cell to the right
scan from the right looking for first cell where
cumulative value > cumulative value in desired output
while that holds move 1 from that cell to the next cell to the left
For your example the steps would be:
FWD:
[0,0,8,0,0]
[0,0,7,1,0]
[0,0,6,2,0]
[0,0,6,1,1]
[0,0,6,0,2]
REV:
[0,1,5,0,2]
[0,2,4,0,2]
[1,1,4,0,2]
[2,0,4,0,2]
i think BFS could actually work.
notice that n*O(n+m) = O(n^2+nm) and therefore not exponential.
also you could use: Floyd-Warshall algorithm and Johnson’s algorithm, with a weight of 1 for a "flat" graph, or even connect the vertices in a new way by their actual distance and potentially save some iterations.
hope it helped :)
void transform(int[] in, int[] out, int size)
{
int[] state = in.clone();
report(state);
while (true)
{
int minPressure = 0;
int indexOfMinPressure = 0;
int maxPressure = 0;
int indexOfMaxPressure = 0;
int pressureSum = 0;
for (int index = 0; index < size - 1; ++index)
{
int lhsDiff = state[index] - out[index];
int rhsDiff = state[index + 1] - out[index + 1];
int pressure = lhsDiff - rhsDiff;
if (pressure < minPressure)
{
minPressure = pressure;
indexOfMinPressure = index;
}
if (pressure > maxPressure)
{
maxPressure = pressure;
indexOfMaxPressure = index;
}
pressureSum += pressure;
}
if (minPressure == 0 && maxPressure == 0)
{
break;
}
boolean shiftLeft;
if (Math.abs(minPressure) > Math.abs(maxPressure))
{
shiftLeft = true;
}
else if (Math.abs(minPressure) < Math.abs(maxPressure))
{
shiftLeft = false;
}
else
{
shiftLeft = (pressureSum < 0);
}
if (shiftLeft)
{
++state[indexOfMinPressure];
--state[indexOfMinPressure + 1];
}
else
{
--state[indexOfMaxPressure];
++state[indexOfMaxPressure + 1];
}
report(state);
}
}
A simple greedy algorithm will work and do the job in minimum number of steps. The function returns the total numbers of steps required for the task.
int shift(std::vector<int>& a,std::vector<int>& b){
int n = a.size();
int sum1=0,sum2=0;
for (int i = 0; i < n; ++i){
sum1+=a[i];
sum2+=b[i];
}
if (sum1!=sum2)
{
return -1;
}
int operations=0;
int j=0;
for (int i = 0; i < n;)
{
if (a[i]<b[i])
{
while(j<n and a[j]==0){
j++;
}
if(a[j]<b[i]-a[i]){
operations+=(j-i)*a[j];
a[i]+=a[j];
a[j]=0;
}else{
operations+=(j-i)*(b[i]-a[i]);
a[j]-=(b[i]-a[i]);
a[i]=b[i];
}
}else if (a[i]>b[i])
{
a[i+1]+=(a[i]-b[i]);
operations+=(a[i]-b[i]);
a[i]=b[i];
}else{
i++;
}
}
return operations;
}
Here -1 is a special value meaning that given array cannot be converted to desired one.
Time Complexity: O(n).
I currently have a 2D char array size: [5][256].
The array can hold either numbers or letters.
I have been tasked with using the Selection Sort to sort the strings into ascending order.
My idea is to convert each row into ASCII and then sort the values in ascending order then convert back to chars.
Ive implemented a 2D Array Selection sort for another task, however, it doesnt work here as i coded it to work with 2 columns not 256 like here (not sure how to change it).
What i need help with is how do i use the ASCII value for each row and use it in a selection sort.
Been trying to figure this out for hours now, driving me mental.
Any help is appreciated.
Im not necessarily looking for someone to code everything for me, more of a kick in the right direction. Im new to C and not aware of every function C can do.
Here is my current code in full:
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
char arc5Strings[5][256];
int nCount, nCount2, nCount3, nCount4, nCount5, nCount6, nCount7;
int fMinVal[1][2] = {1,1};
int nMinValPosition;
int nMoves;
int nRow;
int fTemp[1][2] = {1,1};
int fTemp2[1][2] = {1,1};
//input the values
for(nCount=0; nCount < 5; nCount++)
{
printf("Please input string %d/5: ", nCount + 1);
fgets(arc5Strings[nCount], 256, stdin);
}
printf("\n\n");
//print entire array
for(nCount3 = 0; nCount3 < 5; nCount3++)
{
for(nCount4 = 0; arc5Strings[nCount3][nCount4] != '\0'; nCount4++)
{
printf("%d ", arc5Strings[nCount3][nCount4]);
//ASCII values outputted in a line instead of in array format when using %c
}
}
return 0;
}
Old 2D Array selection sort i devised - extracted from code:
//-----------------------------------
//set up the switch
for(nCount5 = 0; nCount5 < 5; nCount5++)
{
fMinVal[0][0] = arc5Strings[nCount5][0]; //min value is row 0 col 1
nMinValPosition = nCount5;
for(nCount6 = nCount5 + 1; nCount6 < 5; nCount6++)
{
if(arc5Strings[nCount6][1] < fMinVal[0][0])
{
fMinVal[0][0] = arc5Strings[nCount6][0];
nMinValPosition = nCount6;
}
/* Perform the switch - actually switch the values */
if(fMinVal[0][0] < arc5Strings[nCount5][0])
{
fTemp[0][1] = arc5Strings[nCount5][1];
fTemp2[0][0] = arc5Strings[nCount5][0];
arc5Strings[nCount5][1] = arc5Strings[nMinValPosition][1];
arc5Strings[nCount5][0] = arc5Strings[nMinValPosition][0];
arc5Strings[nMinValPosition][1] = fTemp[0][1];
arc5Strings[nMinValPosition][0] = fTemp2[0][0];
nMoves++;
}
}
}
//------------------------------
printf("\n\n");
printf("The sorted list, in ascending order, using selection sort, is:\n\n");
for(nCount3 = 0; nCount3 < 5; nCount3++)
{
for(nCount4 = 0; arc5Strings[nCount3][nCount4] != '\0'; nCount4++)
{
printf("%c", arc5Strings[nCount3][nCount4]);
}
}
printf("\n %d moves were made to sort this list\n", nMoves);
EDIT - RESULTS OF GEORGE'S ANSWER:
Input1 = 90
Input2 = 70
Input3 = abc
Input4 = 500
Input5 = 200
Sorted Array Results:
200
90
70
abc
500
You're on the right track. I would implement this as follows:
for(i=0;i<5;i++)
{
indexOfCurrentSmallest = i;
for(j=i;j<5;j++)
{
for(k=0;k<255;k++)
{
if(arc5Strings[j][k] < arc5Strings[indexOfCurrentSmallest][k])
{
//we found a new possible smallest
indexOfCurrentSmallest = j;
break;
}
else if(arc5Strings[j][k] > arc5Strings[indexOfCurrentSmallest][k])
{
//no point in searching further, the one we are looking at is already larger than the one we found.
break;
}
}
}
//here, we have found the actual smallest, let's do a swap
for(q=0;q<255;q++)
{
temp = arc5Strings[i][q];
arc5Strings[i][q] = arc5Strings[indexOfCurrentSmallest][q];
arc5Strings[indexOfCurrentSmallest][q] = temp;
}
}
I haven't tested this code, but it should be roughly what you're looking for. Basically, it compares ASCII values starting at the left, until it finds a difference, and stores the index for later swapping after comparing all 5 strings.
EDIT I've now tested the code above, and it works now.
First find each string length
int length[5];
for(i = 0, i < 5, i++){
length[i] = strlen(arc5Strings[i]);
}
Sort the lengths. Those with the same, compare the value of the first letter.
Thats it.
valter