How to compare array indexes with an integer in C? - arrays

A grocery store has N different types of chips. Chris wants to buy the chips as many as possible. He has M dollar in his pocket right now and he ask you to help him to count the number of chips he can buy as many as possible.
Format Input:
Input start with T, the number of test cases. For each test cases, there will be 2 integers N and M. In the second line there will be N integers, describing the price of one i-th chips. There will be unlimited supply of each type of chips.
Format Output:
Output starts with “Case #X: ”, where X is the test case number starting at 1, then followed by an integers, the maximum number of chips that Chris can buy
Constraints:
• 1 ≤ T ≤ 100
• 1 ≤ N ≤ 10000
• 1 ≤ M ≤ 10^9
• It is guaranteed the price will be between 1 and 10^6
Sample Input (user input) and Output (output in italic):
6
4 5
1 2 3 4
Case #1: 5
3 3
5 5 5
Case #2: 0
3 2
1 1 1
Case #3: 2
10 5
1 1 1 1 1 2 2 2 2 2
Case #4: 5
6 2
1 2 3 6 5 4
Case #5: 2
1 5
1
Case #6: 5
`
#include <stdio.h>
int main()
{
int t;
scanf("%d", &t);
for(int i = 1; i <= t; i++)
{
long long int n, m;
scanf("%lld %lld", &n, &m);
int chips[n];
for(int j = 0; j < n; j++)
{
scanf("%d", &chips[j]);
}
if(m > chips[n - 1])
{
printf("Case #%d: %lld\n", i, m);
}
else if(m < chips[n - 1])
{
printf("Case #%d: 0\n", i);
}
}
return 0;
}
`
I made a mistake in the if else part. I compare the m with the whole array, but I think I have to compare the m with the indexes of the array one by one. I don't know how to write the syntax to compare the indexes one by one. Does anyone know how to write the if else statement correctly for this problem?

If the problem is asking for the maximum number of packets chris can buy, then chris should only think about how many quantity of lowest-priced packet he can buy.
for example, in testcase 1, the lowest price of a packet is 1, so in this case, having m = 5, he can by 5 packets of worth 1.
So, first, you should find the lowest price of a packet (min value among the given array of costs)
then print:
printf("case #%d: %d\n", m/min);

Related

Rectangle from numbers, internal numbers are high and external numbers are low, there is a problem with some numbers

I have an exercise I need to submit. The user should enter 2 numbers, one of height and one of width, and the output should be a rectangle that the outer numbers are low and the inner ones are high.
So I wrote it but it does not work in some numbers, for example 9 and 3, but in most things it works.
I made 2 variables that are equal to the numbers entered by the user, this data goes down, the other 2 variables are just indicators, of the loops, they have no meaning
If anyone has a different direction how to do it, I would love to hear, just in loops ..
For example:
1 1 1 1 1 1 1 1 1
1 2 2 2 2 2 2 2 1
1 2 3 3 3 3 3 2 1
1 2 3 3 3 3 3 2 1
1 2 2 2 2 2 2 2 1
1 1 1 1 1 1 1 1 1
Thanks
#include <stdio.h>
int main() {
int row, col, u, d;
scanf("%d", &row);
scanf("%d", &col);
int row_1, col_1;
for (u = 1, row_1 = row; u <= row; u++, row_1--) {
for (d = 1, col_1 = col; d <= col; d++, col_1--) {
if (col_1 < u && row_1 > col_1)
printf("%d", col_1);
else if (u > d && row_1 >= d)
printf("%d", d);
else if(row_1 > u)
printf("%d", u);
else
printf("%d", row_1);
}
printf("\n");
}
return 0;
}
I would start by learning to describe the problem. For example:
the user enters the number of rows and columns to print (presumably 1–9 each)
for each position, print the distance to the nearest edge of the rectangle, starting from 1
The above description would quite easily lead to a solution like:
for (int row = 1; row <= num_rows; ++row) {
int y_distance = distance_to_edge(row, num_rows);
for (int col = 1; col <= num_cols; ++col) {
int x_distance = distance_to_edge(col, num_cols);
printf("%d", x_distance < y_distance ? x_distance : y_distance);
}
putchar('\n');
}
(Implementation of distance_to_edge left as exercise.)
Of course this is not the only solution; you can also take advantage of the fact that you know how the position changes (as you have attempted in your solution), but such optimisation may make it harder to get right. One easy option there is to break each loop down to two halves (the distance increases in the first half and decreases in the second)…

C: How to take an input as unknown sized matrix

Question:
Given a matrix A, compute the sum of maximal elements row-wise (find a maximum element of each row and take their sum) and column-wise independently and return those values.
In which input is going to be :
First-line contains n, m number of rows and columns of input matrix.
Next n lines contains m integers.
Some examples:
Input1:
3 3
4 3 2
3 7 7
2 6 0
Output1:
17 18
Input2:
3 4
1 2 3 4
5 6 7 8
9 10 11 12
Output2:
24 42
I can't tell how I am supposed to take the matrix input using scanf. Please help.
just use scanf("%d", &variable) no matter if delimiter is a new line or a space:
#include <stdio.h>
int main()
{
int lines, cols;
scanf("%d", &lines);
scanf("%d", &cols);
for(int y = 0; y < lines; y++){
for(int x = 0; x < lines; x++){
int variable;
scanf("%d", &variable);
// your code
}
}
// your code
return 0;
}

How to find all subsets in Subset Sum (with Dynamic Programming) in C

I'm new into C (1.5 months studying) and our college professor has asked us to find the Dynamic Programming solution of the Subset Sum problem (along with 2 other ones), but I've followed his instructions and I'm stuck on how to actually find (print) the requested subsets. Can somebody help me understand how this works and how to find all of the subsets?
For the code below, the table is {3,2,1,2,4,3,4,1}, and the subsets need to sum up to 7.
EDIT! --> I modified the initial code so as to find how many subsets exist that sum up to particular value (in our case 7, and the subsets are 20). I repeat that I need help finding all the subsets (combinations) that sum up to a value (7 in this case).
In the above case, this means that the code would be able to print 20 subsets, which are:
Subset 1: 3 2 1 1
Subset 2: 3 2 2
Subset 3: 3 1 2 1
Subset 4: 3 1 3
Subset 5: 3 4
Subset 6: 3 3 1
Subset 7: 3 4
Subset 8: 2 1 4
Subset 9: 2 1 3 1
Subset 10: 2 1 4
Subset 11: 2 2 3
Subset 12: 2 4 1
Subset 13: 2 4 1
Subset 14: 1 2 4
Subset 15: 1 2 3 1
Subset 16: 1 2 4
Subset 17: 2 4 1
Subset 18: 2 4 1
Subset 19: 4 3
Subset 20: 3 4
In the C code that follows I'm able to print the table the instructions want me to, and through this table I must find all the subsets. The instructions for the table were:
x[i][j]=x[i-1][j];
if(j>=y[i-1]) x[i][j]+=x[i-1][j-y[i-1]];
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
long set[] = {3,2,1,2,4,3,4,1};
long sum =7;
long n = sizeof(set)/sizeof(set[0]);
iter_subset_sum(set, n, sum);
return 0;
}
int iter_subset_sum (int *y, long n, long sum) {
int i,j,k,**x;
x=malloc((n+1)*sizeof(long**));
for(i=0;i<=n;i++)
x[i]=malloc((sum+1)*sizeof(long*));
for (i=0; i<=n; i++)
x[i][0] = 1;
for (i=1; i<=sum; i++)
x[0][i] =0;
for (i=1; i<=n; i++) {
for (j=1; j<=sum; j++){
x[i][j]=x[i-1][j];
if(j>=y[i-1])
x[i][j]+=x[i-1][j-y[i-1]]; } }
for (i = 0; i <= n; i++){
for (j = 0; j <= sum; j++)
printf ("%4d", x[i][j]);
printf("\n");
}
printf("There are %d subsets :", x[n][sum]);
}
Thank you very much in advance!! I would appreciate it very much if you could help a newbie like me that wants slowly to "go deep" into C...
#include <stdio.h>
int iscan(int a[],int n,int sum){
int f[sum+1],m=0,i,j,k,el,o=0;
for(i=1;i<=sum;i++)f[i]=0;f[0]=1;
for(i=0;i<n;i++){
el=a[i];
if(el>sum)continue;
m=m+el>sum?sum:m+el;
for(k=m-el,j=m;k>=0;j--,k--){
if(f[k]){
/* f[j]=el;*/ //old only last conest
push_toarray_of_stack(on j position ,item size of el);;//this pseudocode is hint for u homework*********** so and change printing all combination after builing array_of_stack's of conection
}
}
if(!f[sum])continue;
k=sum;
while(k){
printf("%d ",f[k]);
k-=f[k];
}
printf("%s\n","");
//exit(0);
o++;
}
//printf("%s\n","can't");
return o;
}
int main(){
int set[] = {1, 3, 2, 4, 2, 6, 5};
int sum = 5;
return iscan(set,sizeof(set)/sizeof(set[0]),sum);
}

Segmentation fault due to recursion

I'm writing a program that is to take a number between 1-10 and display all possible ways of arranging the numbers.
Ex
input: 3
output:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
Whenever I input 9 or 10, the program gives a segmentation fault and dumps the core. I believe the issue is my recursive algorithm is being called too many times. Could someone help point out how I could limit the amount of recursive calls necessary? Here is my current code:
void rearange(int numbers[11], int index, int num, int fact) {
int temp = numbers[index];
numbers[index] = numbers[index-1];
numbers[index-1] = temp;
int i;
for (i = 1; i <= num; ++i) // print the current sequence
{
printf("%d ", numbers[i]);
}
printf("\n");
fact--; // decrement how many sequences remain
index--; // decrement our index in the array
if (index == 1) // if we're at the beginning of the array
index = num; // reset index to end of the array
if (fact > 0) // If we have more sequences remaining
rearange(numbers, index, num, fact); // Do it all again! :D
}
int main() {
int num, i; // our number and a counter
printf("Enter a number less than 10: ");
scanf("%d", &num); // get the number from the user
int numbers[11]; // create an array of appropriate size
// fill array
for (i = 1; i <= num; i++) { // fill the array from 1 to num
numbers[i] = i;
}
int fact = 1; // calculate the factorial to determine
for (i = 1; i <= num; ++i) // how many possible sequences
{
fact = fact * i;
}
rearange(numbers, num, num, fact); // begin rearranging by recursion
return 0;
}
9! (362880) and 10! (3628800) are huge numbers that overflow the call stack when you do as many recursive calls. Because all the local variables and formal parameters have to be stored. You either you have to increase the stack size or convert the recursion into iteration.
On linux, you can do:
ulimit -s unlimited
to set the stack size to unlimited. The default is usually 8MB.
Calculating permutations can be done iteratively, but even if you do it recursively there is no need to have a gigantic stack (like answers suggesting to increase your system stack say). In fact you only need a tiny amount of your stack. Consider this:
0 1 <- this needs **2** stackframes
1 0 and an for-loop of size 2 in each stackframe
0 1 2 <- this needs **3** stackframes
0 2 1 and an for-loop of size 3 in each stackframe
1 0 2
1 2 0
2 1 0
2 0 1
Permuting 9 elements takes 9 stackframes and a for-loop through 9 elements in each stackframe.
EDIT: I have taken the liberty to add a recursion-counter to your rearrange-function, it now prints like this:
Enter a number less than 10: 4
depth 1 1 2 4 3
depth 2 1 4 2 3
depth 3 4 1 2 3
depth 4 4 1 3 2
depth 5 4 3 1 2
depth 6 3 4 1 2
depth 7 3 4 2 1
depth 8 3 2 4 1
depth 9 2 3 4 1
depth 10 2 3 1 4
depth 11 2 1 3 4
depth 12 1 2 3 4
depth 13 1 2 4 3
depth 14 1 4 2 3
depth 15 4 1 2 3
depth 16 4 1 3 2 which is obviously wrong even if you do it recursively.
depth 17 4 3 1 2
depth 18 3 4 1 2
depth 19 3 4 2 1
depth 20 3 2 4 1
depth 21 2 3 4 1
depth 22 2 3 1 4
depth 23 2 1 3 4
depth 24 1 2 3 4
....
The recursion-leafs should be the only ones which output so the depth should be constant and small (equal to the number you enter).
EDIT 2:
Ok, wrote the code. Try it out:
#include "stdio.h"
void betterRecursion(int depth, int elems, int* temp) {
if(depth==elems) {
int j=0;for(;j<elems;++j){
printf("%i ", temp[j]);
}
printf(" (at recursion depth %u)\n", depth);
} else {
int i=0;for(;i<elems;++i){
temp[depth] = i;
betterRecursion(depth+1, elems, temp);
}
}
}
int main() {
int temp[100];
betterRecursion(0, 11, temp); // arrange the 11 elements 0...10
return 0;
}
I'd make your rearange function iterative - do while added, and recursive call removed:
void rearange(int numbers[11], int index, int num, int fact) {
int temp;
do
{
temp = numbers[index];
numbers[index] = numbers[index-1];
numbers[index-1] = temp;
int i;
for (i = 1; i <= num; ++i) // print the current sequence
{
printf("%d ", numbers[i]);
}
printf("\n");
fact--; // decrement how many sequences remain
index--; // decrement our index in the array
if (index == 1) // if we're at the beginning of the array
index = num; // reset index to end of the array
} while (fact > 0);
}
This is not a task for a deep recursion.
Try to invent some more stack-friendly algorithm.
Following code has rather troubles with speed than with stack size...
It's a bit slow e.g. for n=1000 but it works.
#include <stdio.h>
void print_arrangement(int n, int* x)
{
int i;
for(i = 0; i < n; i++)
{
printf("%s%d", i ? " " : "", x[i]);
}
printf("\n");
}
void generate_arrangements(int n, int k, int* x)
{
int i;
int j;
int found;
if (n == k)
{
print_arrangement(n, x);
}
else
{
for(i = 1; i <= n; i++)
{
found = 0;
for(j = 0; j < k; j++)
{
if (x[j] == i)
{
found = 1;
}
}
if (!found)
{
x[k] = i;
generate_arrangements(n, k + 1, x);
}
}
}
}
int main(int argc, char **argv)
{
int x[50];
generate_arrangements(50, 0, x);
}
Your program is using too many recursions unnecessarily. It is using n! recursions when actually n would be enough.
To use only n recursions, consider this logic for the recursive function:
It receives an array nums[] of n unique numbers to arrange
The arrangements can have n different first number in them, as there are n different numbers in the array
(key step) Loop over the elements of nums[], and in each iteration create a new array but with the current element removed, and recurse into the same function passing this shorter array as parameter
As you recurse deeper, the parameter array will be smaller and smaller
When there is only one element left, that's the end of the recursion
Using this algorithm, your recursion will not be deeper than n and you will not get segmentation fault. The key is in the key step, where you build a new array of numbers that is always 1 item shorter than the input array.
As a side note, make sure to check the output of your program before you submit, for example run it through | sort | uniq | wc -l to make sure you are getting the correct number of combinations, and check that there are no duplicates with | sort | uniq -d (the output should be empty if no dups).
Spoiler alert: here's my implementation in C++ using a variation of the above algorithm:
https://gist.github.com/janosgyerik/5063197

project euler exercise 5 approach

Question: 2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.
What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20?
So, I was trying to do exercise 5 on project euler and I came out with this code:
#include <stdio.h>
#define TRUE 1
#define FALSE 0
int main () {
int n, fnd = FALSE, count, i;
for (i = 1; fnd == FALSE; i++) {
count = 0;
for (n = 1; n <= 20; n++) {
count += i % n;
}
printf ("testing %d, count was: %d\n", i, count);
if (count == 0) {
fnd = TRUE;
printf ("%d\n", i);
}
}
return 0;
}
I believe my apporach is correct, it will surely find the number which is divisible by 1 to 20. But it's been computing for 5 minutes, and still no result. Is my approach correct? If yes, then is there another way to do it? I can't think on another way to solve this, tips would be very much appreciated. Thank you in advance.
EDIT:
So, based on the advice I was given by you guys I figured it out, thank you so much!
So, it's still brute force, but instead of adding 1 to the last number, it now adds 2520, which is the LCM of 1 to 10. And therefore, calculating if the sum of the remainders of the multiples of 2520 divided from 11 to 20 was 0. Since 2520 is already divisible by 1 to 10, I only needed to divide by 11 to 20.
#include <stdio.h>
#define TRUE 1
#define FALSE 0
int main () {
int n, fnd = FALSE, count, i;
for (i = 2520; fnd == FALSE; i = i + 2520) {
count = 0;
for (n = 11; n <= 20; n++) {
count += i % n;
}
printf ("testing %d, count was: %d\n", i, count);
if (count == 0 && i != 0) {
fnd = TRUE;
printf ("%d\n", i);
}
}
return 0;
}
Thank you so much, I wouldn't solve it without your help : )
PS: It now computes in less than 10 secs.
Your approach is taking too long because it is a brute-force solution. You need to be slightly clever.
My hint for you is this: What does it mean for a number to be evenly divisible by another number? Or every number below a certain number? Are there commonalities in the prime factors of the numbers? The Wikipedia page on divisibility should be a good starting point.
Hint: You should look up "least common multiple".
Next hint:
The answer is the least common multiple (LCM) of the numbers 1, 2, 3, ..., 20.
LCM of n numbers can be found sequentially: if LCM(1, 2) = x, than LCM(1, 2, 3) = LCM(x, 3); if LCM(1, 2, 3) = y, than LCM(1, 2, 3, 4) = LCM(y, 4) etc. So it's enough to know how to find LCM of any 2 numbers.
For finding LCM of 2 numbers we can use the following formula: LCM(p, q) = pq/GCD(p, q), where GCD is the greatest common divisor
For finding GCD, there is a well-known Euclid's algorithm (perhaps the first non-trivial algorithm on the Earth).
I think you should start by computing the prime factors of each number from 2 to 20.
Since the desired number should be divisible by each number from 1 to 20, it must also
be divisible by each prime factor of those numbers.
Furthermore, it is important keep track of the multiplicities of the prime factors.
For example, 4 = 2 * 2, hence the desired number must be divisible by 2 * 2.
Something I quickly baked with Python 3:
primary_list = []
for i in range(2, 4097):
j = i
k = 2
delta_list = primary_list[0:]
alpha_list = []
while j > 1:
if j % k == 0:
j /= k
alpha_list.append(k)
k = 2
else:
k += 1
for i in alpha_list:
try:
delta_list.remove(i)
except:
primary_list.append(i)
final_number = 1
for i in primary_list:
final_number *= i
print(final_number)
This computes in mere seconds under a slow machine. Python is very good with abstract numbers. The best tool for the job.
The algorithm is relatively simple. We have a basic list primary_list where we store the multiples of the numbers. Then comes the loop where we estimate the range of numbers that we want to compute. We use a temporary variable j as a number that can be easily divided, chopped and conquered. We use k as the divisor, starting as 2. The delta_list is the main working copy of the primary_list where we take apart number after number until only the required "logic" is left. Then we add those numbers to our primary list.
1: 1
2: 2 1
3: 3 1
4: 2 2 1
5: 5 1
6: 2 3 1
7: 7 1
8: 2 2 2 1
9: 3 3 1
10: 2 5 1
The final number is found by multiplying the numbers that we have in the primary_list.
1 * 2 * 3 * 2 * 5 * 7 * 2 * 3 = 2520
As said, Python is _really_ good with numbers. It's the best tool for the job. That's why you should use it instead of C, Erlang, Go, D or any other dynamic / static language for Euler exercises.
I solved it using C. Below is the algorithm!
#include <stdio.h>
#include <stdio.h>
int main()
{
int i;
int count;
for(i=21;i>0;i++)
{ count = 0;
for( int j=2;j<21;j++)
{
if (i%j!=0)
break;
count++;
}
if (count==19)
break;
}
printf("%d\n",i);
return 0;
}
Just some thoughts about above comments,
#pg190 you say " it really only needs to be divisible by the primes between 1 and 20, i.e. 2, 3, 5, 7, 11, 13, 17, 19."
take 9699690, does not devide by all value from 1-20.
So this might be a good solution,
Given the number set [1-20]
The Least Common Multiple can be computed as follows.
Ex. For numbers 2,6,9
Express them in prime multiplications
2 2
6 2 3
9 3 3
LCM = multiple of highest power of each prime number.
= 2*3^2 = 18
This can be done to the problem in hand by expressing each number as prime multiplication
and then do this math.
$num=20;
for($j=19;$j>1;$j--)
{
$num= lcm($j,$num);
}
echo $num;
function lcm($num1, $num2)
{
$lcm = ($num1*$num2)/(gcd($num1,$num2));
return $lcm;
}
function gcd($n1,$n2)
{
$gcd=1;
$min=$n1;
if($n1>$n2)
{
$min=$n2;
}
for($i=$min;$i>1;$i--)
{
if($n1%$i==0 && $n2%$i==0)
{
$gcd*=$i;
$n1/=$i;
$n2/=$i;
}
}
return $gcd;
}
solved in php

Resources