Final Report 1
Final Report 1
Final Report 1
On
DSA Self-paced
Submitted by
Anaswar Aravind
(June-July, 2024)
DECLARATION
I hereby declare that I have completed my six weeks summer training at DSA Self paced
from 25th June 2024 to 22nd July 2024 under the guidance of Mr. Sandeep Jain. I declare
that I have worked with full dedication during these six weeks of training and my
learning outcomes fulfil the requirements of training for the award of degree of Bachelor
of Technology, Lovely Professional university, Phagwara.
Anaswar Aravind
Successfully completion of any type technology requires helps from a number of people. I
have also taken help from different people for the preparation of the report. Now, there is
little efforts to show my deep gratitude to those helpful people.
I would like to also thank my own college Lovely Professional University for offering
such a course which not only improve my programming skill but also introduced me to
new technologies.
Then I would like to thank my parents and friends who have helped me with their
valuable suggestions and guidance for choosing this course.
Last but not least I would like to thank my all classmates who have helped me a lot.
Table Of Contents
1. Introduction
2. Technology Learnt
3. Reason for choosing this technology.
4. Profile of the Problem
5. Problem Analysis
• Problem definition
• Feasibility Analysis
• Problem Complexity
• Constraints and Requirements
• Solution Strategy
• Performance Considerations
• Error Handling
6. Software Requirement Analysis
• Functional Requirements
• Non-Functional Requirements
• Software Requirements
• Assumptions and Constraints
Data Structure is a way of collecting and organizing data in such a way that we can
perform operations on these data in an effective way. Data Structures is about
rendering data elements in terms of some relationship, for better organization and
storage. For example, we have some data which has, player's name "Virat" and age
26. Here "Virat" is of String data type and 26 is of integer data type.
2. What is Algorithm?
This course is a complete package that helped me learn Data Structures and Algorithms
from basic to an advanced level. The course curriculum has been divided into 8 weeks
where one can practice questions & attempt the assessment tests according to his own
pace. The course offers me a wealth of programming challenges that will help me to
prepare for interviews with top-notch companies like Microsoft, Amazon, Adobe etc.
Technology Learnt
• Learnt Data Structures and Algorithms from basic to an advanced level.
• Learnt Topic-wise implementation of different Data Structures & Algorithms as
follows:
1. Introduction
• Asymptotic Notations
• Analysis of Loops
2. Mathematics
• Finding number of Digits in a Number
• Arithmetic and Geometric Progressions
• Quadratic Equations
• Mean and Median
• Prime Numbers
• LCM and HCF
• Factorials
• Permutation and Combinations Basics
• Modular Arithmetic
3. Bit Magic
• Binary Representation
• Set and Unset
• Toggling
• Bitwise Operators
• Algorithms
4. Recursion
• Recursion Basics
The process in which a function calls itself directly or indirectly is called
recursion and the corresponding function is called as recursive function. Using
recursive algorithm, certain problems can be solved quite easily. Examples of
such problems are Towers of Hanoi (TOH), Inorder/Preorder/Postorder Tree
Traversals, DFS of Graph, etc.
• Basic Problems on Recursion
• Tail Recursion
A recursive function is said to be following Tail Recursion if it invokes itself at
the end of the function. That is, if all of the statements are executed before the
function invokes itself then it is said to be following Tail Recursion.
void printN(int N)
{ if(N==0)
return; else
cout<<N<<" ";
printN(N-1);
}
The above function call for N = 5 will print:
54321
• Explanation of Subset Generation Problem
• Explanation of Josephus Problem
• Explanation of permutations of a string
We iterate from first to last index. For every index i, we swap the i-th character
with the first index. This is how we fix characters at the current first index,
then we recursively generate all permutations beginning with fixed characters
(by parent recursive calls). After we have recursively generated all permutations
with the first character fixed, then we move the first character back to its original
position so that we can get the original string back and fix the next character at
first position.
5. Arrays
• Introduction to Arrays
• Insertion and Deletion in Arrays
• Array Rotation
• Reversing an Array
• Sliding Window Technique
• Prefix Sum Array
• Implementing Arrays in C++ using STL
• Iterators in C++ STL
• Implementing Arrays in Java
• Sample Problems on Array
• XOR Linked List - A Memory Efficient Doubly Linked List | Set 1
6. Searching
• Binary Search Iterative and Recursive
• Binary Search and various associated problems
• Two Pointer Approach Problems
7. Sorting
• Implementation of C++ STL sort() function in Arrays and Vectors
• Sorting in Java
• Arrays.sort() in Java
• Collection.sort() in Java
• Stability in Sorting Algorithms
• Insertion Sort
• Merge Sort
• Quick Sort
• Overview of Sorting Algorithms
8. Matrix
• Introduction to Matrix in C++ and Java
• Multidimensional Matrix
• Pass Matrix as Argument
• Printing matrix in a snake pattern
• Transposing a matrix
• Rotating a Matrix
• Check if the element is present in a row and column-wise sorted matrix.
• Boundary Traversal
• Spiral Traversal
• Matrix Multiplication
• Search in row-wise and column-wise Sorted Matrix
9. Hashing
• Introduction and Time complexity analysis
• Application of Hashing
• Discussion on Direct Address Table
• Working and examples on various Hash Functions
• Introduction and Various techniques on Collision Handling
• Chaining and its implementation
• Open Addressing and its Implementation
• Chaining V/S Open Addressing
• Double Hashing
• C++
• Unordered Set
• Unordered Map
• Java
• HashSet
• HashMap
10. Strings
• Discussion of String DS
• Strings in CPP
• Strings in Java
• Rabin Karp Algorithm
• KMP Algorithm
11. Linked List
• Introduction Implementation in CPP
• Implementation in Java
• Comparison with Array DS
• Doubly Linked List
• Circular Linked List
• Loop Problems
• Detecting Loops
• Detecting loops using Floyd cycle detection
• Detecting and Removing Loops in Linked List
12. Stack
• Understanding the Stack data structure
• Applications of Stack
• Implementation of Stack in Array and Linked List
• In C++
• In Java
13. Queue
• Introduction and Application
• Implementation of the queue using array and LinkedList
• In C++ STL
• In Java
• Stack using queue
14. Deque
• Introduction and Application
• Implementation
• In C++ STL 14
• In Java
• Problems (With Video Solutions)
• Maximums of all subarrays of size k
• ArrayDeque in Java
• Design a DS with min max operations
15. Tree
• Introduction
• Tree
• Application
• Binary Tree • Tree Traversal
• Implementation of:
• Inorder Traversal
• Preorder Traversal
• Postorder Traversal
• Level Order Traversal (Line by Line)
• Tree Traversal in Spiral Form
16. Binary Search Tree
• Background, Introduction and Application
• Implementation of Search in BST
• Insertion in BST
• Deletion in BST
• Floor in BST
• Self Balancing BST
• AVL Tree
17. Heap
• Introduction & Implementation
• Binary Heap
• Insertion
• Heapify and Extract
• Decrease Key, Delete and Build Heap
• Heap Sort
• Priority Queue in C++
• PriorityQueue in Java
18. Graph
• Introduction to Graph
• Graph Representation
• Adjacency Matrix
• Adjacency List in CPP and Java
• Adjacency Matrix VS List
• Breadth-First Search
• Applications
• Depth First Search
• Applications
• Shortest Path in Directed Acyclic Graph
• Prim's Algorithm/Minimum Spanning Tree
• Implementation in CPP
• Implementation in Java
• Dijkstra's Shortest Path Algorithm
• Implementation in CPP 16
• Implementation in Java
• Bellman-Ford Shortest Path Algorithm
• Kosaraju's Algorithm
• Articulation Point
• Bridges in Graph
• Tarjan’s Algorithm
19. Greedy
• Introduction
• Activity Selection Problem
• Fractional Knapsack
• Job Sequencing Problem
20. Backtracking
• Concepts of Backtracking
• Rat In a Maze
• N Queen Problem
21. Dynamic Programming
• Introduction
• Dynamic Programming
• Memoization
• Tabulation
22. Tree
• Introduction
• Representation
• Search
• Insert
• Delete
• Count Distinct Rows in a Binary Matrix
23. Segment Tree
• Introduction
• Construction
• Range Query
• Update Query
24. Disjoint Set
• Introduction
• Find and Union Operations
• Union by Rank
• Path Compression
• Kruskal's Algorithm
1. This course has video lectures of all the topics from which one can easily learn. I
prefer learning from video rather than books and notes. I know books and notes and
thesis have their own significance but still video lecture or face to face lectures make
Problem Overview:
o Sudoku Rules: A standard Sudoku puzzle consists of a 9x9 grid divided into
3x3 sub grids, where some cells are pre-filled with numbers. The objective
is to fill in the remaining cells so that each row, column, and 3x3 sub grid
contains all digits from 1 to 9 without repetition.
o Challenge: Solving Sudoku puzzles involves determining the correct
number for each empty cell based on the constraints provided by the filled
cells. This requires a systematic approach to explore potential solutions
while adhering to Sudoku's rules.
Specific Issues:
o Complexity: As the puzzle size and difficulty increase, the number of
possible configurations grows exponentially, making it challenging to solve
efficiently.
o Validation: Ensuring that each placement adheres to Sudoku rules (no
duplicate numbers in rows, columns, and sub grids) is crucial.
o Efficiency: The solver must be efficient enough to handle various levels of
difficulty within a reasonable time frame.
Problem Analysis
1. Problem Definition:
Sudoku is a popular logic puzzle where the objective is to fill a 9x9 grid with numbers
from 1 to 9 such that each number appears exactly once in each row, column, and 3x3 sub
grid. The challenge is to devise an algorithm that can correctly and efficiently solve these
puzzles, given the initial numbers in some cells.
2. Problem Complexity:
Puzzle Size: The Sudoku grid is 9x9, leading to 81 cells in total. This size can lead
to a significant number of possible configurations.
Difficulty Levels: Sudoku puzzles come in various difficulty levels, from easy to
very hard, which affects the complexity of the solving process. Harder puzzles have
fewer pre-filled numbers, requiring more complex strategies for solving.
Sudoku Rules:
o Each row must contain numbers 1-9, with no repetitions.
o Each column must contain numbers 1-9, with no repetitions.
o Each 3x3 sub grid must contain numbers 1-9, with no repetitions.
o Input: The solver must accept a Sudoku puzzle as input, represented by a
string or grid format, where pre-filled cells are given, and empty cells are
marked (e.g., with a dash).
o Output: The solver should return the completed Sudoku grid that satisfies all
the rules, or indicate if the puzzle is unsolvable.
4. Solution Strategy:
5. Performance Considerations:
Efficiency: The algorithm must handle various puzzle difficulties efficiently. While
backtracking can be computationally intensive, optimizing it with techniques such
as constraint propagation can improve performance.
Scalability: The solution should work for all standard Sudoku puzzles, regardless of
their difficulty.
6. Error Handling:
Invalid Puzzles: The solver should be able to detect and handle cases where the
input puzzle is invalid or unsolvable, providing appropriate feedback to the user.
Software Requirement Analysis
1. Functional Requirements:
Puzzle Input:
o The software must accept a Sudoku puzzle as input, which can be provided
in various formats (e.g., a string of numbers with placeholders for empty
cells or a 9x9 grid).
o The input must be validated to ensure it adheres to the standard Sudoku
rules (correct grid size, valid numbers, etc.).
Puzzle Solving:
o The solver must use an algorithm (e.g., backtracking) to fill in the empty
cells while adhering to Sudoku rules.
o The software should handle different difficulty levels, from easy to very
hard, and provide a solution if one exists.
Solution Output:
o The software should output the solved Sudoku puzzle, displaying the
completed grid.
o It should also indicate if the puzzle is unsolvable or if there are any errors in
the provided input.
User Interaction:
o The software should include a user interface that allows users to input their
puzzles and view the solution.
o It should provide buttons for solving the puzzle and clearing the board,
along with any necessary feedback or error messages.
2. Non-Functional Requirements:
Performance:
o The solver must handle standard Sudoku puzzles efficiently, providing solutions
within a reasonable timeframe.
o The performance should be optimized to handle different levels of puzzle
difficulty.
Usability:
o The user interface should be intuitive and user-friendly, allowing users to
easily input puzzles and understand the results.
o The design should be responsive and accessible, accommodating various
screen sizes and devices.
Reliability:
o The software should be reliable and robust, with minimal risk of crashing or
producing incorrect results.
o It should include error handling to manage invalid input or unsolvable
puzzles gracefully.
Maintainability:
3. Software Requirements:
Platform:
o The software should be compatible with modern web browsers, allowing for
easy deployment and access via a web-based interface.
Technology Stack:
o Frontend: HTML, CSS, JavaScript for the user interface and interaction.
o Backend: JavaScript (in the form of a Node.js environment or similar) for
the puzzle-solving algorithm.
Dependencies:
o The software may require libraries or frameworks for JavaScript to support
features such as event handling and DOM manipulation.
Assumptions:
o The software must work within the limitations of web browsers and
JavaScript performance.
o It should be compatible with the typical range of Sudoku puzzles but may
not handle highly unusual or non-standard variations.
Importance and Applicability
1. Problem-Solving and Educational Value:
Importance: Sudoku is a popular puzzle that enhances logical thinking, pattern
recognition, and problem-solving skills. Developing a Sudoku solver helps in
understanding algorithmic approaches like backtracking, recursion, and
optimization, which are fundamental in computer science and mathematics.
Applicability: This solver can be used as a teaching tool in educational settings to
demonstrate how algorithms can be applied to solve complex problems
systematically.
2. User Convenience and Entertainment:
Importance: Sudoku puzzles are a common pastime, and solving them can be time-
consuming and challenging. This solver provides users with an easy way to
complete puzzles, offering a quick solution when they are stuck or simply wish to
check their answers.
Applicability: The Sudoku solver is applicable to both casual players who need
assistance and enthusiasts who want to verify the correctness of their solutions.
3. Demonstration of Algorithmic Efficiency:
Importance: The project showcases how algorithms can be optimized for efficiency,
particularly in solving constraint satisfaction problems like Sudoku. It highlights
the practical application of backtracking algorithms in real-world scenarios.
Applicability: The algorithm can be adapted for other puzzles or problems that
require similar constraint-solving techniques, making it a versatile tool in software
development and problem-solving contexts.
Key Responsibilities:
I created an intuitive and interactive user interface that allows users to input
Sudoku puzzles and receive solutions. This included writing HTML, CSS, and
JavaScript to build and style the web application.
I ensured the algorithm was optimized for performance, minimizing the time
required to solve puzzles. I also performed thorough testing to verify the
accuracy of the solutions and the reliability of the application.
Skills Applied:
Professional Background:
<html>
<head>
<title></title>
<style type="text/css">
td { border: solid thin; height: 1.4em; width: 1.4em; text-align: center; padding: 0; }
.padd
{padding-bottom: 100px;}
</style>
</head>
<body>
<div id="container">
<table id="sudoku-board">
<colgroup><col><col><col>
<colgroup><col><col><col>
<colgroup><col><col><col>
<tbody>
<tbody>
<tbody>
</table>
<div>
<button id="solve-button">Solve!</button>
</div>
<div>
</div>
</div>
</body>
<script type="text/javascript">
document.getElementById("sudoku-board").addEventListener("keyup", function(event)
{
tdEl.innerText = tdEl.innerText[0];
} else {
tdEl.innerText = "";
});
document.getElementById("solve-button").addEventListener("click", function(event) {
if (solution) {
stringToBoard(solution);
} else {
alert("Invalid board!");
})
document.getElementById("clear-button").addEventListener("click", clearBoard);
function clearBoard() {
tds[i].innerText = "";
function boardToString() {
if (validNum.test(tds[i].innerText[0])) {
string += tds[i].innerText;
} else {
string += "-";
return string;
function stringToBoard(string) {
var currentCell;
currentCell = cells.shift();
if (validNum.test(currentCell)) {
tds[i].innerText = currentCell;
</script>
</html>
"use strict";
function solve(boardString) {
if (boardIsInvalid(boardArray)) {
return false;
return recursiveSolve(boardString);
function solveAndPrint(boardString) {
console.log(toString(solvedBoard.split("")));
return solvedBoard;
function recursiveSolve(boardString) {
if (boardIsSolved(boardArray)) {
return boardArray.join("");
boardArray[nextUnsolvedCellIndex] = possibilities[i];
var solvedBoard = recursiveSolve(boardArray.join(""));
if (solvedBoard) {
return solvedBoard;
return false;
function boardIsInvalid(boardArray) {
return !boardIsValid(boardArray);
function boardIsValid(boardArray) {
function boardIsSolved(boardArray) {
return false;
return true;
}
function getNextCellAndPossibilities(boardArray) {
var choices = ["1", "2", "3", "4", "5", "6", "7", "8", "9"].filter(function (num)
{
});
function getAllIntersections(boardArray, i) {
function allRowsValid(boardArray) {
return [0, 9, 18, 27, 36, 45, 54, 63, 72].map(function (i) {
}, true);
}
function getRow(boardArray, i) {
function allColumnsValid(boardArray) {
}, true);
function getColumn(boardArray, i) {
});
function allBoxesValid(boardArray) {
}, true);
}
function getBox(boardArray, i) {
});
function collectionIsValid(collection) {
if (collection[i] != "-") {
numCounts[collection[i]] = 1;
} else {
return false;
return true;
function toString(boardArray) {
return [0, 9, 18, 27, 36, 45, 54, 63, 72].map(function (i) {
}).join("\n");
if (testable) {
solver = {
solve: solve,
solveAndPrint: solveAndPrint,
recursiveSolve: recursiveSolve,
boardIsInvalid: boardIsInvalid,
boardIsValid: boardIsValid,
boardIsSolved: boardIsSolved,
getNextCellAndPossibilities: getNextCellAndPossibilities,
getAllIntersections: getAllIntersections,
allRowsValid: allRowsValid,
getRow: getRow,
allColumnsValid: allColumnsValid,
getColumn: getColumn,
allBoxesValid: allBoxesValid,
getBox: getBox,
collectionIsValid: collectionIsValid,
toString: toString };
} else {
return solver;
}(TESTABLE);
Learning Outcomes
Programming is all about data structures and algorithms. Data structures are used to hold
data while algorithms are used to solve the problem using that data.
Data structures and algorithms (DSA) goes through solutions to standard problems in
detail and gives you an insight into how efficient it is to use each one of them. It also
teaches you the science of evaluating the efficiency of an algorithm. This enables you to
choose the best of various choices.
For example, you want to search your roll number in 30000 pages of documents, for that
you have choices like Linear search, Binary search, etc.
So, the more efficient way will be Binary search for searching something in a huge number
of data. So, if you know the DSA, you can solve any problem efficiently.
GITHUB LINK :
https://github.com/aravindanaswar/SUDOKO-SOLVER.git
Bibliography
• GeeksforGeeks
• YouTube