Selecting elements of n inputs in c without using arrays - c

Given a sequence of integers as input I need to be able to select specific integers of the sequence so that I can execute various arithmetic operations between them.
For example, given this input I want to know the sum of the third and the last integer of the sequence.
EDIT: in the example it would be the sum of 7 and 9
3
1
7
4
9
The condition I have to follow is that I don't use arrays so I can't give every integer an index.
Also I can't know in advance how many integers there will be in the sequence so I can't create an input that determine the number of integers.
To read the inputs I thought of using this loop with a scanf condition:
while (scanf("%d", &i) == 1);
The thing I'm stuck in is how to select the third and the last integers; if it was something like finding the sum of the odd integers I would just put a condition like this:
if (i%2 != 0)
{
sum = sum + i;
i++;
}
Most examples are solved using a for lopp but they either have the number of inputs declared or the inputs are just consecutive integers.
Any suggestion on how can I solve this problem?

You can mix a simple for loop with your scanf condition so you can associate an index to each number and memorize numbers needed to compute your operation (including the last).
Here is an example:
int i, value;
int sum = 0;
int lastValue = 0;
for(i=1 ; scanf("%d", &value) == 1 ; ++i)
{
if(i == 3) /* select the third element */
sum += value;
lastValue = value; /* memorize the last element so far to compute it later */
}
sum += lastValue; /* assume that there is at least one value in the sequence */

Related

Having trouble understanding the for loop

#include <stdio.h>
int n, a[100001], x, y;
int main() {
scanf("%d", &n);
while (n--) {
scanf("%d.%d", &x, &y);
a[x*1000+y]++;
}
for (int i = 0, c = 0; i <= 100000; i++) {
while (a[i]) {
--a[i], ++c;
printf("%d.%03d\n", i / 1000, i % 1000);
if (c == 7) return 0;
}
}
return 0;
}
This is the code that receives an integer n, then the program is expected to receive n number of double or integer variables.
The program is supposed to print out the smallest 7 variables among the input variables to 3 decimal points.
Now the question is i can't seem to figure out how this code in for loop
while (a[i]) {
--a[i], ++c; // <- specifically this part
printf("%d.%03d\n", i / 1000, i % 1000);
if (c == 7) return 0;
}
generates 7 smallest variables.
Any help would be much appreciated
Suppose 8.3 is an input, then you are storing the 8003rd index of the array to 1. i.e a[8003]=1. if 8.3 is input twice then a[8003] will be equal to 2.
So in the for loop when i=8003, a[8003] is non zero that that means there was an input 8.3. So it is considered in the top 7 smallest input values and the loop exits when count reaches 7.
As hellow mentioned, This is bad code and if you are a student, stay away from such programming style (Not just student, everyone should stay away).
What this code does is it creates sort of "Look-up" table.
Whenever a number is entered, it increases a count at that array instance.
e.g. If I input 3.2, it increments a[3002] th location. Code for this is:
scanf("%d.%d", &x, &y);
a[x*1000+y]++;
x = 3 and y = 2 so a[3*1000+2]++ --> a[3002] = 1
(Note: Code assumes that array a is initialized with 0 - another bad habit)
Now say I entered 1.9, code will increment a[1009]. If I enter 3.2 again, a[3002] will be incremented again.
This was input part.
Now code parses entire array a starting from 0. At first it will encounter 1009, code will print 1.9 and keep on parsing array.
When it finds 7 non=zero locations, loop exits.
When you enter same number again, like 3.2, while(a[i]) executes twice printing same number again.
As smaller number will be at lower location in array and array parsing starts from 0, it prints smallest 7 numbers. If you reverse the for loop, you can print 7 biggest numbers.
The answer here is how the input data is being stored.
User entered values populate array a. It does not store actual entered numbers, but a COUNT how many times the value was entered (code makes lots of assumptions about data sanity, but lets ignore that)
The data is naturally Sorted from smallest to largest, so to find 7 smallest inputs you just take first 7 values (iterations tracked by index i, c tracks how many values we already did print out) where the COUNT is not zero (a[i], non zero value indicates how many times user entered corresponding value)

C Program crashes at For Loop

I'm new to C programming (I have some very basic experience with programming via vb.NET), and I'm attempting to write a program for the Project Euler Problem #1.
https://projecteuler.net/problem=1
Algorithm
The challenge requires the programmer to find the sum of all multiples of 3 or 5 (inclusive) below 1000 (I used intInput to allow the user to enter an integer in place of 1000).
My current solution takes the input, and decrements it by 1 until (intInput - n) % 3 = 0, that is, until the next nearest multiple of 3 under the input integer is found.
The program then cycles through all integers from 1 to ((intInput - n) / 3), adding each integer to the sum of the previous integers, so long as the current integer is not a multiple of 5, in which case, it is skipped.
The resultant sum is then stored in intThreeMultiplier.
The above process is then repeated, using 5 in place of 3 to find the highest multiple of 5 under intInput, and then cycles through integers 1 to ((intInput - n) / 5), not skipping multiples of 3 this time, and stores the sum in intFiveMultiplier.
The output sum is then calculated via sum = (3 * intThreeMultiplier) + (5 * intFiveMultiplier).
The Problem
Whenever I compile and run my code, the user is allowed to input an integer, and then the program crashes. I have determined that the cause has something to do with the first For loop, but I can't figure out what it is.
I have commented out everything following the offending code fragment.
Source Code:
#include <stdio.h>
#include <stdlib.h>
void main()
{
int intInput = 0; /*Holds the target number (1000 in the challenge statement.)*/
int n = 0;
int count = 0;
int intThreeMultiplier = 1;
int intFiveMultiplier = 1;
printf("Please enter a positive integer.\n");
scanf("%d",intInput);
for( ; (((intInput - n) % 3) != 0) ; n++)
{}
/*for(; count <= ((intInput - n) / 3); count++)
{
if ((count % 5) != 0)
{
intThreeMultiplier += count;
}
}
count = 0;
for(n = 0 ; ((intInput - n) % 5) != 0 ; n++)
{}
for(; count <= ((intInput - n) / 5) ; count++)
{
intFiveMultiplier += count;
}
int sum = (3 * intThreeMultiplier) + (5 * intFiveMultiplier);
printf("The sume of all multiples of 3 or 5 (inclusively) under %d is %d.",intInput, sum);*/
}
This is my first time posting on StackOverflow, so I apologize in advance if I have broken any of the rules for asking questions, and would appreciate any feedback with respect to this.
In addition, I am extremely open to any suggestions regarding coding practices, or any rookie mistakes I've made with C.
Thanks!
scanf("%d",intInput);
might be
scanf("%d", &intInput); // note the ampersand
scanf need the address the variable where the content is to be stored. Why scanf must take the address of operator
For debugging only, print the input to verify that the input is accepted correctly, something like
printf("intInput = %d\n", intInput);
The first thing you need when you are inputting intInput you should use:
scanf("%d", &intInput);
Because scanf() need as an argument of a pointer to your variable. You are doing this by just putting the & sign before your int.
In addition I think that you should double check your algorithm, because you are summing up some numbers more than once. :)

How do I fix this issue with the if statements inside this for loop?

#define MAX 100000
bool hasPair(int array[], int start, int end, int size, int number)
{
int i, temp;
bool binMap[MAX] = {0}; /*initialize hash map as 0*/
for(i = 0; i < size; i++)
{
temp = number - array[i];
if((temp>=0 && binMap[temp] == 1) && (temp != array[i]) && (array[i]>=start && array[i]<=end))
{
printf("The array contains at least one pair which sums up to %d.\n",number); // problem here
return true;
}
binMap[array[i]] = 1;
if(binMap[temp] == 0 && binMap[array[i]] == 0) //and here
{
printf("The array does not contain any pair which sums up to %d.",number);
return false;
}
}
}
I need to write a function which gets an array,its size,the range of its elements(start and end) and a random number as input and the output must be a statement whether there is a pair of different numbers inside the array that their sum equals that random number that we entered as input.I have a problem with the if statements,
because for example:-
an array of 10 elements and the range of these elements is 0-10 the random number is 18 and the arrays elements are:- 0,5,5,2,9,8,2,7,8,2.There wont be any combination of sum between two different numbers of this array which gives us 18
and it works fine in the functions I wrote.
The problem is that for example if we took the same array and this time we substituted 18 for 10 then there will be two different numbers that their sum will be equal to 10 but in my function if I enter this array with random number as 10 then it wont work and I think there is a problem with my If statement so if you can see it whats the problem here?
Your mistake is in the 2nd if condition. It's redundant. You are always invoking this case after the first iteration, and you don't go on for the next iterations.
You should remove the 2nd if condition entirely, and instead add AFTER the for loop a simple statement: return false;.
The idea is you should let the algorithm keep going to the next iterations, even if one was unseccesful. You only return false when you are done with the loop without finding matching elements during it - and only now you can tell no such elements exist.

How should I generate the n-th digit of this sequence in logarithmic time complexity?

I have the following problem:
The point (a) was easy, here is my solution:
#include <stdio.h>
#include <string.h>
#define MAX_DIGITS 1000000
char conjugateDigit(char digit)
{
if(digit == '1')
return '2';
else
return '1';
}
void conjugateChunk(char* chunk, char* result, int size)
{
int i = 0;
for(; i < size; ++i)
{
result[i] = conjugateDigit(chunk[i]);
}
result[i] = '\0';
}
void displaySequence(int n)
{
// +1 for '\0'
char result[MAX_DIGITS + 1];
// In this variable I store temporally the conjugates at each iteration.
// Since every component of the sequence is 1/4 the size of the sequence
// the length of `tmp` will be MAX_DIGITS / 4 + the string terminator.
char tmp[(MAX_DIGITS / 4) + 1];
// There I assing the basic value to the sequence
strcpy(result, "1221");
// The initial value of k will be 4, since the base sequence has ethe length
// 4. We can see that at each step the size of the sequence 4 times bigger
// than the previous one.
for(int k = 4; k < n; k *= 4)
{
// We conjugate the first part of the sequence.
conjugateChunk(result, tmp, k);
// We will concatenate the conjugate 2 time to the original sequence
strcat(result, tmp);
strcat(result, tmp);
// Now we conjugate the conjugate in order to get the first part.
conjugateChunk(tmp, tmp, k);
strcat(result, tmp);
}
for(int i = 0; i < n; ++i)
{
printf("%c", result[i]);
}
printf("\n");
}
int main()
{
int n;
printf("Insert n: ");
scanf("%d", &n);
printf("The result is: ");
displaySequence(n);
return 0;
}
But for the point b I have to generate the n-th digit in logarithmic time. I have no idea how to do it. I have tried to find a mathematical property of that sequence, but I failed. Can you help me please? It is not the solution itself that really matters, but how do you tackle this kind of problems in a short amount of time.
This problem was given last year (in 2014) at the admission exam at the Faculty of Mathematics and Computer Science at the University of Bucharest.
Suppose you define d_ij as the value of the ith digit in s_j.
Note that for a fixed i, d_ij is defined only for large enough values of j (at first, s_j is not large enough).
Now you should be able to prove to yourself the two following things:
once d_ij is defined for some j, it will never change as j increases (hint: induction).
For a fixed i, d_ij is defined for j logarithmic in i (hint: how does the length of s_j increase as a function of j?).
Combining this with the first item, which you solved, should give you the result along with the complexity proof.
There is a simple programming solution, the key is to use recursion.
Firstly determine the minimal k that the length of s_k is more than n, so that n-th digit exists in s_k. According to a definition, s_k can be split into 4 equal-length parts. You can easily determine into which part the n-th symbol falls, and what is the number of this n-th symbol within that part --- say that n-th symbol in the whole string is n'-th within this part. This part is either s_{k-1}, either inv(s_{k-1}). In any case you recursively determine what is n'-th symbol within that s_{k-1}, and then, if needed, invert it.
The digits up to 4^k are used to determine the digts up to 4^(k+1). This suggests writing n in base 4.
Consider the binary expansion of n where we pair digits together, or equivalently the base 4 expansion where we write 0=(00), 1=(01), 2=(10), and 3=(11).
Let f(n) = +1 if the nth digit is 1, and -1 if the nth digit is 2, where the sequence starts at index 0 so f(0)=1, f(1)=-1, f(2)-1, f(3)=1. This index is one lower than the index starting from 1 used to compute the examples in the question. The 0-based nth digit is (3-f(n))/2. If you start the indices at 1, the nth digit is (3-f(n-1))/2.
f((00)n) = f(n).
f((01)n) = -f(n).
f((10)n) = -f(n).
f((11)n) = f(n).
You can use these to compute f recursively, but since it is a back-recursion you might as well compute f iteratively. f(n) is (-1)^(binary weight of n) = (-1)^(sum of the binary digits of n).
See the Thue-Morse sequence.

Display number in vertical format [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I'm new to C. I have a class assignment to display a number in a vertical format. If the user enters 5678, the instructor want it to display vertically to the screen in a single column as:
8
7
6
5
Second part of assignment is to find the largest divisor of the same number.
I'm totally lost. I'm getting the NUM value from another function. formula seems to work on even numbers, but on odd.
int divisor (int NUM)
{
int index, count=0;
for(index=2;index<=(NUM/2);index=index+1)
{
if(NUM%index==0)
count++;
}
printf("\n\nThe largest divisor of %d is %d\n",NUM, index-1);
return(index);
}
To display the number vertically:
1. get least significant digit,
2. print it and print new line,
3. shift number to the right by one digit
4. goto 1
Algorithm terminates when the number is zero. Call the input number n; getting the least significant (rightmost) digit can be done with n % 10. Right shift can be done with n = n / 10.
For the second part, observe that the largest divisor cannot be more than n/2 (because n = 2 * n/2). So try all number from n/2 down to 1 and break once you find a divisor. You will find the largest divisor because you are considering numbers in decreasing order. To check that x divides y use y % x == 0.
A second way it to check numbers from sqrt(n) down to 1. If m divides n, we can write n = m * k for some k. Now you take max(m, n/m) and continue.
Hope this helps :)
For the first part, there are many ways to approach this. But, without using too many of the standard library functions which seems to be a level appropriate for the question, I think the easiest way would be to take the numbers as a character array. Then access each value through it's index in the character array. This requires only the stdio.h header file. Some quick notes: simply use printf to print the value contained at each index, and throw the newline \n character at the end. If you wanted convert the string to an integer, you can do that very easily using the function atoi() which can be found in stdlib.h. If you want to print out backward, you can simply traverse the array backward.
void displayvert(char str[])
{
int i;
for (i = 0; str[i] != '\0'; ++i) {
printf("%c\n", str[i]);
}
}
Also many ways to approach the second, but in this case for the second question I think I'd use the modulus operator and track the highest value where the result is zero. In order for this to work with the single user provided input, I actually needed atoi() which is in the stdlib.h header. Basically, starting from the value one you'll increase the value up the integer just below the value of 'num' itself. And, if the remainder is zero when you when you divide by it (the purpose of using the modulus operator) then you know it's divisible. Because we're ascending from 1 to the number itself, the last value to return a remainder of zero is the greatest common divisor.
void getgcd(int num)
{
int i, gcd;
// remember, you can't do x % 0!
for (i = 1; i < num; i++) {
if ((num % i) == 0 ) {
gcd = i;
}
}
printf("The greatest common divisor is: %d\n", gcd);
}
Main function and prototypes here so you can see how it all tied together. A couple of quick notes (1) 11 digits was arbitrary; but it's important to note that we used 10 digits for the total input value (you can add checks to this to enforce) and reserved the 11th (at index 10) to allow space for the null terminating character \0. (2) Use scanf to grab input; note that because character arrays do not require the address operator & because it defaults to that.
#include <stdio.h>
#include <stdlib.h>
void displayvert(char str[]);
void getgcd(int num);
int main()
{
char input[11]; // additional character added for \0
printf("Please enter a value up to 10 digits: ");
scanf("%s", input);
displayvert(input);
getgcd(atoi(input));
return 0;
}

Resources