I am doing a problem about checking monotonic sequences. The problem is inputting a sequence and then print "YES" if it is monotonic, "NO" if it is not.
This is my code:
#include <stdio.h>
int main()
{
//Inputting the sequence
int n;
scanf("%d", &n);
int a[n];
for (int i = 1; i <= n; i++)
{
scanf("%d ", &a[i]);
}
//Checking monotonic sequence
for (int i = 1; i <= n; i++)
{
if ((a[i] > a[i-1]) && (a[i] > a[i+1]))
{
printf("NO");
return;
}
else if ((a[i] < a[i-1]) && (a[i] < a[i+1]))
{
printf("NO");
return;
}
}
printf("YES");
return 0;
}
I have failed 2 test case with sequences [1, 2, 3] and [10, 6, 4, 2, 1, -100]; and passed one test case with [1, 2, 3, 3, 2, 1]. Can anyone please point out the problem in my code? I would truly appreciate that. Thank you.
Remove trailing " ". It obliges additional input (or end-of-file) after the number is entered before scanf() returns.
// scanf("%d ", &a[i]);
scanf("%d", &a[i]);
In addition to index problems in 2 places, code needs to look for overall monotonic and not just local monotonic behavior.
bool up = true;
bool down = true;
// for (int i = 1; i <= n; i++)
for (int i = 1; i < n; i++) {
if (a[i] > a[i-1]) down = false;
if (a[i] < a[i-1]) up = false;
}
printf((up || down) ? "YES" : "NO");
Additional code to short-circuit loop.
// for (int i = 1; i < n; i++) {
for (int i = 1; i < n && (up || down); i++) {
Further there is lack of the coding goal clarity on tie cases. May need
if (a[i] >= a[i-1]) down = false;
if (a[i] <= a[i-1]) up = false;
a has indices from 0 to n-1; you code references a[0] (which never gets assigned to) and a[n] (which is outside the bounds of the array).
You are checking with invalid array index. here you are declaring an array size of n but you are checking with i+1 that means n+1 for the last case. This is out of bound for your array. First of all you are storing data in array from 1 to n . But when you declare a array size n then it has index from 0 to n-1.so you can store data from 0 to n and start the check from 1 and end in n-1.
this one will work for you:
#include <stdio.h>
int
main ()
{
//Inputting the sequence
int n;
scanf ("%d", &n);
int a[n];
for (int i = 0; i < n; i++)
{
scanf ("%d", &a[i]);
}
int inc = 0;
int dec = 0;
//Checking monotonic sequence
for (int i = 1; i < n ; i++)
{
if (a[i] > a[i - 1])
{
inc = 1;
}
else if (a[i] < a[i - 1])
{
dec = 1;
}
}
if (inc == 1 && dec == 1)
{
printf ("NO");
}
else
{
printf ("YES");
}
return 0;
}
Related
How do I make my code more efficient (in time) pertaining to a competitive coding question (source: codechef starters 73 div 4):
(Problem) Chef has an array A of length N. Chef wants to append a non-negative integer X to the array A such that the bitwise OR of the entire array becomes = Y .
Determine the minimum possible value of X. If no possible value of X exists, output -1.
Input Format
The first line contains a single integer T — the number of test cases. Then the test cases follow.
The first line of each test case contains two integers N and Y — the size of the array A and final bitwise OR of the array A.
The second line of each test case contains N space-separated integers A_1, A_2, ..., A_N denoting the array A.
Please don't judge me for my choice of language .
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int* binary_number(int n) // returns pointer to a array of length 20(based on given constrains) representing binary
{
int* ptc;
ptc = (int*) malloc(20*sizeof(int));
for(int i = 0; i < 20; i++)
{
if((n / (int) pow(2,19-i)) > 0){*(ptc + i) = 1;}
else {*(ptc + i) = 0;}
n = n % (int) pow(2,19-i) ;
}
return ptc;
}
int or_value(int* ptc, int n) // Takes in pointers containing 1 or zero and gives the logical OR
{
for(int k = 0; k < n; n++)
{
if(*ptc == *(ptc + 20*k)){continue;} // pointers are 20 units apart
else{return 1;break;}
}
return *ptc;
}
int main(void) {
int t; scanf("%d", &t);
for (int i = 0; i < t; i++)
{
int n, y;
scanf("%d %d", &n, &y);
int a[n];
for(int j = 0; j < n ; j++)
{
scanf("%d", &a[j]);
}
int b[20*n];
for (int j = 0; j < n; j++)
{
for (int k = 0; k < 20; k++)
{
b[20*j + k] = *(binary_number(a[n])+k);
}
}
int c = 0;
int p = 0;
for (int j = 0; j < 20; j++)
{
if ((*(binary_number(y) + j) == 1) && (or_value((&b[0] + j),n) == 0)){c = c + pow(2,19 - j);}
else if ((*(binary_number(y) + j) == 0) && (or_value((&b[0] + j),n) == 1)){p = 1; break;}
}
if (p==1){printf("-1");}
else {printf("%d\n", c);}
}
return 0;
}
I wrote a program that examines whether a number in a sequence is repeated 2 times (so many times it should be repeated) if it is repeated 2 times "YES", if not "NO". I think this can be written in a simpler and better way, so I'm interested in the suggestions and corrections of someone more experienced than me.
The program should print YES if each member of array is repeated exactly once, and otherwise it should print NO:
Enter the number of array: 8
Enter the sequence: 1 2 2 1 3 3 4 4
YES
Enter the number of string members: 7
Enter the string: 1 2 1 2 1 3 4
NO
Here is my code:
#include <stdio.h>
#define arr 100
int main() {
int n, i, p = 1, j, a;
double array[arr];
int num[100];
do {
printf("Enter the number of array: ");
scanf("%d", &n);
} while (n < 1 || n > 100);
printf("Enter array: ");
for (i = 0; i < n; i++) {
scanf("%lf", &array[i]);
num[i] = -1;
}
for (i = 0; i < n; i++) {
a = 1;
for (j = i + 1; j < n; j++) {
if (array[i] == array[j]) {
a++;
num[j] = 0;
}
}
if (num[i] != 0)
num[i] = a;
}
for (i = 0; i < n; i++) {
if (num[i] == 0)
continue;
if (num[i] != 2) {
p = 0;
break;
}
}
if (p == 1)
printf("YES");
else
printf("NO");
return 0;
}
I am going to provide a code review here because the code doesn't work and that makes it off-topic on Code Review.
Good things about the code:
There are no global variables.
There is an attempt to define a symbolic constant for the array size.
Things that can be improved:
Declare the variables are you need them. In the original version of C back in the 1970s and 1980s variables had to be declared at the top of the function. That is no longer the case, and a recommended programming practice to declare the variable as needed. In C the language doesn't provide a default initialization of the variable so variables should be initialized as part of the declaration. For readability and maintainability each variable should be declared and initialized on its own line.
Capitalize the constants, arr should be ARR.
ARR should be used in the declaration of num as well as the declaration of array.
ARR should be used instead of 100 in this statement while (n < 1 || n > 100).
Since the program only allows a single digit to be read at a time, array should be an array of integers rather than array of doubles.
There is only one error check on user input.
A simplified version of the program that does work:
One of the first things you need to learn in programming is how to write functions and subroutines. This is important because it allows you to break problems into smaller and smaller pieces until it is very easy to solve the problem. There are a number of programming principles that this relates to, 2 of them are the Single Responsibility Principle states:
that every module, class, or function should have responsibility over a single part of the functionality provided by the software, and that responsibility should be entirely encapsulated by that module, class or function.
and the KISS Principle (Keep It Simple).
#include <stdio.h>
#include <stdbool.h>
#define ARR 100
static int get_user_input(int array[ARR])
{
int count = 0;
do {
printf("Enter the number of array: ");
scanf("%d", &count);
} while (count < 1 || count > ARR);
printf("Enter array: ");
for (int i = 0; i < count; i++) {
scanf("%1d", &array[i]);
}
return count;
}
static bool find_first_repetition(int count, int array[ARR])
{
bool repetition = false;
for (int i = 1; i < count; i++)
{
if (array[i - 1] == array[i])
{
return true;
}
}
return repetition;
}
int main() {
int n;
int num[ARR];
n = get_user_input(num);
if (find_first_repetition(n, num))
{
printf("YES");
}
else
{
printf("NO");
}
return 0;
}
Your code works, but there are some issues:
you should test for conversion failures in scanf(): the return value must be 1 as there is a single conversion for each scanf() call.
the counting loops are too complicated: just counting the number of occurrences with 2 nested loops is much simpler and has comparable time complexity, and using a += (array[i] == array[j]); may produce fast branchless code on most architectures.
it is good style to finish the program output with a newline.
Here is a modified version:
#include <stdio.h>
int main() {
int n;
do {
printf("Enter the length of the array: ");
if (scanf("%d", &n) != 1)
return 1;
} while (n < 1 || n > 100);
double array[n];
printf("Enter array: ");
for (int i = 0; i < n; i++) {
if (scanf("%lf", &array[i]) != 1)
return 1;
}
int p = 1;
for (int i = 0; i < n; i++) {
int a = 0;
for (int j = 0; j < n; j++) {
a += (array[i] == array[j]);
}
if (a != 2) {
p = 0;
break;
}
}
if (p == 1)
printf("YES\n");
else
printf("NO\n");
return 0;
}
So here is the problem: Write a program that accept an integer n, print out the largest number but smaller or equal n that is the product of two consecutive even number. Example: Input: 12, Output: 8 ( 2x4 )
Here is my code :
#include <stdio.h>
int main()
{
int n;
scanf("%d", &n);
for (int i = n; i >= 0; i--)
{
for (int j = 0; j <= n; j = j + 2)
{
if ( i == j * (j+2) )
{
printf("%d ", i);
break;
}
}
}
return 0;
}
So if i input 20, it will print out 8 and 0 instead of 8, if i input 30, it will print out 24,8 and 0 instead of just 24. How do i make it stop after printing out the first number that appropriate ?
You need to stop an outer loop from processing, for example by using a boolean flag (meaning "solution found, we finish work") or a goto statement.
#include <stdio.h>
int main() {
int n;
scanf("%d", &n);
int solutionFound = 0;
for (int i = n; i >= 0; i--) {
// this could also be put into for's condition i.e. "i >= 0 && !solutionFound"
if (solutionFound) {
break;
}
for (int j = 0; j <= n; j = j + 2) {
if ( i == j * (j+2) ) {
printf("%d ", i);
solutionFound = 1;
break;
}
}
}
return 0;
}
EDIT: immediate return as noted in the comments is also a nice idea, if you don't need to do anything later.
Your problem is that you are nested - in a for loop which is inside another for loop - when you want to stop processing.
Some languages would let you code break 2; to indicate that you want to break out of 2 loops. Alas, C i snot such a language.
I would recommend that you code a function. That would serve a few porpoises: 1) your main should be "lean & mean" 2) as your programs get larger, you will learn the benefits of putting individual coding tasks into functions 3) you can use return; instead of break; and it will exit the function immediately.
Something like this:
#include <stdio.h>
void FindNeighbouringDivisors(int n)
{
for (int i = n; i >= 0; i--)
{
for (int j = 0; j <= n; j = j + 2)
{
if ( i == j * (j+2) )
{
printf("%d times %d = %d", j, j + 2, i);
return;
}
}
}
printf("There are no two adjacent even numbers which can be multiplied to give %d", n);
}
int main()
{
int n;
scanf("%d", &n); /* could get from comamnd line */
FindNeighbouringDivisors(n);
return 0; /* should be EXIT_SUCCESS */
}
Btw, when you have a problem with your code, ask a question here. When you have it working, consider posting it at our code review site where more experienced programmers can give you advice on how to improve it. It's a great way to learn
Break only breaks you out of immediate loop, so either use flags or just use return to terminate the execution. Or you can even use following code:
#include <stdio.h>
int main()
{
int n;
scanf("%d", &n);
for (int j = 0; j <= n; j = j + 2)
{
if ( n < j * (j+2) )
{
printf("%d ", j*(j-2));
break;
}
}
return 0;
}
This is a program on sorting integers.
#include <stdio.h>
int main(void) {
int n, i, j, k;
int nmbr[100];
printf("\n How many numbers ? ");
scanf("%d", &n);
printf("\n");
for (i = 0; i < n; ++i) {
printf(" Number %d : ", i + 1);
scanf("%d", &nmbr[i]);
}
for (i = 0; i < n; ++i) {
for (j = 0; j < n; ++j) {
if (nmbr[j] > nmbr[j + 1]) {
k = nmbr[j];
nmbr[j] = nmbr[j + 1];
nmbr[j + 1] = k;
}
}
}
printf("\n Numbers after sorting : \n");
for (i = 0; i < n; ++i) {
printf (" %d", nmbr[i]);
}
return 0;
}
It works fine, but when I enter some number that contains more than 2 digits, the first number that is printed is negative and really big. I don't also get the last integer too. I enter N as 4, then the numbers I entered were 25, 762, 588, and 34. The result I get is:
-1217260830 25 34 588
What seems to be the problem?
You are running the loop as for (j = 0; j < n; ++j) which means j will have values from 0 to n-1 which are valid array indices (or array elements with relevant values).
But, inside that loop you are accessing an element beyond the last. For instance, in
if (nmbr[j] > nmbr[j + 1])
you are accessing nmbr[j + 1]. If the current value of j in n-1, then you are accessing nmbr[n-1 + 1] i.e. nmbr[n] which will be a value outside the array and may contain a garbage value (which might as well be negative!).
If you are trying something like Bubblesort, you might want to run the inner loop like for (j = 0; j < n - 1; ++j).
There are multiple problems in your code:
You do not check the return values of scanf(). If any of these input operations fail, the destination values remain uninitialized, invoking undefined behavior and potentially producing garbage output.
You do not verify that the number of values provided by the user is at most 100. The reading loop will cause a buffer overflow if n is too large.
Your sorting logic is flawed: in the nested loop, you refer to nmbr[j + 1] which is beyond the values read from the user. This invokes undefined behavior: potentially causing a garbage value to appear in the output.
Here is a corrected version:
#include <stdio.h>
int main(void) {
int n, i, j, k;
int nmbr[100];
printf("\n How many numbers ? ");
if (scanf("%d", &n) != 1 || n > 100) {
printf("input error\n");
return 1;
}
printf("\n");
for (i = 0; i < n; ++i) {
printf(" Number %d : ", i + 1);
if (scanf("%d", &nmbr[i]) != 1) {{
printf("input error\n");
return 1;
}
}
for (i = 0; i < n; ++i) {
for (j = 0; j < n - 1; ++j) {
if (nmbr[j] > nmbr[j + 1]) {
k = nmbr[j];
nmbr[j] = nmbr[j + 1];
nmbr[j + 1] = k;
}
}
}
printf("\n Numbers after sorting :\n");
for (i = 0; i < n; ++i) {
printf (" %d", nmbr[i]);
}
printf("\n");
return 0;
}
Your Sorting Logic is wrong. It should be:
for (i = 0; i < n; ++i){
for (j = 0; j < (n-1); ++j){
if (nmbr[j] > nmbr[j + 1]){
k = nmbr[j];
nmbr[j] = nmbr[j + 1];
nmbr[j + 1] = k;
}
}
You are trying to access out of bounds of array, when you iterate in your second loop using j. This is causing the garbage value.
As per your example involving 4 elements, when you try to access j+1, it will try to access nmbr[3+1] in the last iteration of second loop which leads to out of bounds access.
Problem is with the sorting logic as suggested by fellow coders. But It is always good coding habit to initialize the variables. Also use the qualifier if are dealing with positive numbers only.
unsigned int n = 0 , i = 0, j = 0, k = 0;
unsigned int nmbr[100] = {0};
If you would have initialized them, out put of your program would be following, which might help you tracing the problem by yourself.
0 25 34 588
int main(void)
{
int i,j=0,k; //initialization
char equation[100]; //input is a string (I think?)
int data[3]; //want only 3 numbers to be harvested
printf("Enter an equation: ");
fgets(equation, 100, stdin); //not so sure about fgets()
for (i = 0; i < equation[100]+1; i++) { //main loop which combs through
//"equation" array and attempts
//to find int values and store
while (j <= 2) { //them in "data" array
if (isdigit(equation[i])) {
data[j] = equation[i]
j++;
}
}
if (j == 2) break;
}
for (k = 0; k <= 2; k++) { //this is just to print the results
printf("%d\n", data[k]);
}
return 0;
}
Hello! This is my program for my introductory class in C, I am trying to comb through an array and pluck out the numbers and assign them to another array, which I can then access and manipulate.
However, whenever I run this I get 0 0 0 as my three elements in my "data" array.
I am not sure whether I made an error with my logic or with the array syntax, as I am new to arrays.
Thanks in advance!!! :)
There are a few problems in your code:
for (i = 0; i < equation[100]+1; i++) { should be something like
size_t equ_len = strlen(equation);
for (i = 0; i < equ_len; i++) {
Whatever the input is, the value of equation[100] is uncertain, because char equation[100];, equation only has 100 element, and the last of them is equation[99].
equation[i] = data[j]; should be
data[j] = equation[i];
I suppose you want to store digit in equation to data.
break; should be deleted.
this break; statement will jump out of the while loop, the result is you will store the last digit in equation to data[0] (suppose you have switched data and equation, as pointed out in #2).
If you want the first three digits in equation, you should do something like
equ_len = strlen(equation);
j = 0;
for (i = 0; i < equ_len; i++) {
if (j <= 2 && isdigit(equation[i])) {
data[j] = equation[i];
j++;
}
if (j > 2) break;
}
printf("%d\n", data[k]); should be printf("%c\n", data[k]);
%d will give the ASCII code of data[k], for example, if the value of data[k] is character '1', %d will print 50 (the ASCII code of '1') instead of 1.
Here is my final code, based on the OP code:
#include <ctype.h>
#include <string.h>
#include <stdio.h>
int main(void)
{
int i,j,k;
char equation[100];
int data[3];
int equ_len;
printf("Enter an equation: ");
fgets(equation, 100, stdin);
equ_len = strlen(equation);
j = 0;
for (i = 0; i < equ_len; i++) {
if (j <= 2 && isdigit(equation[i])) {
data[j] = equation[i];
j++;
}
if (j > 2) break;
}
for (k = 0; k <= 2; k++) {
printf("%c\n", data[k]);
}
return 0;
}
Tested with:
$ ./a.out
Enter an equation: 1 + 2 + 3
1
2
3