How to set specific values to arrays in a loop? - C - c

I'm in a beginner programming course and our assignment is make a program of a game that starts with 10 people. You start with the first person and count people till 3, then drop that person. You keep doing this until there is only one person left.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n[10] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, i = 0;
int * ptrN = &n[i];
for( i = 0; n[i]; n[i+3]){
if (n[i+3] = 1){
*ptrN = 0;
}
else if (n[i] = 0)
continue;
else
printf("Wrong");
}
printf("The value of n0 %d\tn1 %d\tn2 %d\tn3 %d\tn4 %d\tn5 %d\tn6 %d\tn7 %d\tn8 %d\tn9 %d", n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7], n[8], n[9]);
return 0;
}
I'm far off from my answer right now but I'm already encountering problems. When I run the above code, it will only change the value of n[0] and then will exit program. Would appreciate any guidance. Thank you

As mentioned in the comments:
Use == to compare, = is for assignment.
You don't need to use a pointer. You can use n[i]
You need to increment i.
You need to skip over the 0's.
As you mentioned, you also need to stop when there is only one 1 left.
There are more than one way to solve that but you could do it by having a counter for how many 1's there are and have a while-loop that ends when the counter is down to 1:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n[10] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, count = 10;
/* `i` needs to start at -1 so that we start counting:
* "0, 1, 2. n[2] is out!"
* instead of counting:
* "1, 2, 3. n[3] is out!"
*/
int i = -1;
while (count > 1) {
/* We need to count three of those persons that are not out.
* That means we have to search for the next person that is not
* out (by skipping over `0`) and repeat that three times.
*
* If we just increase `i` by 3 ( `(i + 3) % 10` ) then we are
* not checking how many of those persons between `n[i]` and
* `n[(i + 3) % 10]` needed to be skipped over.
*
* So repeat three times:
*/
for (int j = 0; j < 3; j++) {
/* This will search for the next person that is not out by
* increasing `i` by one until `n[i]` is not `0`:
*/
do {
i = (i + 1) % 10;
} while (n[i] == 0); // Check next person if this one is out.
} // I forgot to close this bracket in my first version of the answer
n[i] = 0;
count--;
}
printf("The value of n0 %d\tn1 %d\tn2 %d\tn3 %d\tn4 %d\tn5 %d\tn6 %d\tn7 %d\tn8 %d\tn9 %d", n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7], n[8], n[9]);
return 0;
}

Related

C/C++ Bitwise operation university problem

Problem
Given a sequence of N integer values(possible values of N: 3, 5, 7, 9, 11 ...). Using at most one conditional operator(or conditional ternary operation), the program must determine whether it is true that every three elements the sequence increases and then decreases(sine sequence). Loops in a program can only be used to enumerate elements of a sequence.
Example
* *
* * * *
* * *
What I think
int compare_num(int num1, int num2)
{
return (int)(((num1 + num2) - sqrt((num1 - num2) * (num1 - num2))) / 2);
}
bool_t is_increasing2(int arr[], int size)
{
int tmin = arr[0];
int res = 0;
for (int i = 0; i < size - 1; i++)
{
tmin = compare_num(arr[i + 1], tmin);
res = tmin ^ arr[i + 1];
}
return res;
}
int main(void)
{
int arr[] = {10, 9, 8, 7, 6, 5};
int arr2[] = {1, 2, 3, 4, 5};
int res = is_increasing2(arr2, N);
if (res == 0)
{
printf("Decreasing\n");
}
else
{
printf("Increasing\n");
}
return 0;
}
I use this code to check, that sequence is increasing or not. But now I need to use it to check, that my sine sequence is sine and I can't use more ternary or if/else operators
There is what I have to real problem
bool_t is_increasingSine2(int arr[], int size){
int tmax = 0;
int res = 0;
for(int i = 0; i < size; i += 3){
for(int j = i; j < i + 2 && j < size - 1; j++){
tmax = compare_num(arr[j], arr[j + 1]);
res = tmax ^ arr[j + 1];
}
//There if res == 0 part of sine is increasing otherwise not, but what to do next???
}
return 0;
}
You do not need any conditional operators for this problem, but we will use one in the printf since it is suggested.
Rephrasing the problem as a requirement that each of the first two elements must be less than the one that follows it and each of the next two must be greater than the one that follows it makes it fairly simple to test:
#include <stdio.h>
#include <stdlib.h>
/* Given array Array with N elements, return true iff each of the first two
elements is less than the one following it, each of the next two is greater
than the one following it, and then repeating in a cycle until the end of
the array.
*/
static _Bool TestCriterion(int Array[], size_t N)
{
/* Iterate through each element of the array except the last (the one
with index N-1), since there is no element following the last element
to compare it to.
*/
for (size_t i = 0; i < N-1; ++i)
{
/* Set phase to 0 for the first two elements, 1 for the next two,
then 0, 1, 0, 1… Note that while "i & 2" has the value 0 or 2,
assigning it to a Boolean produces a value of 0 or 1.
*/
_Bool Phase = i & 2;
/* For phase 0, test whether the element with index i is less than
the element with index i+1, and return false (0) if it is not. For
phase 1, compare element i+1 with element i.
*/
if (! (Array[i+Phase] < Array[i+1-Phase]))
return 0;
}
// All elements passed the test, so return true (1).
return 1;
}
/* Compute the number of elements in an array by dividing the size of the
array by the size of an element.
*/
#define NumberOf(a) (sizeof (a) / sizeof *(a))
int main(void)
{
int Array[] = { 1, 2, 3, 2, 1, 2, 3, 2, 1 };
printf("%s.\n", TestCriterion(Array, NumberOf(Array)) ? "Passes" : "Fails");
}

How to make a series that adds up by 5 every 5 counts using for loop?

I'm kind of new in C programming and I'm trying to make a program that prints the nth term of a series and every 5 counts, it adds up by 5.
Example: 1, 2, 3, 4, 9, 10, 11, 12, 17, 18, 19, 20, 25......
Here is my code
int num,digit,count = 1;
printf("Enter n: ");
scanf("%d", &num);
for(int i=1; i<=num; i++){
count++;
if(count > 5){
count = 0;
i+=4;
}
printf("%d ",i);
}
My code doesn't get to the specific nth term that I'm asking for. For example, I've inputted 10 and it only shows up until the 6th term
The thing to do is get clear in your head what you want to do and how you are going to do it. Rather than tinkering with code, break things down into simple parts and make them clear.
#include <stdio.h>
int main(void)
{
int num = 10;
// Method 1: Spell everything out.
// i counts number of terms printed.
// j counts number of terms since last multiple of four terms.
// k is current term.
for (
int i = 0, j = 0, k = 1; // Initialize all counters.
i < num; // Continue until num terms are printed.
++i) // Update count.
{
printf("%d ", k); // Print current term.
++j; // Increment four-beat count.
if (4 <= j)
{
// Every fourth term, reset j and increment the term by 5.
j = 0;
k += 5;
}
else
// Otherwise, increment the term by 1.
k += 1;
}
printf("\n");
// Method 2: Use one counter and calculate term.
// Iterate i to print num terms.
for (int i = 0; i < num; ++i)
/* Break the loop count into two parts: the number of groups of 4
(i/4) and a subcount within each group (i%4). Looking at the
starts of each group (1, 9, 17, 25...), we see each is eight
greater than the previous one. So we multiply the group number by
8 to get the right offsets for them. Within each group, the term
increments by 1, so we use i%4 directly (effectively multiplied by
1). Then (i/4)*8 + i%4 would start us at 0 for i=0, but we want to
start at 1, so we add 1.
*/
printf("%d ", (i/4)*8 + i%4 + 1);
printf("\n");
}
You shall not change the variable i within the body of the for loop.
You need to introduce one more variable that will store the current outputted number.
Here is a demonstration program.
#include <stdio.h>
int main(void)
{
unsigned int n = 0;
printf( "Enter n: " );
scanf( "%u", &n );
for ( unsigned int i = 0, value = 0, count = 1; i < n; i++ )
{
if ( count == 5 )
{
value += 5;
count = 1;
}
else
{
++value;
}
printf( "%u ", value );
++count;
}
}
The program output is
Enter n: 13
1 2 3 4 9 10 11 12 17 18 19 20 25
Here's another take that I think is a bit less complicated, with explanations in the comments:
#include <stdio.h>
int main(void)
{
int num, count = 1;
num = 20;
// if you look closely, you actually have an initial condition before the
// main pattern starts. Once the pattern starts, its actually every _fourth_
// term that gets added by 5. You'll make things easier on yourself if you
// print out this initial condition, then handle the pattern in the loop.
// If you really want to be correct, you can wrap this in a if (num > 0) check
printf("%d ", count++);
// start at 1, because we already printed the first item
for(int i=1; i<num; i++, count++)
{
// now we can focus on every fourth term
if (i % 4 == 0)
{
// if it's the fourth one, add 5 to the previous value
// Of course this simplifies to count += 4
count = (count-1) + 5;
}
printf("%d ",count);
}
}
Demonstration

Is there a way to discard a number stored using malloc/realloc when printing the result?

What the code does:
Asks the person to enter x amount of numbers and finishes by entering a " 0 " (zero).
The numbers are then saved and stored using malloc/realloc.
With the help of a bubble sort, numbers entered will be sorted and printed out in an ascending order.
My problem: when the sorted numbers are printed out, it also adds the 0 (zero), which only purpose is to finish the task and not be added to the list of numbers entered by the person. For example if I add: 4,5,8,1,3,1,10 ("0" to finish). The printing result will be: 0, 1, 1, 3, 4, 5, 8, 10.
I'm new to C (worked with it for only about 2 weeks). So far I've tried changing " i " to 1 in this for-loop. However, all it does is to basically shift everything one step (?). Causing the 0 only to go from being first to last: 1, 1, 3, 4, 5, 8, 10, 0.
> //Bubble sort:
> for (int i = 0; i < inputNumber; i++)
I assume using free() will only work when you're looking to free all the memory stored and not one particular number? Any help is appreciated. Further, yes this is a work assignment :).
Here's the code:
int main()
{
int nr = 1;
int temp;
int *numberStore = malloc(sizeof(int));
int inputNumber = 0;
while (nr != 0)
{
printf("Add numbers to be stored (finish by entering 0): ");
scanf("%d", &nr);
printf("\n");
numberStore[inputNumber] = nr;
inputNumber++;
numberStore = realloc(numberStore, (inputNumber + 1) * sizeof(int));
}
//Bubble sort:
for (int i = 0; i < inputNumber; i++)
{
for (int j = 0; j < (inputNumber - i - 1); j++)
{
if (numberStore[j] > numberStore[j + 1])
{
temp = numberStore[j];
numberStore[j] = numberStore[j + 1];
numberStore[j + 1] = temp;
}
}
}
//Prints the stored numbers in ascending order:
for (int i = 0; i < inputNumber; i++)
{
printf("%d\n", numberStore[i]);
}
return 0;
}
Just simply don't add 0 to your data
while (nr != 0)
{
printf("Add numbers to be stored (finish by entering 0): ");
scanf("%d", &nr);
printf("\n");
if (nr != 0) // only add if not 0
{
numberStore[inputNumber] = nr;
inputNumber++;
numberStore = realloc(numberStore, (inputNumber + 1) * sizeof(int));
}
}
Or, same idea, slightly more compact: if (nr == 0) break;
Just decrement the count of numbers before sorting:
numberStore = realloc(numberStore, (inputNumber + 1) * sizeof(int));
}
// yay - the algorithm thinks there are less numbers in the array
// the last element is just zero - don't care
inputNumber -= 1;
//Bubble sort:
for (int i = 0; i < inputNumber; i++)
This would just overallocate the array for one element. A better alternative would be to make decision to add element to the array depending on the value - don't add array element if read value is 0. Remember to handle errors - realloc and scanf may fail.

Can't do all possible moves of a Horse in a Chess table

UPDATE: Thanks a lot M Oehm for your awesome answer, really helped me a lot. That struct pos moves is really helpful, haven't studied it yet on class. Im working on a fully solution of my code adding yours as a bone on the programs skeleton. Already fixed the problem of updating fila and columna, the random choice and the switch from 0 to 7 without the ' ' because they're not characters as you and davidc pointed. My program still have some problems which im working on before posting the fully operational program here. I'll update the code tomorrow if not today. Thank you all for your comments and solutions, and M oehm for the time you spent making that wonderful answer.
------------------------------------------------------------------------------------------------------------------------------------
UPDATE 2: Finnished it, made some little changes on M Oehm code and instead of putting manually the first location of the horse i used my previous PosicionCaballo(). Had to delete the code of the MoverCaballo() which had a Switch with 8 possible moves which was set by a random number because i couldn't make it work (i guess the main problem was that part because already was a mess). Now the program with the code below should ask the user for the initial position of the horse, after that the screen will print a 10x10 table filled with 0's (free spaces), fill it with 1's (taken spaces which did the horse moving randomly) and when it finnishes display a message on how many positions did it take.
COORD cxy;
#define posicion(x,y) {(cxy.X)= (x);(cxy.Y)= (y); SetConsoleCursorPosition((GetStdHandle(STD_OUTPUT_HANDLE)), (cxy) );}
int ajedrez[10][10];
int fila, columna;
void GenerarTablero(int m[10][10]){
int i, j;
for (i = 0; i < 10; i++){
for (j = 0; j < 10; j++){
m[i][j] = 0;
}
}
}
GenerarTablero makes the chess board and fills it with 0's.
Global are fila (row) and columna (column) the parts of the ajedrez[10][10]
ajedrez[10][10] is the chess table in a 10x10 size.
void PosicionCaballo(int m[10][10]){
printf("Fila: ");
scanf_s("%d", &fila);
printf("Columna: ");
scanf_s("%d", &columna);
printf("\n");
m[fila][columna] = 2;
system("cls");
}
PosicionCaballo does ask the user for the initial position of the horse and puts the horse on the table.
Example: Row: 5 Column: 5
int horse(int y, int x)
{
int visited[SIZE][SIZE] = { { 0 } };
int count = 0;
if (on_board(y, x) == 0) return -1;
/* Set starting position */
visited[y][x] = 1;
while (1) { /* Infinite loop - must use break */
int poss[8]; /* Possible moves */
int nposs = 0; /* Actual length of poss */
int i, k = 1;
for (i = 0; i < 8; i++) {
int xx = x + moves[i].x;
int yy = y + moves[i].y;
if (on_board(yy, xx) && visited[yy][xx] == 0) {
poss[nposs++] = i;
}
}
/* No more valid moves: return */
if (nposs == 0){
posicion(0, 11);
printf("El tablero se ha bloqueado con ");
return count;
}
/* pick one of the valid moves */
i = poss[rand() % nposs];
x = x + moves[i].x;
y = y + moves[i].y;
/* update horse's position */
visited[y][x] = 1;
count++;
/* print position */
posicion(y, x);
printf("1");
}
return -1; /* Should never be reached */
}
void MostrarMapa(int m[10][10]){
int i, j;
for (i = 0; i < 10; i++){
for (j = 0; j < 10; j++){
printf("%d", ajedrez[i][j]);
}
printf("\n");
}
}
MostrarMapa only prints the chess table on the screen.
int main(void){
int n;
srand(time(NULL));
GenerarTablero(ajedrez);
PosicionCaballo(ajedrez);
MostrarMapa(ajedrez);
n = horse(fila, columna);
posicion(31, 11);
printf("%d movimientos\n", n);
getch();
return 0;
}
and then my main which im using all the functions stated upside.
Thank you very much in advance for your help guys :).
I guess that your assignment is about finding a valid path that visits all squares. Your code tries to find one random path.
Your code has several errors:
When you test ajedrez[fila - 2][columna - 1], you don't check whether fila - 2 or columna - 1 are really valid indices of your chess board. If you access invalid indices, way -1 or 11, you invoke undefined behaviour.
You don't update fila and columna, that is: You don't move your horse.
You overwrite the board twice. That's not an error, but your code shouldn't do double duty.
Your random choice is broken. You have eight possible moves, so you want rand() % 8, which yields numbers from 0 to 7. (David has already pointed this out in a comment.)
Your case labels are charater constants, not numbers. Use case 0:, not case '0':.
You just skip invalid moves. When there are no more valid moves, this will result in an infinite loop. You should check this condition and terminate the loop if it occurs.
As I understand it, the ´posicion` macro is just to show ehere the horse is. Maybe you should skip that at the moment and just print the new coordinates, which isn't as pretty, but straightforward.
Your eight switch cases manifest another flaw: You have the same repeated code eight times over. The only difference is the jump pattern. Such a set-up lends itself to either writing a function where you pass the row and columns distance to jump or to using an array of possible jump patterns.
Your code should instead do something like this for each move:
Loop over all eight jump patterns. If the horse would jump off the board or if the horse would visit a tile that has already been visited, skip that possibility. Otherwise, add the move to an auxiliary array.
If the number of possibilities is zero, terminate the loop - the horse has nowhere to go.
Pick one of the valid moves.
Move the horse, mark the current tile visited.
Report the jump, if desired: Print the new position or place the cursor, whatever.
Below is an example implementation that uses an array of jump patterns. It will give one random path. You can adapt this code to your problem.
#include <stdlib.h>
#include <stdio.h>
#include <time.h> /* for time() */
#define SIZE 10 /* Fixed board size */
struct pos {
int x, y;
};
struct pos moves[8] = { /* Jump patterns */
{1, 2},
{2, 1},
{2, -1},
{1, -2},
{-1, -2},
{-2, -1},
{-2, 1},
{-1, 2}
};
/*
* Is position (y, x) a valid board coordinate?
*/
int on_board(int y, int x)
{
if (x < 0 || x >= SIZE) return 0;
if (y < 0 || y >= SIZE) return 0;
return 1;
}
/*
* Move the horse randomly, starting from (y, x). Print the
* visited fields and return the number of moves made or
* -1 if an error occurs.
*/
int horse(int y, int x)
{
int visited[SIZE][SIZE] = {{0}};
int count = 0;
if (on_board(y, x) == 0) return -1;
/* Set starting position */
visited[y][x] = 1;
printf("%c%d, ", 'A' + y, x + 1);
while (1) { /* Infinite loop - must use break */
int poss[8]; /* Possible moves */
int nposs = 0; /* Actual length of poss */
int i;
for (i = 0; i < 8; i++) {
int xx = x + moves[i].x;
int yy = y + moves[i].y;
if (on_board(yy, xx) && visited[yy][xx] == 0) {
poss[nposs++] = i;
}
}
/* No more valid moves: return */
if (nposs == 0){
printf("whoa!\n");
return count;
}
/* pick one of the valid moves */
i = poss[rand() % nposs];
x = x + moves[i].x;
y = y + moves[i].y;
/* update horse's position */
visited[y][x] = 1;
count++;
/* print position */
printf("%c%d, ", 'A' + y, x + 1);
}
return -1; /* Should never be reached */
}
int main()
{
int n;
srand(time(NULL));
n = horse(3, 6);
printf("%d moves\n", n);
return 0;
}
You seem to update the position using posicion(), but not update fila and columna

How to find the element of an array that is repeated at least N/2 times?

Given an array with N elements. We know that one of those elements repeats itself at least N/2 times.
We don't know anything about the other elements . They may repeat or may be unique .
Is there a way to find out the element that repeats at least N/2 times in a single pass or may be O(N)?
No extra space is to be used .
As the other users have already posted the algorithm, I won't repeat that. However, I provide a simple explanation as to why it works:
Consider the following diagram, which is actually a diagram of unpolarized light:
Each arrow from the centre represents a different candidate. Imagine a point somewhere on an arrow representing the counter and candidate. Initially the counter is at zero, so it begins in the centre.
When the current candidate is found, it moves one step in the direction of that arrow. If a different value is found, the counter moves one step towards the centre.
If there is a majority value, more than half of the moves will be towards that arrow, and hence the algorithm will end with the current candidate being the majority value.
st0le answered the question, but here's a 5minute implementation:
#include <stdio.h>
#define SIZE 13
int boyerMoore(int arr[]) {
int current_candidate = arr[0], counter = 0, i;
for (i = 0; i < SIZE; ++i) {
if (current_candidate == arr[i]) {
++counter;
printf("candidate: %i, counter: %i\n",current_candidate,counter);
} else if (counter == 0) {
current_candidate = arr[i];
++counter;
printf("candidate: %i, counter: %i\n",current_candidate,counter);
} else {
--counter;
printf("candidate: %i, counter: %i\n",current_candidate,counter);
}
}
return current_candidate;
}
int main() {
int numbers[SIZE] = {5,5,5,3,3,1,1,3,3,3,1,3,3};
printf("majority: %i\n", boyerMoore(numbers));
return 0;
}
And here's a fun explanation (more fun than reading the paper, at least): http://userweb.cs.utexas.edu/~moore/best-ideas/mjrty/index.html
The Boyer-Moore Majority Vote Algorithm
//list needs to have an element with a count of more than n/2 throughout itself for
//this algorithm to work properly at all times.
lst = [1,2,1,2,3,1,3,3,1,2,1,1,1]
currentCount = 0
currentValue = lst[0]
for val in lst:
if val == currentValue:
currentCount += 1
else:
currentCount -= 1
if currentCount == 0:
currentValue = val
currentCount = 1
print(currentValue)
This code is a similar implementation to the way in which we find the majority of an element
int find(int* arr, int size)
{
int count = 0, i, m;
for (i = 0; i < size; i++)
{
if (count == 0)
m = arr[i];
if (arr[i] == m)
count++;
else
count--;
}
return m;
}
It doesn't seem possible to count anything without using extra space. You have to store atleast one counter somewhere. If you mean to say you cannot use more than O(n) space then it should be fairly easy.
One way would be to create a second list of only unique objects from the original list. Then, create a third list the same length as the second with a counter for the number of occurrences of each item in the list.
Another way would be to sort the list then find the largest contiguous section.
Using the modification suggested by ffao to Davi'd reply:
public class MaxRepeated {
public static void main(final String[] args) {
maxRepeatedElement(new int[]{1, 2, 1, 2, 3, 2, 3, 1});
maxRepeatedElement(new int[]{1, 2, 1, 2, 3, 1, 3, 1});
maxRepeatedElement(new int[]{1, 2, 1, 2, 4, 1, 1, 3, 1, 3, 1});
maxRepeatedElement(new int[]{1, 2, 1, 2, 2, 1, 2, 3, 1, 2, 1, 2});
}
private static int maxRepeatedElement(final int[] arr) {
int current_candidate = arr[0];
int previous_candidate = arr[0];
int counter = 0, i;
for (i = 0; i < arr.length; ++i) {
if (current_candidate == arr[i]) {
++counter;
} else if (counter == 0) {
previous_candidate = current_candidate;
current_candidate = arr[i];
++counter;
} else {
--counter;
}
System.out.printf(" candidate: %d, counter: %d\n", current_candidate, counter);
}
if (counter == 0) {
System.out.printf(" possible: %d or %d with net freq %d \n", current_candidate, previous_candidate, counter);
final int f1 = frequency(arr, current_candidate);
final int f2 = frequency(arr, previous_candidate);
final int halfLen = arr.length / 2 + (arr.length % 2 == 0 ? 0 : 1);
if (f1 >= halfLen || f2 >= halfLen) {
if (f1 > f2) {
System.out.printf("majority: %d with freq %d \n", current_candidate, f1);
} else {
System.out.printf("majority: %d with freq %d \n", previous_candidate, f2);
}
} else {
System.out.printf("NO majority! \n");
}
} else {
System.out.printf("majority: %d with freq %d \n", current_candidate, frequency(arr, current_candidate));
}
return current_candidate;
}
private static int frequency(final int[] arr, final int candidate) {
int counter = 0;
for (int c : arr) {
counter += candidate == c ? 1 : 0;
}
return counter;
}
}
Try this :
#include<iostream>
using namespace std;
int main()
{
int counter=0;
int a[]={10, 11, 5, 27, 4, 2, 7, 5, 7, 11, 9, 5, 5, 4, 10, 7, 5, 3, 7, 5};
for(int i = 0; i < 20; i++)
{
if(a[i]==5)
counter++;
}
cout << "it appears " << counter << " times";
}
The Boyer-Moore Majority Vote Algorithm fails to find correct majority in the below input arrays
int numbers[SIZE] = {1,2,3,4,1,2,3,4,1,2,3,4};
int numbers[SIZE] = {1,2,3,4,1,2,3,4,1,2,3,4,1};

Resources