Paper Code: ESCS 202
Programming for Problem Solving
Year 2024
Group-A
1. I) What will be the output
#include <stdio.h>
void main()
{
int a[2][3] = {1, 2, 3, 4, 5};
int i = 0, j = 0;
for(i = 0; i < 2; i++)
for(j = 0; j < 3; j++)
printf("%d ", a[i][j]);
}
Output
123450
ii) What is the worst case complexity of bubble sort?
Answer: O(n²)
iii) What Is the default return type of function definition?
If you did not specify a return type, the compiler assumed int by default.
iv) What will be the output
#include <stdio.h>
main() {
int n;
n = f1(4);
printf("%d", n);
}
f1(int x) {
int b;
if(x == 1)
return 1;
else
b = x * f1(x - 1);
return b;
}
Answer:
24
v) What is the size of a C structure?
The size of a C structure depends on several factors: the sizes of its members, their types, and padding for memory
alignment.
struct MyStruct {
char c;
int i;
float f;
};
char → 1 byte
int → typically 4 bytes
float → typically 4 bytes
Naively, sum = 1 + 4 + 4 = 9 bytes.
vi) What will be the output
#include <stdio.h>
int main() {
int a = 3, *b = &a;
printf("%d", a * b);
}
Answer:
9
vii) Which language is written in binary codes only?
The language that is written in binary codes only is called Machine Language (or Machine Code).
viii) The C pre-processors are specified with which symbols
In C, preprocessor directives are instructions given to the preprocessor before compilation. They always start with
the # symbol.
ix) What will be the output of the following C code?
#include<stdio.h>
void main(){
double ct ;
printf (" enter a value between 1 to 2 :") ;
scanf ("%lf", &ch) ; // ch is undeclared
Switch (ch) { // Switch should be lowercase: switch
case 1 :
printf("1") ; break;
case 2:
printf("2");
break;
}
}
Answer:
syntax errors
x) What Will happen if in a C program you assign a value to an array element whose subscript exceeds the size of
array?
Assigning a value to an array element with a subscript exceeding its size leads to undefined behavior — it may
corrupt memory, crash the program, or seemingly work incorrectly.
xi) What is the advantage of selection sort over other sorting techniques?
Advantages of Selection Sort:
1. Simple and easy to implement
2. Requires minimal swaps
3. In-place (no extra memory needed)
4. Predictable performance regardless of input
5. Works well on small arrays
xii) What is the limit for number of functions in a C Program?
There is no fixed limit in the C language; the limit depends on the compiler and system resources.
Group B
2. What the differences between call by value and call by reference.
Feature Call by Value Call by Reference
Parameters passed Copy of value Address of variable
Effect on original
No change Changes are reflected
variable
Memory used Extra memory for copies Less memory, no copy
Safety Safer (original not modified) Must be careful with pointers
When original data must not When we want function to modify original
Use case
change data
3. Write a C program to compute factorial of a number using recursion
#include <stdio.h>
// Recursive function to calculate factorial
int factorial(int n) {
if (n == 0 || n == 1) // Base case: factorial of 0 or 1 is 1
return 1;
else
return n * factorial(n - 1); // Recursive call
}
int main() {
int num;
printf("Enter a positive integer: ");
scanf("%d", &num);
if (num < 0)
printf("Factorial is not defined for negative numbers.\n");
else
printf("Factorial of %d is %d\n", num, factorial(num));
return 0;
}
4. What is the difference between break and continue statement?
Feature break continue
Action Exits the loop or switch Skips current iteration, continues loop
Scope Loops and switch Only loops
Effect on loop Stops loop completely Loop continues with next iteration
Use case Terminate early on a condition Skip processing for specific iteration
5. Differentiate between Compiler and interpreter
Feature Compiler Interpreter
Translation Whole program at once Line by line
Execution speed Fast Slower
Feature Compiler Interpreter
Error detection All errors together Errors stop execution immediately
Output file Yes No
Memory More Less
Example C, C++ Python, Ruby
6. Write a C program to perform addition, subtraction, multiplication and division of two numbers by using switch case.
#include <stdio.h>
int main() {
double num1, num2, result;
char operator;
// Input numbers
printf("Enter first number: ");
scanf("%lf", &num1);
printf("Enter second number: ");
scanf("%lf", &num2);
// Input operator
printf("Enter an operator (+, -, *, /): ");
scanf(" %c", &operator); // Notice the space before %c
// Switch case for operations
switch(operator) {
case '+':
result = num1 + num2;
printf("Result: %.2lf\n", result);
break;
case '-':
result = num1 - num2;
printf("Result: %.2lf\n", result);
break;
case '*':
result = num1 * num2;
printf("Result: %.2lf\n", result);
break;
case '/':
if(num2 != 0) {
result = num1 / num2;
printf("Result: %.2lf\n", result);
} else {
printf("Error: Division by zero is not allowed.\n");
}
break;
default:
printf("Error: Invalid operator entered.\n");
}
return 0;
}
Group-C
7. Describe different types of asymptotic notation of complexity analysis of algorithms.
In algorithm analysis, asymptotic notations are used to describe the time or space complexity of an algorithm as the
input size grows. These notations help estimate performance independent of machine or implementation details.
Let’s go through the different types of asymptotic notations clearly:
1. Big O Notation (O)
Definition: Represents the upper bound of an algorithm’s running time.
It tells us the worst-case performance.
Focus: “At most” how much time or space the algorithm will take.
Mathematical Form:
T (n)=O(f (n)) if ∃ c >0 , n0 >0 :T (n)≤ c ⋅f (n) for all n ≥ n0
Example:
Linear search in an array of size n: O(n)
Bubble sort (worst case): O(n²)
2. Omega Notation (Ω)
Definition: Represents the lower bound of an algorithm’s running time.
It tells us the best-case performance.
Focus: “At least” how much time the algorithm will take.
Mathematical Form:
T (n)=Ω(f ( n)) if ∃c >0 , n0 >0 :T (n)≥ c ⋅ f (n) for all n≥ n 0
Example:
Linear search (best case, element at first position): Ω(1)
Bubble sort (best case, already sorted, optimized): Ω(n)
3. Theta Notation (Θ)
Definition: Represents tight bound (both upper and lower bound) of an algorithm’s running time.
It tells us the average case or exact asymptotic behavior.
Mathematical Form:
T (n)=Θ(f (n)) if ∃ c 1 , c 2 >0 , n0 >0 :c 1 f ( n) ≤ T (n) ≤ c 2 f (n) for all n ≥n 0
Example:
Insertion sort (average case): Θ(n²)
Binary search: Θ(log n)
4. Little o Notation (o)
Definition: Represents an upper bound that is not tight.
Indicates that algorithm grows slower than f(n) asymptotically.
Mathematical Form:
T (n)
T (n)=o (f (n)) if lim =0
n →∞ f (n)
Example:
T(n) = n is o(n²) because n grows slower than n².
5. Little omega Notation (ω)
Definition: Represents a lower bound that is not tight.
Indicates that algorithm grows faster than f(n) asymptotically.
Mathematical Form:
T (n)
T (n)=ω (f (n)) if lim =∞
n →∞ f (n)
Example:
T(n) = n² is ω(n) because n² grows faster than n.
8. A) Write a C program to find the maximum and minimum of Some values using a function that returns an array.
In C, functions cannot directly return arrays, but we can return a pointer to an array or use static arrays. Here's a
program that finds maximum and minimum values using a function that returns an array
#include <stdio.h>
// Function to find max and min
int* findMaxMin(int arr[], int n) {
static int result[2]; // result[0] = max, result[1] = min
int i;
result[0] = arr[0]; // Initialize max
result[1] = arr[0]; // Initialize min
for(i = 1; i < n; i++) {
if(arr[i] > result[0])
result[0] = arr[i]; // Update max
if(arr[i] < result[1])
result[1] = arr[i]; // Update min
}
return result;
}
int main() {
int n, i;
printf("Enter number of elements: ");
scanf("%d", &n);
int arr[n];
printf("Enter %d elements:\n", n);
for(i = 0; i < n; i++)
scanf("%d", &arr[i]);
int *maxMin = findMaxMin(arr, n);
printf("Maximum value: %d\n", maxMin[0]);
printf("Minimum value: %d\n", maxMin[1]);
return 0;
}
b) Write a program in C to print all palindrome numbers in a given range using the function.
#include <stdio.h>
// Function to check if a number is palindrome
int isPalindrome(int num) {
int original = num, reversed = 0, digit;
while(num > 0) {
digit = num % 10;
reversed = reversed * 10 + digit;
num = num / 10;
}
if(reversed == original)
return 1; // Palindrome
else
return 0; // Not palindrome
}
int main() {
int start, end;
// Input range
printf("Enter the starting number: ");
scanf("%d", &start);
printf("Enter the ending number: ");
scanf("%d", &end);
printf("Palindrome numbers between %d and %d are:\n", start, end);
for(int i = start; i <= end; i++) {
if(isPalindrome(i)) {
printf("%d ", i);
}
}
printf("\n");
return 0;
}
Enter the starting number: 100
Enter the ending number: 150
Palindrome numbers between 100 and 150 are:
101 111 121 131 141
9. A) Write an algorithm to sort an array using the Merge sort algorithm
Algorithm: Merge Sort
Input: An array A[0…n-1] of n elements
Output: Sorted array in ascending order
Step 1: MergeSort(A, l, r)
1. If l >= r (array has 0 or 1 element)
o Return (already sorted)
2. Find the middle index:
m = (l + r) / 2
3. Recursively sort the left half:
MergeSort(A, l, m)
4. Recursively sort the right half:
MergeSort(A, m+1, r)
5. Merge the two sorted halves:
Merge(A, l, m, r)
Step 2: Merge(A, l, m, r)
Input: Two sorted subarrays A[l…m] and A[m+1…r]
Output: Merged sorted array in A[l…r]
1. Create temporary arrays L[0…m-l] and R[0…r-m-1]
o Copy A[l…m] into L[]
o Copy A[m+1…r] into R[]
2. Initialize pointers: i = 0, j = 0, k = l
3. While i < size(L) and j < size(R)
o If L[i] <= R[j]
A[k] = L[i]
i=i+1
o Else
A[k] = R[j]
j=j+1
o k=k+1
4. Copy any remaining elements of L[] (if i < size(L)) into A[]
5. Copy any remaining elements of R[] (if j < size(R)) into A[]
Step 3: Call MergeSort
MergeSort(A, 0, n-1)
After this, array A will be sorted in ascending order.
b) Calculate the time complexity of Merge sort
Let’s carefully calculate the time complexity of Merge Sort step by step. Merge Sort is a divide-and-conquer
algorithm, and its time complexity can be analyzed using recurrence relations.
1. Understanding Merge Sort Steps
1. Divide: The array of size n is divided into two halves.
o Takes O(1) time.
2. Conquer (Recursive Sort): Recursively sort each half.
3. Combine (Merge): Merge two sorted halves into one sorted array.
o Merging two arrays of size n/2 each → O(n) time.
2. Recurrence Relation
Let T(n) be the time complexity of sorting n elements.
T (n)=2 ⋅T (n/2)+ O(n)
2 * T(n/2) → recursive calls on two halves
O(n) → merging two halves
3. Solve the Recurrence Using Master Theorem
Master Theorem:
T (n)=aT (n /b)+ f (n)
Here: a = 2, b = 2, f(n) = n
Compare f(n) with n^{\log_b a}:
log 2 2 1
n =n =n
f(n) = Θ(n)
Case 2 of Master Theorem: f(n) = Θ(n^{\log_b a})
⇒T (n)=Θ(n log n)
10. What are the different types of Computer?
1. Based on Size and Power
Type Description Example / Use
Extremely fast and powerful; handles complex Weather forecasting, nuclear
Supercomputer
scientific calculations. simulations
Large, powerful; used by organizations for bulk Banks, airlines (reservation
Mainframe Computer
processing. systems)
Medium-sized; less powerful than mainframes,
Minicomputer Manufacturing process control
used in business or scientific tasks.
Microcomputer / Personal Small, low-cost; used by individuals for everyday
Desktop PCs, laptops, tablets
Computer (PC) tasks.
High-performance microcomputer for technical or CAD design, 3D modeling,
Workstation
scientific work. software development
Washing machines, microwave
Embedded Computer Built into other devices for dedicated functions.
ovens, smart TVs
2. Based on Purpose
Type Description
Can perform multiple tasks like word processing, gaming,
General-Purpose Computer
internet browsing.
Special-Purpose Computer Designed to perform specific tasks only.
Examples: ATMs, digital watches, traffic signal
controllers
3. Based on Data Handling
Type Description
Analog Computer Works with continuous data; measures physical quantities.
Digital Computer Works with discrete data (0s and 1s); most modern computers are digital.
Hybrid Computer Combines analog and digital features.
4. Based on Generation
Generation Technology Example / Feature
1st Gen (1940–1956) Vacuum tubes ENIAC
2nd Gen (1956–1963) Transistors IBM 1401
3rd Gen (1964–1971) Integrated Circuits (ICs) IBM 360
4th Gen (1971–Present) Microprocessors PCs, Laptops
5th Gen (Present & Future) AI, Machine learning, parallel processing Supercomputers, AI devices
11. A) Write a program in C language to print the factorial of a number.
#include <stdio.h>
int main() {
int n, i;
unsigned long long factorial = 1; // Use long long for large factorials
// Input number
printf("Enter a positive integer: ");
scanf("%d", &n);
if (n < 0) {
printf("Factorial is not defined for negative numbers.\n");
} else {
// Calculate factorial
for(i = 1; i <= n; i++) {
factorial *= i;
}
printf("Factorial of %d is %llu\n", n, factorial);
}
return 0;
}
Enter a positive integer: 5
Factorial of 5 is 120
b) Write a C program to print the Fibonacci series up to nth term.
#include <stdio.h>
int main() {
int n, i;
unsigned long long t1 = 0, t2 = 1, nextTerm;
// Input the number of terms
printf("Enter the number of terms: ");
scanf("%d", &n);
if (n <= 0) {
printf("Please enter a positive integer.\n");
} else {
printf("Fibonacci Series up to %d terms:\n", n);
for (i = 1; i <= n; i++) {
if (i == 1) {
printf("%llu ", t1);
continue;
}
if (i == 2) {
printf("%llu ", t2);
continue;
}
nextTerm = t1 + t2;
printf("%llu ", nextTerm);
t1 = t2;
t2 = nextTerm;
}
printf("\n");
}
return 0;
}
Enter the number of terms: 8
Fibonacci Series up to 8 terms:
0 1 1 2 3 5 8 13