Generate random numbers with Array - arrays

I am learning C and I keep mixing up array and matrix. and I can't seem to understand where I am doing wrong with my code. I have made 2 different version of it and the only feedback I am getting is, I have mixed array with matrix.
I was wondering if anyone could help me understand exactly where I went wrong, since I am not getting anywhere with my prof and his explanation about it. (Sorry in advanced)
This is the first code, But both of them are really similar.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
int array[100];
int max = 0, min = 1;
int fro;
fro = (int)time(NULL);
srand(fro);
for (int i = 0; i < 100; i++) {
array[i] = rand() % (400 + 1 - 100) + 100;
if (array[i] <= min) {
min = array[i];
}
if (array[i] >= max)
max = array[i];
}
printf("Array\n");
for (int row = 0; row < 10; row++) {
for (int col = 0; col < 10; col++) {
printf(" %i ", array[row * 10 + col]);
}
printf("\n");
}
return 0;
}
This is another version, but I got similar feedback as the first one.
I am mixing up array and matrix..
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
int tal[10][10];
int array[100];
int max = 0, min = 1;
int fro;
fro = (int)time(NULL);
srand(fro);
// Version 3 of the array slump generation
for (int row = 0; row < 10; row++) {
//printf("Yttre loop row %i\n", row);
for (int col = 0; col < 10; col++) { // row = 1, col = 0
tal[row][col] = rand() % (400 + 1 - 100) + 100;
// printf("tal[%i][%i] = %i\n", row, col, tal[row][col]);
// Get max
if (tal[row][col] >= max) {
max = tal[row][col];
}
// Get min
if (tal[row][col] <= min) {
min = tal[row][col];
}
// printf("tal[%i][%i] = %i\n", row, col, tal[row][col]);
}
}
// Printar ut hela matrisen i row-major order
for (int row = 0; row < 10; row++) {
for (int col = 0; col < 10; col++) {
printf(" %i ", tal[row][col]);
}
printf("\n");
}
return 0;
}
I mean both of them works and I think I am using array :/
We haven't even gone trough matrix yet...

The notion of a matrix is not an ISO C concept. However, you can use an array to denote a matrix by imposing imposing additional linear algebra constraints. There are several linear algebra libraries for C. However, be prepared for some people use the term matrix loosely to mean any two-dimensional array, because they look similar in most presentations.
Your first example is an int array[100] which stores array 100 of int. You then access it by 10 row and 10 col; since 10 * 10 = 100 <= 100 that you've reserved for it, this is entirely valid. One might prefer this representation because it is explicitly contiguous, but has no way for the compiler to bounds-check.
Your second example is int tal[10][10], which is array 10 of array 10 of int, all in the same block of memory. It's the same 100-element array, but accessed differently, as you've done. This is also valid, and I think more what your teacher was asking.
The one you treat more like a matrix will be more like a matrix.

Related

How to sort a 2d array based on these conditions ? (The conditions are given within the code)

/*
The program must accept N integers as the input. Each integer is
given a weight. The program must sort the integers in ascending
order based on their weight and print the integers along with their
weights as the output as given in the Example Input/Output
sections. The weight of each integer is calculated based on the
conditions given below.
Conditions:
Weight = 5 if it is a perfect cube.
Weight = 4 if it is a multiple of 4 and divisible by 6.
Weight = 3 if it is a prime number.
Hint: Use stable sort (insertion sort, bubble sort or merge sort).
Boundary Conditions:
1 <= N <= 1000
Input Format:
The first line contains N.
The second line contains N integers separated by a space.
Output Format:
The first line contains integers with their weight as given in the Example Input/Output sections.
Example Input/Output 1:
Input:
7
10 36 54 89 12 216 27
Output:
<10,0>,<54,0>,<89,3>,<36,4>,<12,4>,<27,5>,<216,9>
Example Input/Output 2:
Input:
10
12 18 16 64 14 30 37 27 343 216
Output:
<18,0>,<16,0>,<14,0>,<30,0>,<37,3>,<12,4>,<64,5>,<27,5>,<343,5>,<216,9>
*/
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
int perfcube(int n)
{
int cubert = cbrt(n);
if (cubert * cubert * cubert == n)
{
return 1;
}
else
return 0;
}
int divis(int n)
{
if (n % 4 == 0 && n % 6 == 0)
{
return 1;
}
return 0;
}
int prime(int n)
{
int count = 0;
for (int i = 1; i <= n; i++)
{
if (n % i == 0)
{
count++;
}
}
if (count == 2)
{
return 1;
}
else
{
return 0;
}
}
int main()
{
int n;
scanf("%d", &n);
int a[n];
int b[n][2];
// scanning n variables into array a
for (int i = 0; i < n; i++)
{
scanf("%d", &a[i]);
}
// copying rows of a(1d array) to b(2d array)
int l = 0; // variable to traverse 1d array without its own loop
// traverse 2d array
for (int j = 0; j < n; j++)
{
for (int k = 0; k < 2; k++)
{
if (k == 0)
{
// if k = 0 that is first col then store 1st col value of 1d array to 2d array
b[j][k] = a[l++];
}
else
{
// if other cols come then skip it
continue;
}
}
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < 2; j++)
{
if (j == 0)
{
if (perfcube(b[i][j]))
{
b[i][j + 1] += 5;
}
if (divis(b[i][j]))
{
b[i][j + 1] += 4;
}
if (prime(b[i][j]))
{
b[i][j + 1] += 3;
}
}
}
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < 2; j++)
{
printf("<%d,>", b[i][j]);
}
printf("\n");
}
return (0);
}
I tried approaching the problem like this and ended up with an output like this. Please help me proceed from here.
Output
<10,><0,>
<36,><4,>
<54,><0,>
<89,><3,>
<12,><4,>
<216,><9,>
<27,><5,>
I am new to programming
I have tried approaching the problem like this and ended up with an output like that.
Please help me proceed from here.
I am not allowed to use pointers or functions like qsort
How do I sort these in that format and print it
Output of the program that I ended up with.
The output should match the question.
Sorting, at its core, centers around the comparison of two items. For example, if A < B, then A should come before B.
For example, we can reorder
3 5 2 1 4
to
1 2 3 4 5
We can see it is correct because each adjacent pair maintains a ≤ relationship.
This relationship is a comparison function. The one used for your standard sorting looks something like this:
bool compare( int a, int b )
{
return a <= b;
}
 
What your homework is asking you to do is change the comparison function to not compare the values directly, but compare the results of a function applied to them:
bool compare( int a, int b )
{
return weight_function( a ) <= weight_function( b );
}
You must write and implement the weight function, then use it in your sorting algorithm.
(Your algorithm probably has an if (a <= b) in it somewhere, which you could rewrite as if (compare( a, b ))... but you don’t need to do that, just use the weight functions properly.

Calculating primes using wiki algorithm

I have just started using C and I am currently working on calculating primes using the wikipedia algorithm here:
algorithm Sieve of Eratosthenes is
input: an integer n > 1.
output: all prime numbers from 2 through n.
let A be an array of Boolean values, indexed by integers 2 to n,
initially all set to true.
for i = 2, 3, 4, ..., not exceeding √n do
if A[i] is true
for j = i2, i2+i, i2+2i, i2+3i, ..., not exceeding n do
A[j] := false
return all i such that A[i] is true.
When I try implementing what I think turns out like the code above, I get what I believe is an 'infinite loop', where might I have gone wrong?
#include <stdio.h>
#include <stdlib.h>
int main(void) {
//create empty array to store values
int isPrime[] = {};
//set a large number
int n = 1000;
//create for loop
for(int i = 2; i < n; i++){
///create another for loop taking the exponents
for(int j = i; j < pow(i, 2); j++){
//if i is equal to j is true then return those values true
if(isPrime[i] == isPrime[j]){
printf("%d", isPrime[i]);
}
}
}
There's many errors in your code including an empty array, use of pow (which is a floating-point function) and numerous logic errors that deviate from the wikipedia example code.
Here's a corrected, working version that follows the logic of the wikipedia version, with a loop afterwards to print out all the primes less than n:
#include <stdio.h>
int main(void) {
int n = 1000;
int isPrime[n];
for (int i = 0; i < n; i++) {
isPrime[i] = 1;
}
for (int i = 2; i * i < n; i++) {
if (isPrime[i]) {
for (int j = i * i; j < n; j += i) {
isPrime[j] = 0;
}
}
}
for (int i = 2; i < n; i++) {
if (isPrime[i]) {
printf("%d ", i);
}
}
printf("\n");
}
(Note that a small deviation from the wikipedia algorithm is that this prints primes less than n rather than primes less than or equal to n).

Replacing all duplicate numbers in an Array, so that every element is unique in C

The elements in the array are created using rand().
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int main(void){
int array[6] = { 0 };
srand(time(NULL));
for(int i = 0; i < 6; i++){
array[i] = rand() % 49 + 1;
}
/*
Code to check for duplicates
if duplicate found
duplicate = rand(49);
*/
for(int i = 0; i<6; i++){
printf("[%d]",array[i]);
}
return 0;
}
I don´t really want to sort the array if it makes it easier to find duplicates because the array is for a lottery ticket.
I have tried different methods, but all of them are inefficient and includes a lot of loops.
I had different approaches, but all of them didn´t really work, because what if, the newly created number, is yet again a duplicate? Or if the last number in the array is a duplicate.
So I came with the following approach: The algorithm will create as many areas, as long no number in the array is a duplicate
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#define TRUE 1
int main(void) {
int a[6] = {0};
srand(time(NULL));
while (TRUE) {
int c = 0;
for (int i = 0; i < 6; i++) {
a[i] = rand() % 49 + 1;
}
for (int i = 0; i < 6; i++) {
for (int j = i + 1; j < 6; j++) {
if (a[i] == a[j]) {
c++;
}
}
}
if (c == 0) {
break;
}
}
for (int i = 0; i < 6; i++) {
printf("%d\n", a[i]);
}
return 0;
}
Any Ideas, how to make an easy, efficient, but not so complex algorithm for a beginner?
Thanks :)
There's two sort of problems here. Firstly, if you find a duplicate number, you wish it to be replaced by another number. However, it is also possible that the new number could be a duplicate to some other value. I'd suggest adding the following code to your program to check for duplicacy
for(int i = 0; i<6; i++)
{
for(int k=0; k<6; k++)
{
if(i==k)
{
continue;
}
if(array[i] == array[k])
{
array[i]=rand()%49+1;
}
}
}
There is an outer loop to rotate between the 6 elements of the array, and an inner loop to test that element against all other elements of that array. However, you should note that it is entirely possible that the elements 1-5 may end up being duplicated to some other value again.
Edit: The continue; statement iterates the loop for the next value. Its there to make sure no element is tested against itself.

Can't seem to sum multiple array lines to multiple int variables in c language

I'm a first grade student atm. and I'm struggling to finish my "homework" with c language.
Right now I'm trying to apply 4 array lines sum to 4 int variables and here's what I've achieved so far:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int dvimatisMas[4][4] = { {1,2,3,4}, {5,6,7,8}, {9,10,11,12}, {13, 14, 15, 16} };
int eiluciuSum[4];
for(int i = 0; i < 4; i++){
for(int x = 0; x < 4; x++){
for(int j = 0; j < 4; j++){
eiluciuSum[i] += dvimatisMas[x][j];
}
}
}
printf("suma 1 eil: %d\n", eiluciuSum[1]);
printf("suma 2 eil: %d\n", eiluciuSum[2]);
printf("suma 3 eil: %d\n", eiluciuSum[3]);
printf("suma 4 eil: %d\n", eiluciuSum[4]);
int min = 0;
int max = 0;
}
it simply gives out a bunch of answers even though there should be just 4. As you can see in the code I've tried to correct this by writing 4 separate prints and specifying each bracket for them so yeah I obviously get 4 answers like I should but they aren't correct and still I shouldn't be specifying all of that anyway.
If I write something more "simple" I get the desired result:
int dvimatisMas[4][4] = { {1,2,3,4}, {5,6,7,8}, {9,10,11,12}, {13, 14, 15, 16} };
int eilute1 = 0;
int eilute2 = 0;
int eilute3 = 0;
int eilute4 = 0;
for(int i = 0; i < 4; i++){
eilute1 += dvimatisMas[0][i];
eilute2 += dvimatisMas[1][i];
eilute3 += dvimatisMas[2][i];
eilute4 += dvimatisMas[3][i];
}
printf("suma 1 eil: %d\n", eilute1);
printf("suma 2 eil: %d\n", eilute2);
printf("suma 3 eil: %d\n", eilute3);
printf("suma 4 eil: %d\n", eilute4);
But the problem is that I also have to print out the smallest number out of 'eilute' as well as the biggest. But I can't get to that point since I need 'eilute[]' (I called it 'eiluciuSum[]' in the first code) to be expanded by the code and to use it in an 'if' statement like "if(eilute[i] < 0){ min += eilute[i]; printf("smallest: %d", min)" etc. and thats how I'm supposed to do it (well at the very least something like that instead of bunch of complicated equations and I mean it is more short and 'professional' am I right?).
If I managed to explain my situation understandably could someone help and explain on what I'm doing wrong in the first provided code?
Thank you in advance.
The final version of your code is at the bottom.
Firstly, you don't need the variable x. Cut out the second for loop.
for(int i = 0; i < 4; i++) {
for(int j = 0; j < 4; j++) {
eiluciuSum[i] += dvimatisMas[i][j];
}
}
Secondly, the problem is that the eiluciuSum array is not initialized to zero. It already contains a garbage value in it from whatever was stored in that memory address before. You should replace its definition with this:
int eiluciuSum[4] = { 0 };
Then just put the printf statement after the inner loop like this:
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
eiluciuSum[i] += dvimatisMas[i][j];
}
printf("%d\n", eiluciuSum[i]);
}
And it should work fine without the 4 printf statements below.
Thirdly, in regards to finding the maximum/minimum values, all you need to do is set the max/min variables to the first element in the array and then loop through the array, looking for values larger/smaller than whatever is the current largest/smallest, and switch those values.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int dvimatisMas[4][4] = { {1,2,3,4}, {5,6,7,8}, {9,10,11,12}, {13, 14, 15, 16} };
int eiluciuSum[4] = { 0 }; // initialize all elements of array to 0
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
eiluciuSum[i] += dvimatisMas[i][j];
}
printf("%d\n", eiluciuSum[i]);
}
int min = eiluciuSum[0]; // assume the first sum is the smallest
int max = eiluciuSum[0]; // assume the first sum is the largest
// loop through all elements of array and if you encounter one bigger/smaller
// than the current max/min, then make those the current max/min values
for (int i = 0; i < 4; i++) {
if (eiluciuSum[i] < min)
min = eiluciuSum[i];
if (eiluciuSum[i] > max)
max = eiluciuSum[i];
}
printf("The smallest sum is %d\n", min);
printf("The largest sum is %d\n", max);
}

Optimise a code of random number with no repetition in C

I do a code that will display to the screen 10 random numbers with no repetitions. I want to know if we can optimize the code or if you have a better and simple way in order to do this request.
Thanks !!
int main(){
int nbr = 0; srand(time(NULL));
int arr[10], i, j, flag;
for (i = 0; i < 10; i++)
{
do
{
nbr = rand() % 10 + 1;
flag = 1;
for (j = 0; j < i; j ++)
{
if (nbr == arr[j])
{
flag = 0;
break;
}
}
} while (!flag);
arr[i] = nbr;
}
for (i = 0; i < 10; i++)
{
printf("%5d", arr[i]);
}
system("PAUSE");
return 0;
}
So if i get what you're trying to do here it is:
generate an array of numbers between 1 and 10, in a random order (given rand() % 10 + 1)
instead of trial and error I'd suggest the following algorithm:
fill arr with 1...10
shuffle arr
this will run a lot faster
While I agree with the solution provided by Work of Artiz, this will result in the hard question to answer of when to stop shuffling.
To solve this you can use the following solution (which will use more memory, but less clock time):
1 Create an array temp having values 1..10 (ordered, not random)
2 Keep track of the length length of the array (10)
3 Generate a random index rand_i between 0 and length - 1
4 Copy temp[rand_i] to next position in your final array
5 Overwrite temp[rand_i] by temp[length-1]
6 Decrement length
7 Iterate Steps 3 - 6 until your array is filled (10 times)
This will both eliminate your excessive looping, and the problem of when to stop shuffling your array
EDIT: including code
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
int main(){
int nbr = 0; srand(time(NULL));
int arr[10], i, j, flag;
int temp[10] = {1,2,3,4,5,6,7,8,9,10};
int length = 10;
for (i = 0; i < 10; i++)
{
nbr = rand() % length; // Generate random index between 0 and length - 1
arr[i] = temp[nbr]; // Copy value from random index in temp to next index in arr
// Now since temp[nbr] is already taken (copied to arr) we should replace it by last available value in temp (temp[lenght])
// and in the next iteration we will create a value between 0 and length -1. This will keep values not yet taken from temp in
// contiguous order
temp[nbr] = temp[length-1];
length--;
}
for (i = 0; i < 10; i++)
{
printf("%5d", arr[i]);
}
return 0;
}

Resources