Calculate the Cyclomatic Complexity - cyclomatic-complexity

Calculate the CC (Cyclomatic Complexity) of the following code snippets.
I am not sure if I have drawn the Control Flow Graph correctly and furthermore if my calculation for the Cyclomatic Complexity is correct. And as for the formula M = E - N + 2P, the P is defined as "P = number of nodes that have exit points". Am I only counting the return here? How is it then with GCD2, if the method calls itself recursively does this also count as a return?
GCD1
public class GCD1 {
public int gcd(int a, int b) {
if (a < b) {
int t = a;
a = b;
b = t;
}
while (a % b != 0) {
int r = a % b;
a = b;
b = r;
}
return b;
}
}
GCD2
public class GCD2 {
public int gcd(int a, int b) {
if (a < b)
return gcd(b, a);
else if (b == 0)
return a;
else
return gcd(b, a % b);
}
}
Calculation
M = E – N + 2P
where,
E = the number of edges in the control flow graph
N = the number of nodes in the control flow graph
P = number of nodes that have exit points
Control Flow Graph of above GCD1
M = 7 - 6 + 2*1 = 3
Control Flow Graph of above GCD2
M = 8 - 7 + 2*1 = 3

Related

Minimum Cost Path with Left, Right, Bottom and Up moves allowed

Problem Statement:
Given a square grid of size N, each cell of which contains integer cost which represents a cost to traverse through that cell, we need to find a path from top left cell to bottom right cell by which the total cost incurred is minimum.
From the cell (i,j) we can go (i,j-1), (i, j+1), (i-1, j), (i+1, j).
Note: It is assumed that negative cost cycles do not exist in the input matrix.
Below is the code that I have written:
class Coordinate {
int x;
int y;
public Coordinate(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + x;
result = prime * result + y;
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Coordinate other = (Coordinate) obj;
if (x != other.x)
return false;
if (y != other.y)
return false;
return true;
}
}
public class MinCostPath {
public static int minimumCostPath(int[][] grid) {
int R = grid.length;
int C = grid[0].length;
int[][] dist = new int[R][C];
for (int i = 0; i < R; i++) {
for (int j = 0; j < C; j++) {
dist[i][j] = Integer.MAX_VALUE;
}
}
dist[0][0] = grid[0][0];
Queue<Coordinate> q = new LinkedList<>();
q.add(new Coordinate(0, 0));
int[] x = { -1, 1, 0, 0 };
int[] y = { 0, 0, 1, -1 };
while (!q.isEmpty()) {
Coordinate current = q.poll();
for (int i = 0; i < 4; i++) {
int xi = current.getX() + x[i];
int yi = current.getY() + y[i];
if (isSafe(xi, yi, R, C)) {
if (dist[xi][yi] > dist[current.getX()][current.getY()] + grid[xi][yi]) {
dist[xi][yi] = dist[current.getX()][current.getY()] + grid[xi][yi];
Coordinate c = new Coordinate(xi, yi);
if (!q.contains(c))
q.add(c);
}
}
}
}
return dist[R - 1][C - 1];
}
private static boolean isSafe(int xi, int yi, int r, int c) {
return (xi >= 0) && (xi < r) && (yi >= 0) && (yi < c);
}
public static void main(String[] args) {
int[][] grid = { { 9, 4, 9, 9 }, { 6, 7, 6, 4 }, { 8, 3, 3, 7 }, { 7, 4, 9, 10 } };
System.out.println(minimumCostPath(grid));
}
}
It gives 'Runtime Error:Time Limit Exceeded' Error
Below is an article from geeksforgeeks that has the solution.
Minimum Cost Path Problem
What I am not able to understand is why my code is giving 'Time Limit Exceeded' Error while the solution mentioned in the article is working. To my understanding, both the solutions are doing exactly the same thing.
Please help me understand the difference and what optimization is needed in the code that I have written. Thanks in Advance.
It seems from your implementation that you are trying to use Breadth First Search instead of Dijkstra which is the right approach to solve this.
You need to use a priority queue and a map to trace your path.
Also for BFS typically you don't need to do if (! q.contains(node)) that actually unnecessarily consumes time.
what optimization is needed in the code
The problem needs to be reformulated so you can apply the Dijkstra algorithm ( https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm )
That algorithm assumes the links are costed, rather than the nodes ( cells ). Consider two adjacent cells with traversal costs c and d. Travelling from the first to the second adds cost d. Travelling from the second to the first adds cost c. So you can connect the two cells with two unidirectional links of cost c and d. The Dijkstra algorithm will give you the correct cost when the entire path is travelled, minus the the traversal cost of the first cell - which is a constant and can therefor be ignored when finding the optimal path.
I use the boost graph implementation of Dijkstra, which is fast and well tested ( https://www.boost.org/doc/libs/1_76_0/libs/graph/doc/dijkstra_shortest_paths.html ). The API is a challenge if you haven't used the boost library before, so I use a C++ style wrapper to simplify coding ( https://github.com/JamesBremner/PathFinder )
Here is the output from PathFinder on the sample problem you posted
C:\Users\James\code\PathFinder\bin>mazes ..\dat\vivekkumar.txt
Mazes
cellcosts
s9 4 9 9
6 7 6 4
8 3 3 7
7 4 9 e10
4 by 4
0 -> 1 -> 5 -> 9 -> 10 -> 11 -> 15 ->
+---+---+---+---+
| s * |
+ + + + +
| * |
+ + + + +
| * * * |
+ + + + +
| e |
+---+---+---+---+

Clarification of Answer... find the max possible two equal sum in a SET

I need a clarification of the answer of this question but I can not comment (not enough rep) so I ask a new question. Hope it is ok.
The problem is this:
Given an array, you have to find the max possible two equal sum, you
can exclude elements.
i.e 1,2,3,4,6 is given array we can have max two equal sum as 6+2 =
4+3+1
i.e 4,10,18, 22, we can get two equal sum as 18+4 = 22
what would be your approach to solve this problem apart from brute
force to find all computation and checking two possible equal sum?
edit 1: max no of array elements are N <= 50 and each element can be
up to 1<= K <=1000
edit 2: Total elements sum cannot be greater than 1000.
The approved answer says:
I suggest solving this using DP where instead of tracking A,B (the
size of the two sets), you instead track A+B,A-B (the sum and
difference of the two sets).
Then for each element in the array, try adding it to A, or B, or
neither.
The advantage of tracking the sum/difference is that you only need to
keep track of a single value for each difference, namely the largest
value of the sum you have seen for this difference.
What I do not undertand is:
If this was the subset sum problem I could solve it with DP, having a memoization matrix of (N x P), where N is the size of the set and P is the target sum...
But I can not figure it out how I should keep track A+B,A-B (as said for the author of the approved answer). Which should be the dimensions of the memoization matrix ? and how that helps to solve the problem ?
The author of the answer was kind enough to provide a code example but it is hard to me to undertand since I do not know python (I know java).
I think thinking how this solution relates to the single subset problem might be misleading for you. Here we are concerned with a maximum achievable sum, and what's more, we need to distinguish between two disjoint sets of numbers as we traverse. Clearly tracking specific combinations would be too expensive.
Looking at the difference between sets A and B, we can say:
A - B = d
A = d + B
Clearly, we want the highest sum when d = 0. How do we know that sum? It's (A + B) / 2!
For the transition in the dynamic program, we'd like to know if it's better to place the current element in A, B or neither. This is achieved like this:
e <- current element
d <- difference between A and B
(1) add e to A -> d + e
why?
A = d + B
(A + e) = d + e + B
(2) add e to B -> d - e
why?
A = d + B
A = d - e + (B + e)
(3) don't use e -> that's simply
what we already have stored for d
Let's look at Peter de Rivas' code for the transition:
# update a copy of our map, so
# we can reference previous values,
# while assigning new values
D2=D.copy()
# d is A - B
# s is A + B
for d,s in D.items():
# a new sum that includes element a
# we haven't decided if a
# will be in A or B
s2 = s + a
# d2 will take on each value here
# in turn, once d - a (adding a to B),
# and once d + a (adding a to A)
for d2 in [d-a, d+a]:
# The main transition:
# the two new differences,
# (d-a) and (d+a) as keys in
# our map get the highest sum
# seen so far, either (1) the
# new sum, s2, or (2) what we
# already stored (meaning `a`
# will be excluded here)
# so all three possibilities
# are covered.
D2[abs(d2)] = max(D2[abs(d2)], s2)
In the end we have stored the highest A + B seen for d = 0, where the elements in A and B form disjoint sets. Return (A + B) / 2.
Try this dp approch : it works fine.
/*
*
i/p ::
1
5
1 2 3 4 6
o/p : 8
1
4
4 10 18 22
o/p : 22
1
4
4 118 22 3
o/p : 0
*/
import java.util.Scanner;
public class TwoPipesOfMaxEqualLength {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int t = sc.nextInt();
while (t-- > 0) {
int n = sc.nextInt();
int[] arr = new int[n + 1];
for (int i = 1; i <= n; i++) {
arr[i] = sc.nextInt();
}
MaxLength(arr, n);
}
}
private static void MaxLength(int[] arr, int n) {
int dp[][] = new int[1005][1005];
int dp1[][] = new int[1005][1005];
// initialize dp with values as 0.
for (int i = 0; i <= 1000; i++) {
for (int j = 0; j <= 1000; j++)
dp[i][j] = 0;
}
// make (0,0) as 1.
dp[0][0] = 1;
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= 1000; j++) {
for (int k = 0; k <= 1000; k++) {
if (j >= arr[i]) {
if (dp[j - arr[i]][k] == 1) {
dp1[j][k] = 1;## Heading ##
}
}
if (k >= arr[i]) {
if (dp[j][k - arr[i]] == 1) {
dp1[j][k] = 1;
}
}
if (dp[j][k] == 1) {
dp1[j][k] = 1;
}
}
}
for (int j = 0; j <= 1000; j++) {
for (int k = 0; k <= 1000; k++) {
dp[j][k] = dp1[j][k];
dp1[j][k] = 0;
}
}
}
int ans = 0;
for (int i = 1; i <= 1000; i++) {
if (dp[i][i] == 1) {
ans = i;
}
}
System.out.println(ans);
}
}
#include <bits/stdc++.h>
using namespace std;
/*
Brute force recursive solve.
*/
void solve(vector<int>&arr, int &ans, int p1, int p2, int idx, int mx_p){
// if p1 == p2, we have a potential answer
if(p1 == p2){
ans = max(ans, p1);
}
//base case 1:
if((p1>mx_p) || (p2>mx_p) || (idx >= arr.size())){
return;
}
// leave the current element
solve(arr, ans, p1, p2, idx+1, mx_p);
// add the current element to p1
solve(arr, ans, p1+arr[idx], p2, idx+1, mx_p);
// add the current element to p2
solve(arr, ans, p1, p2+arr[idx], idx+1, mx_p);
}
/*
Recursive solve with memoization.
*/
int solve(vector<vector<vector<int>>>&memo, vector<int>&arr,
int p1, int p2, int idx, int mx_p){
//base case 1:
if((p1>mx_p) || (p2>mx_p) || (idx>arr.size())){
return -1;
}
// memo'ed answer
if(memo[p1][p2][idx]>-1){
return memo[p1][p2][idx];
}
// if p1 == p2, we have a potential answer
if(p1 == p2){
memo[p1][p2][idx] = max(memo[p1][p2][idx], p1);
}
// leave the current element
memo[p1][p2][idx] = max(memo[p1][p2][idx], solve(memo, arr, p1, p2,
idx+1, mx_p));
// add the current element to p1
memo[p1][p2][idx] = max(memo[p1][p2][idx],
solve(memo, arr, p1+arr[idx], p2, idx+1, mx_p));
// add the current element to p2
memo[p1][p2][idx] = max(memo[p1][p2][idx],
solve(memo, arr, p1, p2+arr[idx], idx+1, mx_p));
return memo[p1][p2][idx];
}
int main(){
vector<int>arr = {1, 2, 3, 4, 7};
int ans = 0;
int mx_p = 0;
for(auto i:arr){
mx_p += i;
}
mx_p /= 2;
vector<vector<vector<int>>>memo(mx_p+1, vector<vector<int>>(mx_p+1,
vector<int>(arr.size()+1,-1)));
ans = solve(memo, arr, 0, 0, 0, mx_p);
ans = (ans>=0)?ans:0;
// solve(arr, ans, 0, 0, 0, mx_p);
cout << ans << endl;
return 0;
}

What is the time complexity of the right to left method in modular exponentiation?

http://en.wikipedia.org/wiki/Modular_exponentiation#Right-to-left_binary_method
What is the time complexity of the right to left method in modular exponentiation?
is it O(1) because we are going through the binary representation of e which is constant time?
int mod(int b, int e, int m) {
b = b % m;
int result = 1;
while (e) {
if (e % 2 == 1) {
result = (result * b) % m;
}
b = (b * b) % m;
e >>= 1;
}
return result;
}

Better algorithm for finding solutions to "a + b = c + d"

So lets abcd is a number between 1000 and 9999 and a,b,c,d are it's digits.
So find the number, where a+b=c+d. There is one solution down with four loops, but i need
a solution with three loops.
for (int a = 1; a <= 9; a++)
{
for (int b = 0; b <= 9; b++)
{
for (int c = 0; c <= 9; c++)
{
for (int d = 0; d <= 9; d++)
{
if ((a + b) == (c + d))
{
Console.WriteLine(" " + a + " " + b + " " + c + " " + d);
}
}
}
}
}
If someone asked you to solve the x + 1 == 2 equation, would you actually attempt to loop over all possible values of x to see which one fits? I hope not. You will probably figure out that the equation permits an immediate direct analytical solution x = 2 - 1 = 1.
The same logic applies to your case. Once you know a, b and c, your a + b == c + d equation permits a direct solution for d: d = a + b - c. There's no need to iterate over d just like there's no need to iterate over x in x + 1 == 2.
The first 3 loops establish values for a, b, and c. Knowing this and your equation just compute what d needs to be in order for your equation to hold true. Then check that the number computed for d is valid.
for (int a = 1; a <= 9; a++)
{
for (int b = 0; b <= 9; b++)
{
for (int c = 0; c <= 9; c++)
{
d = a + b - c;
if (d <= 9 && d >= 0)
{
Console.WriteLine(" " + a + " " + b + " " + c + " " + d);
}
}
}
}
What you have a special case of 4SUM that can be solved via one of the ways to quadratically solve 3SUM, making it O(N^2). Although it requires some use of data structures.
The first thing to note is since you are looking for A + B = C + D, What you really want to do is find a list of pairs of numbers that add up to some number S.
You can simply this by having a map/dict where the key is the sum and it maps to an list of pairs that equal that sum. The result is:
S = [(a,b),(c,d),(e,f),...] for a number of values of S
Which is equivalent to saying:
a + b = c + d = e + f = ... = S for a number of values of S
You then simply go through each sum and remove the ones where there is only a single element in the list.
I'm thinking you can then break go through the combinations of pairs obtaining things like a + b = c + d and c + d = e + f, at a cost of an additional O(N^2) as long as there are no duplicates due to limits on how many ways you can obtain a sum. Although, I might be wrong and it takes O(N^3) to list the solution in that form.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace test
{
class Program
{
static void Main(string[] args)
{
var number = Enumerable.Range(1000, 9000);
var list = from y in number
let a = y / 1000
let b = (y - 1000 * a) / 100
let c = (y - 1000 * a - 100 * b) / 10
let d = (y - 1000 * a - 100 * b - 10 * c)
where a + b == c + d
select y;
foreach (var item in list)
{
Console.WriteLine(item);
}
Console.Read();
}
}
}
String s1;
Set<String> s=new TreeSet();
for( int i=1;i<10;i++)
{
s1=null;
s1=""+i;
for(int j=0;j<10;j++)
{
String tempj=s1;
s1=s1+j;
for(int k=0;k<10;k++)
{
String tempk=s1;
s1=s1+k;
int temp=i+j-k;
s1=s1+temp;
if(temp<10)
s.add(s1);
s1=tempk;
}
s1=tempj;
}
}
for(String i:s )
System.out.println(i+);
----------------------------------------------------------------EDIT 1------------------
import java.util.*;
public class HelloWorld{
public static void main(String []args){
String happyNumber;
Set<String> numberSet=new TreeSet();
for( int i=1;i<10;i++)
{
happyNumber=null; //Every 1st loop will give a new number so old one has to be deleted
happyNumber=""+i; //Adding the number in 1st place (place value will be i*10000)
for(int j=0;j<10;j++) //Loop for putting nmber in 1000th place
{
String tempj=happyNumber; //taking happyNumber( only one digit fixed till now) into a temp variable to permutate on other places
happyNumber=happyNumber+j; //Attaching another number after this we have (AB)
for(int k=0;k<10;k++) //permutating with value of c and calculating d
{
String tempk=happyNumber;
happyNumber=happyNumber+k; //Attaching variable for 3rd place (c)
int temp=i+j-k; //calculating value of d
if(temp<10) //checking whether we have right value for d
{
happyNumber=happyNumber+temp;
numberSet.add(happyNumber);
}
happyNumber=tempk; //bringing number back to its previous state for more combination
}
happyNumber=tempj; //bringing number back to its previous state for more combination
}
}
for(String i:numberSet )
System.out.println(i);
}
}

base b expansion of n algorithm

im reading about base b expansion of n algorithm and this book is really hard to read and understand, i am not sure what the bottom part means...
does it return n or what ? how would you do this...thanks
some method (n,b)
if b == 0
return 1
q = n
k = 0
while q does not == 0
a[k] = q % b
q = q / b
k = k + 1
return ???
I wrote an implementation in C for the function. It uses a pointer as input parameter, where the output (a vector of integers) will be placed. The function also returns an integer - the logical size of the vector.
#include <assert.h>
int toBase(int n, int b, int* answer) {
assert(b > 1);
q = n
k = 0
while (q != 0) {
answer[k] = q % b;
q /= b;
++k;
}
return k;
}
int main() {
int answer[32];
int n = 100000;
int b = 2;
int answerSize = toBase(n, b, answer);
// use answer and answerSize
return 0;
}
Another way to do it (without the pointer parameter) is to allocate memory for the vector inside the function and return it, requiring the calling function to release the used memory after it has finished processing it.
In this case, you can't tell the logical size of the vector, so you have to set answer[k] to a special value (-1 here), to know where the vector ends.
#include <assert.h>
int* toBase(int n, int b) {
assert(b > 1);
int* answer = malloc(33 * sizeof(int));
q = n
k = 0
while (q != 0) {
answer[k] = q % b;
q /= b;
++k;
}
answer[k] = -1;
return answer;
}
int main() {
int n = 100000;
int b = 2;
int *answer = toBase(n, b);
// use answer
free(answer);
return 0;
}
A more elegant solution (in C++) is to use the STL vector class.
The idea behind this algorithm is that it's creating a list of values ak, ak-1, ak-2, ..., a0. At the very end, it wants to return that list of values and do so in a form that looks like the base-b representation of the number.
For example, if you input 33 into this algorithm and ask for its base-16 representation, the algorithm will set a1 = 2 and a0 = 1. The return value of the algorithm is then the representation 21, which is a1 (2) followed by a0 (1).
The notation they're using is just fancy mathspeak for "return the list of values produced by this algorithm." You can think of it as returning an array of the base-b digits of the number.
Hope this helps!

Resources