diff --git a/README.md b/README.md index 3661c43..c2746da 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ [![Code Health](https://landscape.io/github/HackersUOP/codeBase/master/landscape.svg?style=flat)](https://landscape.io/github/HackersUOP/codeBase/master) # codeBase -This repository is to store useful algorithms which are used frequently and to study them +This repository is to store useful algorithms which are used frequently and to study them. + +# Google Group + +All information regarding the programming related activities of the deaprtment are archived in [https://groups.google.com/forum/#!forum/cepdnaclk](https://groups.google.com/forum/#!forum/cepdnaclk) diff --git a/codeBase/ACES_Coders/v7.0/coders/RichestDay.py b/codeBase/ACES_Coders/v7.0/coders/RichestDay.py new file mode 100644 index 0000000..8cc4dac --- /dev/null +++ b/codeBase/ACES_Coders/v7.0/coders/RichestDay.py @@ -0,0 +1,20 @@ +''' + gihanjayatilaka[at]eng[dot]pdn[dot]ac[dot]lk 16/02/2020 +''' +P=int(input()) + +diff=[0]*(100000+1) + +for _ in range(P): + m,s,e=map(int,input().strip().split()) + + diff[s]+=m + diff[e+1]-=m + +pay=[0]*len(diff) + +pay[0]=diff[0] +for i in range(1,len(pay)): + pay[i]=pay[i-1]+diff[i] + +print(max(pay)) diff --git a/codeBase/ACES_Coders/v8.0/coders/A-Mysterious-Bot/Readme.md b/codeBase/ACES_Coders/v8.0/coders/A-Mysterious-Bot/Readme.md new file mode 100644 index 0000000..d79bab9 --- /dev/null +++ b/codeBase/ACES_Coders/v8.0/coders/A-Mysterious-Bot/Readme.md @@ -0,0 +1 @@ +The solution will be added later. Please contact sanoj.punchihewa[at]eng[dot]pdn[dot]ac[dot]lk for support. \ No newline at end of file diff --git a/codeBase/ACES_Coders/v8.0/coders/A-walk-to-remember/Solution.py b/codeBase/ACES_Coders/v8.0/coders/A-walk-to-remember/Solution.py new file mode 100644 index 0000000..95e7b82 --- /dev/null +++ b/codeBase/ACES_Coders/v8.0/coders/A-walk-to-remember/Solution.py @@ -0,0 +1,23 @@ +''' + This solution was submitted by Team: eyeCoders_UOP + during ACES Coders v8 2020 + Team lead: Rusiru Thushara thusharakart@gmail.com + + The solution runs in O(n) +''' +def getline():return [float(x) for x in input().strip().split(' ')] +c,e,n,s0 = getline() +arr, lst = [], [] +m = c/s0 +for i in range(int(n)): + x,s = getline() + arr.append((x,s)) + if x=0: + m = max(m,(c-x)/s) + elif s<0: + lst.append((x,s)) +count = 0 +for x,s in lst: + if x+s*m <= c: + count+=1 +print(round(m),count) diff --git a/codeBase/ACES_Coders/v8.0/coders/Basketball-tryouts/Readme.md b/codeBase/ACES_Coders/v8.0/coders/Basketball-tryouts/Readme.md new file mode 100644 index 0000000..a6fdf06 --- /dev/null +++ b/codeBase/ACES_Coders/v8.0/coders/Basketball-tryouts/Readme.md @@ -0,0 +1,13 @@ +# Basketball Tryouts - Solution + +The constraints of the problem are, +N < 500000 +D < 1000000 + +For a solution to work in under 2 sec for C / 4 sec for JAVA or 10 sec for python, the solution ought to be of time complexity O(N log(N)) at worst. + +No team scored full marks for this question during the competition. But several users have scored full marks while upsolving the problem after the competition ended. These solutions are of order O(N^2). Apparently, it is possible to get full marks for this question even with an O(N^2) solution with several clever tweaks. + +O(N log(N)) Solution: Solution.cpp +O(N^2) solutions : Solution_dtdinidu7.py , Solution_InterGreat_UOP.py + diff --git a/codeBase/ACES_Coders/v8.0/coders/Basketball-tryouts/Solution.cpp b/codeBase/ACES_Coders/v8.0/coders/Basketball-tryouts/Solution.cpp new file mode 100644 index 0000000..be1159f --- /dev/null +++ b/codeBase/ACES_Coders/v8.0/coders/Basketball-tryouts/Solution.cpp @@ -0,0 +1,148 @@ +#include +#include + +#include +#include +#include +using namespace std; + + +bool DEBUG= false; + +vector > normalize(vector > v) { + vector > ret; + sort(v.begin(), v.end()); + for (int i = 0; i < v.size(); i++) { + while (ret.size() && ret.back().first <= v[i].first && + ret.back().second <= v[i].second) { + ret.pop_back(); + } + ret.push_back(v[i]); + } + return ret; +} + +vector > rev(vector > v) { + reverse(v.begin(), v.end()); + for (int i = 0; i < v.size(); i++) v[i].first = -v[i].first; + for (int i = 0; i < v.size(); i++) v[i].second = -v[i].second; + return v; +} + +long long solve(const vector >& a, int ai1, int ai2, + const vector >& b, int bi1, int bi2, + bool swapped) { + if (ai2-ai1 <= 50 || bi2-bi1 <= 50) { + long long ret = 0; + for (int i = ai1; i < ai2; i++) + for (int j = bi1; j < bi2; j++) { + if (swapped) { + ret = max(ret, (long long)min(0, b[j].first-a[i].first) * + (b[j].second-a[i].second)); + } else { + ret = max(ret, (long long)max(0, b[j].first-a[i].first) * + (b[j].second-a[i].second)); + } + } + return ret; + } + + vector > b1, b2; + int i = (ai2+ai1)/2; + for (int j = bi1; j+1 < bi2; j += 2) { + long long v1 = (long long)(b[j].first-a[i].first) * + (b[j].second-a[i].second); + long long v2 = (long long)(b[j+1].first-a[i].first) * + (b[j+1].second-a[i].second); + if (v1 < v2) { + b1.push_back(b[j]); b1.push_back(b[j+1]); b2.push_back(b[j+1]); + } else { + b1.push_back(b[j]); b2.push_back(b[j]); b2.push_back(b[j+1]); + } + } + if ((bi2-bi1)%2) { b1.push_back(b[bi2-1]); b2.push_back(b[bi2-1]); } + + return max(solve(b1, 0, b1.size(), a, ai1, i, !swapped), + solve(b2, 0, b2.size(), a, i, ai2, !swapped)); +} + +int main() { + int N, D; + scanf("%d %d",&N,&D); + +// vector > A, C; + + int ar_st[N]; + int ar_en[N]; + char ar_type[N]; + int ar_score[N]; + + int countA=0,countB=0,countC=0; + + long ansA,ansB=0,ansC=0; + + int n=0; + for(n=0;n > A(countA), C(countC); + countA=0,countB=0,countC=0; + for(n=0;n maxi: + maxi = val + return maxi + +N, D = list(map(int, input().split())) +A = defaultdict() +C = defaultdict() +sA = 0 +sC = 0 +sB = 0 +numA = -1 +numC = -1 +for t in range(N): + t1, t2, t3, t4 = input().split() + t1 = int(t1) + t2 = int(t2) + t4 = int(t4) + if t3 == "A": + numA += 1 + if (t4 not in A) or A[t4] < t2: + A[t4] = t2 + sA += (t4 * t2) + elif t3 == "B": + sB += (t2 - t1 + 1) * t4 + else: + numC += 1 + if (t4 not in C) or C[t4] > t1: + C[t4] = t1 + sC += (t2 - t1 + 1) * t4 +unpaired = sA + sB + sC +As = A +Cs = C +# As = sorted(A.keys(), reverse = True) +# Cs = sorted(C.keys()) +paired = pair() +print(str(unpaired) + " " + str(unpaired + paired)) diff --git a/codeBase/ACES_Coders/v8.0/coders/Basketball-tryouts/Solution_dtdinidu7.py b/codeBase/ACES_Coders/v8.0/coders/Basketball-tryouts/Solution_dtdinidu7.py new file mode 100644 index 0000000..2ba0285 --- /dev/null +++ b/codeBase/ACES_Coders/v8.0/coders/Basketball-tryouts/Solution_dtdinidu7.py @@ -0,0 +1,38 @@ +n, d = [int(i) for i in input().split()] + +A = {} +C = {} + +shoots = 0 + +def rangeD(e1, s2, e2): + tmp = min(e1, e2) - s2+1 + return(tmp if tmp >= 0 else -1) + +for _ in range(n): + s, e, t, num = [i for i in input().split()] + s, e, num = int(s), int(e), int(num) + shoots += (e-s+1)*num + if (t == "A"): + if num in A: + A[num] = max(A[num], e) + else: + A[num] = e + elif (t == "C"): + if num in C: + C[num] = min(C[num], s) + else: + C[num] = s + +print(shoots, end = ' ') + +maxVal = 0 + +for a in A: + for c in C: + if (a > c): + tmp = rangeD(A[a], C[c], d) + if not tmp == -1: + maxVal = max(maxVal, tmp*(a-c)) + +print(shoots+maxVal) diff --git a/codeBase/ACES_Coders/v8.0/coders/Dunder-Mifflin/Readme.md b/codeBase/ACES_Coders/v8.0/coders/Dunder-Mifflin/Readme.md new file mode 100644 index 0000000..74304bc --- /dev/null +++ b/codeBase/ACES_Coders/v8.0/coders/Dunder-Mifflin/Readme.md @@ -0,0 +1 @@ +The solution will be added later. Please contact hishan.indrajith.adikari[at]eng[dot]pdn[dot]ac[dot]lk for support. \ No newline at end of file diff --git a/codeBase/ACES_Coders/v8.0/coders/Essence-scanner/sol.py b/codeBase/ACES_Coders/v8.0/coders/Essence-scanner/sol.py new file mode 100644 index 0000000..399cb75 --- /dev/null +++ b/codeBase/ACES_Coders/v8.0/coders/Essence-scanner/sol.py @@ -0,0 +1,87 @@ +# Problem setter's code +# Author : harshana.w@eng.pdn.ac.lk +def f(X,Y,M,_x,_y): + ret = 0 + for i in range(len(X)): + d = (X[i]-_x)**2 + (Y[i]-_y)**2 + d = d**0.5 + ret += d*M[i] + return ret + +def geometricMedian(x, y, m): + n = len(x) + + # start assumption from Center of Mass + _x,_y = 0, 0 + for i in range(n): + _x += x[i] * m[i] + _y += y[i] * m[i] + _x,_y = _x/sum(m),_y/sum(m) + opt_d = f(x,y,m,_x,_y) + + + for i in range(n): + newd = f(x,y, m, x[i],y[i]) + if (newd < opt_d): + opt_d = newd + _x = x[i] + _y = y[i] + + test_distance = 10**5 + + test_x = [-1,0,1,0] + test_y = [0,1,0,-1] + delta = 10**100 + while (test_distance > lower_limit and delta > 1e-7): + + flag = 0 + for i in range(4): + newx = _x + test_distance * test_x[i] + newy = _y + test_distance * test_y[i] + newd = f(x,y,m, newx,newy) + if (newd < opt_d): + delta = opt_d - newd + opt_d = newd + _x = newx + _y = newy + # print("new loc {:.6f} {:.6f} d={:.6f} delta={:8f} testd={:.8f}".format(_x,_y,opt_d,delta,test_distance)) + flag = 1 + break + if (flag == 0): + test_distance /= 2 + return _x,_y + +lower_limit = 1e-5 +N,M = map(int,input().split()) +Xs,Ys = [],[] +ms = [] +for i in range(N): + x,y,m = map(int,input().split()) + Xs.append(x) + Ys.append(y) + ms.append(m) + + +xC,yC = geometricMedian(Xs, Ys, ms) + +_x,_y = 0, 0 +for i in range(len(Xs)): + _x += Xs[i] * ms[i] + _y += Ys[i] * ms[i] +_x,_y = _x/sum(ms),_y/sum(ms) + + +Xs.append(0) +Ys.append(0) +ms.append(M) +xH,yH = geometricMedian(Xs, Ys, ms) + +_x,_y = 0, 0 +for i in range(len(Xs)): + _x += Xs[i] * ms[i] + _y += Ys[i] * ms[i] +_x,_y = _x/sum(ms),_y/sum(ms) + + +print("{} {}".format(round(xC),round(yC))) +print("{} {}".format(round(xH),round(yH))) diff --git a/codeBase/ACES_Coders/v8.0/coders/Game-of-life/Readme.md b/codeBase/ACES_Coders/v8.0/coders/Game-of-life/Readme.md new file mode 100644 index 0000000..92bc416 --- /dev/null +++ b/codeBase/ACES_Coders/v8.0/coders/Game-of-life/Readme.md @@ -0,0 +1 @@ +The solution will be added later. Please contact suren.sri[at]eng[dot]pdn[dot]ac[dot]lk for support. \ No newline at end of file diff --git a/codeBase/ACES_Coders/v8.0/coders/Gift-pack/Readme.md b/codeBase/ACES_Coders/v8.0/coders/Gift-pack/Readme.md new file mode 100644 index 0000000..92bc416 --- /dev/null +++ b/codeBase/ACES_Coders/v8.0/coders/Gift-pack/Readme.md @@ -0,0 +1 @@ +The solution will be added later. Please contact suren.sri[at]eng[dot]pdn[dot]ac[dot]lk for support. \ No newline at end of file diff --git a/codeBase/ACES_Coders/v8.0/coders/Interfering-Base-Stations/Readme.md b/codeBase/ACES_Coders/v8.0/coders/Interfering-Base-Stations/Readme.md new file mode 100644 index 0000000..92bc416 --- /dev/null +++ b/codeBase/ACES_Coders/v8.0/coders/Interfering-Base-Stations/Readme.md @@ -0,0 +1 @@ +The solution will be added later. Please contact suren.sri[at]eng[dot]pdn[dot]ac[dot]lk for support. \ No newline at end of file diff --git a/codeBase/ACES_Coders/v8.0/coders/Love-letters/solution.py b/codeBase/ACES_Coders/v8.0/coders/Love-letters/solution.py new file mode 100644 index 0000000..bbb38b2 --- /dev/null +++ b/codeBase/ACES_Coders/v8.0/coders/Love-letters/solution.py @@ -0,0 +1,94 @@ +# Written by: Dhanushki Mapitigama +# pavithya.mapitigama@eng.pdn.ac.lk + + +# In here we are using Aho corasick algorithm for the fully optimized solution. + +FAIL = -1 + +keywords = [] + +S, N = (int(val) for val in str(input()).split()) + + +for i in range (S): + w = input() + word = w.rstrip() + word = word.lower() + keywords.append(word) + + +# creating the Trie dictionary by adding given words + +transitions = {} +outputs = {} +fails = {} + +new_state = 0 + +for keyword in keywords: + state = 0 + + for j, char in enumerate(keyword): + res = transitions.get((state, char), FAIL) + if res == FAIL: + break + state = res + + for char in keyword[j:]: + new_state += 1 + transitions[(state, char)] = new_state + state = new_state + + outputs[state] = [keyword] + +queue = [] + +for (from_state, char), to_state in transitions.items(): + if from_state == 0 and to_state != 0: + queue.append(to_state) + fails[to_state] = 0 + +while queue: + r = queue.pop(0) + for (from_state, char), to_state in transitions.items(): + if from_state == r: + queue.append(to_state) + state = fails[from_state] + + while True: + res = transitions.get((state, char), state and FAIL) + if res != FAIL: + break + state = fails[state] + + failure = transitions.get((state, char), state and FAIL) + fails[to_state] = failure + outputs.setdefault(to_state, []).extend( + outputs.get(failure, [])) + + + +# Taking letters one by one and check with the created dictionary + +for j in range (N): + root = [] + letter = input().rstrip() + state = 0 + results = [] + for i, char in enumerate(letter.lower()): + while True: + res = transitions.get((state, char), state and FAIL) + if res != FAIL: + state = res + break + state = fails[state] + + for match in outputs.get(state, ()): + pos = i - len(match) + 1 + results.append(match) + + root = results + + if len(root): + print(str(j)+ " " + str(len(root))) diff --git a/codeBase/ACES_Coders/v8.0/coders/Prime-Nim-game/Readme.md b/codeBase/ACES_Coders/v8.0/coders/Prime-Nim-game/Readme.md new file mode 100644 index 0000000..92bc416 --- /dev/null +++ b/codeBase/ACES_Coders/v8.0/coders/Prime-Nim-game/Readme.md @@ -0,0 +1 @@ +The solution will be added later. Please contact suren.sri[at]eng[dot]pdn[dot]ac[dot]lk for support. \ No newline at end of file diff --git a/codeBase/ACES_Coders/v8.0/coders/Project-groups/Solution.java b/codeBase/ACES_Coders/v8.0/coders/Project-groups/Solution.java new file mode 100644 index 0000000..1f75d81 --- /dev/null +++ b/codeBase/ACES_Coders/v8.0/coders/Project-groups/Solution.java @@ -0,0 +1,149 @@ +/* + Problem setter's code. + gihanjayatilaka[at]eng[dot]pdn[dot]ac[dot]lk + 2020-02-27 + + The time complexity is O(N^2 log(N)) + The memory complexity is O(N) +*/ + +import java.lang.reflect.Array; +import java.util.Arrays; +import java.util.Scanner; + +public class Solution { + static boolean DEBUG=false; + static Scanner sc=new Scanner(System.in); + public static void main(String[] args) { + String[] temp=sc.nextLine().trim().split(" "); + + int N=Integer.parseInt(temp[0]); + int D=Integer.parseInt(temp[1]); + float DD=(float)D; + + float[][] theta12=new float[N][2]; + double[][] xyf=new double[N][2]; + + + + + for(int n=0;n=2){ + ans+=(currCount*(currCount-1))/2; + if(DEBUG){ + System.out.println("FOUND!"+ ans); + } + } + currCount=1; + curr=ar[ss]; + } + + if(DEBUG){ + System.out.println(curr+" "+ar[ss]+" "+currCount); + } + } + } + if(DEBUG){ + System.out.println("ANSWER: "+ans); + } + + return ans; + } +} diff --git a/codeBase/ACES_Coders/v8.0/coders/Project-groups/Solution2.cpp b/codeBase/ACES_Coders/v8.0/coders/Project-groups/Solution2.cpp new file mode 100644 index 0000000..a40179a --- /dev/null +++ b/codeBase/ACES_Coders/v8.0/coders/Project-groups/Solution2.cpp @@ -0,0 +1,106 @@ +/* + This is a solution posted by the hackerrank user : https://www.hackerrank.com/Mevan_Niluminda after the competition. + The solution achieved 100% marks. + + Time complexity: O(N^2) + Space complexity: O(D^2) + + +*/ +#include +using namespace std; +struct point_t +{ + int x; + int y; +}; + +unsigned int squared_distance(const point_t &p1, const point_t &p2) +{ + int a = p2.x - p1.x; + int b = p2.y - p1.y; + return a*a + b*b; +} +void vec_print(int num[],int N){ + for(int i=0;i>N>>D; + map > d; + vector names; + for(int i=0;i>ty>>number; + names.push_back(ty); + d[ty].first = number; + } + for(int i=0;i>ty>>number; + d[ty].second = number; + } + + vector points; + for ( int j=0;j0){ + nb_triangles = nb_triangles + ((distances[dis[i]]*(distances[dis[i]]-1))>>1); + distances[dis[i]] = 0; + } + + // cout< P: + final_ans.append(tmp_i[k]) + if tmp[k] < 0.5: + zeros += 1 +final_ans.sort() + +print(" ".join(map(str, final_ans)).strip()) diff --git a/codeBase/ACES_Coders/v8.0/coders/Stop-the-Fire/sol.py b/codeBase/ACES_Coders/v8.0/coders/Stop-the-Fire/sol.py new file mode 100644 index 0000000..71e9b56 --- /dev/null +++ b/codeBase/ACES_Coders/v8.0/coders/Stop-the-Fire/sol.py @@ -0,0 +1,187 @@ +# Python program to find articulation points in an undirected graph + +from collections import defaultdict +import math +#This class represents an undirected graph +#using adjacency list representation +class Graph: + + def __init__(self,vertices): + self.V= vertices #No. of vertices + self.graph = defaultdict(list) # default dictionary to store graph + self.Time = 0 + + # function to add an edge to graph + def addEdge(self,u,v): + self.graph[u].append(v) + self.graph[v].append(u) + + '''A recursive function that find articulation points + using DFS traversal + u --> The vertex to be visited next + visited[] --> keeps tract of visited vertices + disc[] --> Stores discovery times of visited vertices + parent[] --> Stores parent vertices in DFS tree + ap[] --> Store articulation points''' + def APUtil(self,u, visited, ap, parent, low, disc, chd): + + #Count of children in current node + children =0 + decendants = 0 + # Mark the current node as visited and print it + visited[u]= True + + # Initialize discovery time and low value + disc[u] = self.Time + low[u] = self.Time + self.Time += 1 + + #Recur for all the vertices adjacent to this vertex + for v in self.graph[u]: + # If v is not visited yet, then make it a child of u + # in DFS tree and recur for it + if visited[v] == False : + parent[v] = u + children += 1 + decendants += 1 + decendants += self.APUtil(v, visited, ap, parent, low, disc,chd) + + # Check if the subtree rooted with v has a connection to + # one of the ancestors of u + low[u] = min(low[u], low[v]) + + chd[u] = decendants + + # u is an articulation point in following cases + # (1) u is root of DFS tree and has two or more chilren. + if parent[u] == -1 and children > 1: + ap[u] = True + + #(2) If u is not root and low value of one of its child is more + # than discovery value of u. + if parent[u] != -1 and low[v] >= disc[u]: + ap[u] = True + + # Update low value of u for parent function calls + elif v != parent[u]: + low[u] = min(low[u], disc[v]) + return decendants + + #The function to do DFS traversal. It uses recursive APUtil() + def AP(self,start): + + # Mark all the vertices as not visited + # and Initialize parent and visited, + # and ap(articulation point) arrays + visited = [False] * (self.V) + disc = [float("Inf")] * (self.V) + low = [float("Inf")] * (self.V) + parent = [-1] * (self.V) + ap = [False] * (self.V) #To store articulation points + chd = [0] *self.V + # Call the recursive helper function + # to find articulation points + # in DFS tree rooted with vertex 'i' + + self.APUtil(start, visited, ap, parent, low, disc, chd) + + return ap,chd + +class Graph2(): + + def __init__(self, vertices): + self.V = vertices + self.graph = [[0 for column in range(vertices)] + for row in range(vertices)] + + # A utility function to find the vertex with + # minimum distance value, from the set of vertices + # not yet included in shortest path tree + def minDistance(self, dist, sptSet): + + # Initilaize minimum distance for next node + _min = 10**100 + + # Search not nearest vertex not in the + # shortest path tree + + for v in range(self.V): + if dist[v] < _min and sptSet[v] == False: + _min = dist[v] + min_index = v + return min_index + + # Funtion that implements Dijkstra's single source + # shortest path algorithm for a graph represented + # using adjacency matrix representation + def dijkstra(self, src): + + dist = [10**100] * self.V + dist[src] = 0 + sptSet = [False] * self.V + + for cout in range(self.V): + + # Pick the minimum distance vertex from + # the set of vertices not yet processed. + # u is always equal to src in first iteration + u = self.minDistance(dist, sptSet) + + # Put the minimum distance vertex in the + # shotest path tree + sptSet[u] = True + + # Update dist value of the adjacent vertices + # of the picked vertex only if the current + # distance is greater than new distance and + # the vertex in not in the shotest path tree + for v in range(self.V): + if self.graph[u][v] > 0 and sptSet[v] == False and dist[v] > dist[u] + self.graph[u][v]: + dist[v] = dist[u] + self.graph[u][v] + return dist +N,S,M = map(int,input().split()) + +arr = [[0 for _ in range(N)] for _ in range(N)] + +for _ in range(M): + a,b,w = input().split() + arr[int(a)][int(b)] = float(w) + +g1 = Graph(N) +for i in range(N): + for j in range(i+1,N): + if arr[i][j] > 0: + g1.addEdge(i,j) + +ap,chd = g1.AP(S) +aps = [] +for index, value in enumerate (ap): + if value == True: + aps.append(index) + +arr_log = [[0 for _ in range(N)] for _ in range(N)] +for i in range(N): + for j in range(N): + if (arr[i][j] > 0): + arr_log[i][j] = -math.log10(arr[i][j]) + else: + arr_log[i][j] = 10*100 + +g = Graph2(N) +g.graph = arr_log + +dist = g.dijkstra(S) + +_max = -10**100 +ans = -1 +for ap in aps: + if 10**(-dist[ap])*chd[ap] > _max: + if ap == S: + continue + _max = 10**(-dist[ap])*chd[ap] + ans = ap + +print(ans) + + + diff --git a/codeBase/ACES_Coders/v8.0/coders/The-Heist-of-Musketeers/Readme.md b/codeBase/ACES_Coders/v8.0/coders/The-Heist-of-Musketeers/Readme.md new file mode 100644 index 0000000..92bc416 --- /dev/null +++ b/codeBase/ACES_Coders/v8.0/coders/The-Heist-of-Musketeers/Readme.md @@ -0,0 +1 @@ +The solution will be added later. Please contact suren.sri[at]eng[dot]pdn[dot]ac[dot]lk for support. \ No newline at end of file diff --git a/codeBase/ACES_Coders/v8.0/pre-coders/Color-me/Readme.md b/codeBase/ACES_Coders/v8.0/pre-coders/Color-me/Readme.md new file mode 100644 index 0000000..d3c7d5e --- /dev/null +++ b/codeBase/ACES_Coders/v8.0/pre-coders/Color-me/Readme.md @@ -0,0 +1 @@ +The solution will be added later. Please contact harshana.w[at]eng[dot]pdn[dot]ac[dot]lk for support. \ No newline at end of file diff --git a/codeBase/ACES_Coders/v8.0/pre-coders/Find-the-sum/Solution.py b/codeBase/ACES_Coders/v8.0/pre-coders/Find-the-sum/Solution.py new file mode 100644 index 0000000..ae7cb19 --- /dev/null +++ b/codeBase/ACES_Coders/v8.0/pre-coders/Find-the-sum/Solution.py @@ -0,0 +1,20 @@ +''' + This code was written by UOP_hashInclude during ACES Precoders v8 2020 + nuwanjaliyagoda@eng.pdn.ac.lk imeshuek@eng.pdn.ac.lk dinelkadilshani95@gmail.com + +''' +qwe,n=[int(i) for i in input().strip().split(" ")] + +p=[int(i) for i in input().strip().split(" ")] +q=[0] +tot=0 +for i in p: + tot+=i + q+=[tot] + +for i in range (n): + a,b=[int(i) for i in input().strip().split(" ")] + if b>=qwe: + b=len(q)-1 + print(q[b+1]-q[a]) + diff --git a/codeBase/ACES_Coders/v8.0/pre-coders/Gauntlet-quest/Solution.java b/codeBase/ACES_Coders/v8.0/pre-coders/Gauntlet-quest/Solution.java new file mode 100644 index 0000000..133bccd --- /dev/null +++ b/codeBase/ACES_Coders/v8.0/pre-coders/Gauntlet-quest/Solution.java @@ -0,0 +1,101 @@ +/* + This code was written by UOP_IntElligence during ACES Precoders v8 2020 + hisnionline@gmail.com muhammadh.aslamm@gmail.com irfanmm96@gmail.com + +*/ +import java.io.*; +import java.util.*; + +public class Solution { + + static int max(int x, int y){ + return (x > y) ? x : y; + } + + static int min(int x, int y){ + return (x > y) ? y : x; + } + public static void main(String[] args) throws IOException { + Scanner sc = new Scanner(System.in); + + String[] Str = sc.nextLine().split(" "); + + int n = Integer.parseInt(Str[0]); + int m = Integer.parseInt(Str[1]); + int k = Integer.parseInt(Str[2]); + + int[] matrix = new int[n]; + HashMap[] path = new HashMap[n]; + int[][] dist = new int[n][1<0){ + f |= 1 << (sc.nextInt() - 1); + } + matrix[itr] = f; + path[itr] = new HashMap(); + Arrays.fill(dist[itr], Integer.MAX_VALUE); + itr++; + } + + itr = 0; + while(itr que = new PriorityQueue(); + que.add(new Edge(0, matrix[0], 0)); + while(!que.isEmpty()) { + int i = que.peek().e; + int f = que.peek().f; + int w = que.poll().w; + if(dist[i][f] < w) { + continue; + } + + for(int j : path[i].keySet()) { + int planet = f|matrix[j]; + int time = w+path[i].get(j); + if(dist[j][planet] > time) { + dist[j][planet] = time; + que.add(new Edge(j,planet,time)); + } + } + + } + + int result = 100000000; + for(int i = 0; i < 1<{ + int e, f, w; + + public Edge(int e, int f, int w) { + super(); + this.e = e; + this.f = f; + this.w = w; + } + + @Override + public int compareTo(Edge o) { + return this.w-o.w; + } + } +} \ No newline at end of file diff --git a/codeBase/ACES_Coders/v8.0/pre-coders/Gauntlet-quest/Solution.py b/codeBase/ACES_Coders/v8.0/pre-coders/Gauntlet-quest/Solution.py new file mode 100644 index 0000000..17ebf3b --- /dev/null +++ b/codeBase/ACES_Coders/v8.0/pre-coders/Gauntlet-quest/Solution.py @@ -0,0 +1,38 @@ +''' +NOTE: +Due to the large queue size, the unoptimized solution is comparatively slower (Only in interpreted languages like python). +Thus multiple queues are used, one for each bit mask value. +suren.sri@eng.pdn.ac.lk +''' + +from heapq import * +n, m, k = map(int, input().split()) +typ = [sum(map(lambda x: 1 << (x - 1), map(int, input().split()[1:]))) for _ in range(n)] +graph = [[] for i in range(n)] +for i in range(m): + a, b, c = map(int, input().split()) + a, b = a - 1, b - 1 + graph[a].append((b, c)) + graph[b].append((a, c)) +k, n = (1 << k) - 1, n - 1 +h = [[] for _ in range(k + 1)] +v = [set() for _ in range(k + 1)] +last = {0: 0} +heappush(h[typ[0]], (0, 0)) +flag = INF = 10 ** 9 +for i in range(k + 1): + while h[i]: + c, a = heappop(h[i]) + if a == n: + for x, y in last.items(): + if i | x == k: + flag = min(flag, max(y, c)) + last[i] = min(c, last.get(i, INF)) + if a in v[i]: + continue + v[i].add(a) + for x, y in graph[a]: + j = typ[x] | i + if x not in v[j]: + heappush(h[j], (y + c, x)) +print(flag) diff --git a/codeBase/ACES_Coders/v8.0/pre-coders/Gauntlet-quest/Solution_unoptimized.py b/codeBase/ACES_Coders/v8.0/pre-coders/Gauntlet-quest/Solution_unoptimized.py new file mode 100644 index 0000000..2c92ae7 --- /dev/null +++ b/codeBase/ACES_Coders/v8.0/pre-coders/Gauntlet-quest/Solution_unoptimized.py @@ -0,0 +1,42 @@ +''' +suren.sri@eng.pdn.ac.lk +''' +from heapq import heappop, heappush +from collections import defaultdict + +n, m, k = map(int, raw_input().split()) + +masks = [0] * (n+1) +graph = defaultdict(list) +dp = [[float('inf')]*(2**k+2) for i in xrange(n+1)] + +for i in xrange(1, n+1): + ar = map(int, raw_input().split()) + for t in xrange(1, len(ar)): + masks[i] |= 2**(ar[t]-1) + +for i in range(m): + u, v, w = map(int, raw_input().split()) + graph[u].append((v, w)) + graph[v].append((u, w)) + +queue = [(0, 1, masks[1])] + +# Djikstra +while queue: + cost, node, mask = heappop(queue) + for X in graph[node]: + v, c = X + if cost + c < dp[v][mask|masks[v]]: + heappush(queue, (cost+c, v, mask | masks[v])) + dp[v][mask | masks[v]] = cost + c + +ans = float('inf') + +# Brute force bit manipulation +for i in xrange(2**k): + for j in xrange(2**k): + if i | j == 2**k - 1 and dp[n][j] != float('inf'): + ans = min(ans, max(dp[n][i], dp[n][j])) + +print ans diff --git a/codeBase/ACES_Coders/v8.0/pre-coders/Job-selection/Readme.md b/codeBase/ACES_Coders/v8.0/pre-coders/Job-selection/Readme.md new file mode 100644 index 0000000..e873819 --- /dev/null +++ b/codeBase/ACES_Coders/v8.0/pre-coders/Job-selection/Readme.md @@ -0,0 +1 @@ +Hint: Bipartite graph matching. \ No newline at end of file diff --git a/codeBase/ACES_Coders/v8.0/pre-coders/Journey-on-tiles/Solution.java b/codeBase/ACES_Coders/v8.0/pre-coders/Journey-on-tiles/Solution.java new file mode 100644 index 0000000..7d56170 --- /dev/null +++ b/codeBase/ACES_Coders/v8.0/pre-coders/Journey-on-tiles/Solution.java @@ -0,0 +1,47 @@ +/* + This code was written by UOP_IntElligence during ACES Precoders v8 2020 + hisnionline@gmail.com muhammadh.aslamm@gmail.com irfanmm96@gmail.com +*/ +import java.io.*; +import java.util.*; + +public class Solution { + + static int max(int x, int y){ + return (x > y) ? x : y; + } + + private static int minCost(int cost[][], int m, int n){ + int i, j; + int tc[][]=new int[m+1][n+1]; + + tc[0][0] = cost[0][0]; + + for (i = 1; i <= m; i++) + tc[i][0] = tc[i-1][0] + cost[i][0]; + + for (j = 1; j <= n; j++) + tc[0][j] = tc[0][j-1] + cost[0][j]; + + for (i = 1; i <= m; i++) + for (j = 1; j <= n; j++) + tc[i][j] = max(tc[i-1][j], tc[i][j-1]) + cost[i][j]; + + return tc[m][n]; + } + + public static void main(String[] args) { + Scanner scanner = new Scanner(System.in); + + int ROW = scanner.nextInt(); + int [][] arr = new int[ROW][ROW]; + + for(int i=0;i +#include +#include +#include +#include +using namespace std; + + +int main() { + int t; + cin >> t; + for(int k=0;k> s; + string result; + result += s[0]; + for(int i=1;i result[0]){ + result = result + s[i]; + } + else{ + result = s[i] + result; + } + } + cout << result << endl; + } + return 0; +} \ No newline at end of file diff --git a/codeBase/ACES_Coders/v8.0/pre-coders/Lexicographically-smallest-game/Solution.py b/codeBase/ACES_Coders/v8.0/pre-coders/Lexicographically-smallest-game/Solution.py new file mode 100644 index 0000000..05f994e --- /dev/null +++ b/codeBase/ACES_Coders/v8.0/pre-coders/Lexicographically-smallest-game/Solution.py @@ -0,0 +1,24 @@ +''' + This code was written by UOP_hashInclude during ACES Precoders v8 2020 + nuwanjaliyagoda@eng.pdn.ac.lk imeshuek@eng.pdn.ac.lk dinelkadilshani95@gmail.com + +''' +n=int(input()) +p=[] +for i in range (n): + word=input().strip() + p+=[word] + + +for i in p: + w="" + for j in i: + if w=="": + w=j + elif w[0]>=j: + w=j+w + else: + w=w+j + print(w) + + \ No newline at end of file diff --git a/codeBase/ACES_Coders/v8.0/pre-coders/Office-crushes/Solution.cpp b/codeBase/ACES_Coders/v8.0/pre-coders/Office-crushes/Solution.cpp new file mode 100644 index 0000000..dfdb673 --- /dev/null +++ b/codeBase/ACES_Coders/v8.0/pre-coders/Office-crushes/Solution.cpp @@ -0,0 +1,88 @@ +/* + This code was written by UOP_JPAC during ACES Precoders v8 2020 + pubuduudara7@gmail.com imsuneth@gmail.com pasan96tennakoon@gmail.com +*/ +#include +#include +#include +#include +#include + +using namespace std; + +void select(vector s, vector f) { + vector> ans; + + priority_queue, vector>, greater>> p; + + for (int i = 0; i < s.size(); i++) { + p.push(make_pair(f[i], s[i])); + } + + auto it = p.top(); + float start = it.second; + float end = it.first; + p.pop(); + ans.push_back(make_pair(start, end)); + + while (!p.empty()) { + auto itr = p.top(); + p.pop(); + if (itr.second >= end) { + start = itr.second; + end = itr.first; + ans.push_back(make_pair(start, end)); + } + } + cout << ans.size() << endl; + +} + +int main() { + int n; + cin >> n; + char x; + float a, b; + + + string line; + + vector s; + vector f; + + int j = 0; + for (int i = 0; i < n; i++) { + string yes, start, end; + cin >> yes >> start >> end; + if (yes[0] == 'Y') { + replace(start.begin(), start.end(), ':', '.'); + replace(end.begin(), end.end(), ':', '.'); + + + string tok; + vector internal1, internal2; + stringstream ss(start); + stringstream ee(end); + while(getline(ss, tok, '.')) { + internal1.push_back(tok); + } + + while(getline(ee, tok, '.')) { + internal2.push_back(tok); + } + + float sss = stof(internal1[0])*60 + stof(internal1[1]); + float enn = stof(internal2[0])*60 + stof(internal2[1]); + + s.push_back(sss); + f.push_back(enn); + j++; + } + + + } + + select(s, f); + + return 0; +} \ No newline at end of file diff --git a/codeBase/ACES_Coders/v8.0/pre-coders/Office-crushes/Solution.java b/codeBase/ACES_Coders/v8.0/pre-coders/Office-crushes/Solution.java new file mode 100644 index 0000000..7efe2e2 --- /dev/null +++ b/codeBase/ACES_Coders/v8.0/pre-coders/Office-crushes/Solution.java @@ -0,0 +1,80 @@ +/* + This code was written by UOP_eyeCoders during ACES Precoders v8 2020 + thusharakart@gmail.com nuwan.harshamatrix@gmail.com thilankanayana@gmail.com + +*/ +import java.io.*; +import java.util.*; + +public class Solution { + public static void sortbyColumn(int arr[][], int col) + { + // Using built-in sort function Arrays.sort + Arrays.sort(arr, new Comparator() { + + @Override + // Compare values according to columns + public int compare(final int[] entry1, + final int[] entry2) { + + // To sort in descending order revert + // the '>' Operator + if (entry1[col] > entry2[col]) + return 1; + else + return -1; + } + }); // End of function call sort(). + } + static int timeConvert(String date){ + String[]arr=date.split(":"); + int a=100*Integer.parseInt(arr[0]); + int b = Integer.parseInt(arr[1]); + return a+b; + } + public static void main(String[] args) { + /* Enter your code here. Read input from STDIN. Print output to STDOUT. Your class should be named Solution. */ + Scanner in = new Scanner(System.in); + int t = in.nextInt(); + in.nextLine(); + String[][]arr = new String[t][3]; + + int size = 0,index = 0; + for(int i=0;i=last){ + temp++; + last =brr[k][1]; + } + + + } + System.out.println(temp); + + + } +} \ No newline at end of file diff --git a/codeBase/ACES_Coders/v8.0/pre-coders/Office-crushes/Solution.py b/codeBase/ACES_Coders/v8.0/pre-coders/Office-crushes/Solution.py new file mode 100644 index 0000000..b04d7b2 --- /dev/null +++ b/codeBase/ACES_Coders/v8.0/pre-coders/Office-crushes/Solution.py @@ -0,0 +1,29 @@ +''' + This code was written by UOP_Binarybeasts during ACES Precoders v8 2020 + e17212@eng.pdn.ac.lk kalpani.abewickrama@gmail.com ishini.udara@gmail.com +''' +n = int(input().strip()) +meetings = [] + +for i in range(n): + a, s, e = list(map(str,input().strip().split())) + col_idx = s.index(":") + s = int(s[:col_idx])*60 + int(s[col_idx+1:]) + col_idx = e.index(":") + e = int(e[:col_idx])*60 + int(e[col_idx+1:]) + if a=='Y': + meetings.append([i,s,e]) + +sorted_meetings = sorted(meetings,key=lambda x: x[2]) + +s = set([sorted_meetings[0][0]]) + +k=0 + +for i in range(1,len(meetings)): + if sorted_meetings[i][1] >= sorted_meetings[k][2]: + s.add(sorted_meetings[i][0]) + k=i + + +print(len(s)) diff --git a/codeBase/ACES_Coders/v8.0/pre-coders/Valentines-day-gifts/Solution.java b/codeBase/ACES_Coders/v8.0/pre-coders/Valentines-day-gifts/Solution.java new file mode 100644 index 0000000..88322ad --- /dev/null +++ b/codeBase/ACES_Coders/v8.0/pre-coders/Valentines-day-gifts/Solution.java @@ -0,0 +1,75 @@ +/* + gihanjayatilaka[at]eng[dot]pdn[dot]ac[dot]lk + */ +import javax.sound.midi.SysexMessage; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Scanner; + +class Gift implements Comparable{ + String name; + float radius; + + Gift(String name,float radius){ + this.name=name; + this.radius=radius; + } + + public int compareTo(Gift p){ + return Float.compare(this.radius,p.radius); + } + +} + + +public class Solution { + static Scanner sc=new Scanner(System.in); + + public static void main(String[] args) { + int N=Integer.parseInt(sc.nextLine()); + + Gift[] gifts=new Gift[N]; +// String[] names=new String[N]; +// float[] radius=new float[N]; + + for(int i=0;i names=new HashSet<>(); + + for(int i=0;i(); + + for(int i=0;i(); + } + } + + System.out.println(ans); + + + + } +} diff --git a/codeBase/ACES_Coders/v8.0/pre-coders/Valentines-day-gifts/Solution.py b/codeBase/ACES_Coders/v8.0/pre-coders/Valentines-day-gifts/Solution.py new file mode 100644 index 0000000..d611bb0 --- /dev/null +++ b/codeBase/ACES_Coders/v8.0/pre-coders/Valentines-day-gifts/Solution.py @@ -0,0 +1,24 @@ +''' + gihanjayatilaka[at]eng[dot]pdn[dot]ac[dot]lk +''' + +N=int(input()) +names=[] +radii=[] +for _ in range(N): + name,radius=input().strip().split() + names.append(name) + radii.append(float(radius)) +rn=zip(radii,names) +rn=sorted(rn) +ans=1 +noOfCrushes=len(set(names)) + +names=set() +for i in range(N): + names.add(rn[i][1]) + if len(names)==noOfCrushes:#One person can wrap only the gifts of everyone else = ONE less than the no of crushes + ans+=1 + names=set() + names.add(rn[i][1]) +print(ans) diff --git a/codeBase/Algorithms/Other/Binomial_Coefficient(nCr)/NCR.java b/codeBase/Algorithms/Other/Binomial_Coefficient(nCr)/NCR.java new file mode 100644 index 0000000..bd04a6f --- /dev/null +++ b/codeBase/Algorithms/Other/Binomial_Coefficient(nCr)/NCR.java @@ -0,0 +1,30 @@ +/* + gihanjayatilaka[at]eng[dot]pdn[dot]ac[dot]lk + 2020-04-04 + + DP (Dynamic progamming) nCr (number of k-combinations) +*/ +import java.util.Scanner; +class NCR{ + static Scanner sc=new Scanner(System.in); + + public static void main(String[] args){ + int N=sc.nextInt(); + int R=sc.nextInt(); + System.out.println(N+"c"+R+" = "+nCr(N,R)); + } + + public static long nCr(int n,int r){ + long[][] c=new long[n+1][r+1]; + int i,j; + for(i=0;i0)System.out.print(ar[ar.length-1]); + System.out.println(""); + } + public static void printFast(long[][] ar){ + for(int x=0;xMSP[x][2]){ + processedBits[x]+=Math.min((long)MSP[x][0],(t-(long)MSP[x][2])/(long)MSP[x][1]); + } + } + + Arrays.sort(processedBits); + for(int x=C-1;x>(C-1)-R;x--){ + totalBits+=processedBits[x]; + } + + + + + if(totalBits>=B)return true; + else return false; + } +} diff --git a/codeBase/CodeJam/2018/2018_qualification_CubicUFO/Solution.java b/codeBase/CodeJam/2018/2018_qualification_CubicUFO/Solution.java new file mode 100644 index 0000000..3d67f7c --- /dev/null +++ b/codeBase/CodeJam/2018/2018_qualification_CubicUFO/Solution.java @@ -0,0 +1,318 @@ +/* + Code written by gihanjayatilaka[at]eng.pdn.ac.lk during Code Jam 2018 + This solution passed all test cases +*/ +import java.util.*; +import java.io.*; + +class InputReader { + BufferedReader bReader; + StringTokenizer tokenizer; + + InputReader(InputStream inputStream){ + InputStreamReader inStreamReader=new InputStreamReader(inputStream); + bReader=new BufferedReader(inStreamReader); + tokenizer=new StringTokenizer(""); + + } + + public String nextLine(){ + try{ + String inLine= bReader.readLine(); + tokenizer= new StringTokenizer(inLine); + return inLine; + + } + catch(Exception e){ + return null; + } + } + + public String nextWord(){ + while(tokenizer== null || !tokenizer.hasMoreTokens()){ + nextLine(); + //tokenizer=new StringTokenizer(nextLine()); + } + return tokenizer.nextToken(); + } + + public boolean hasNext(){ + try{ + return bReader.ready(); + } + catch(Exception e){ + return false; + } + } + + + +} + +class IO2 { + static InputReader sc=new InputReader(System.in); + + public static String readLine(){ + return sc.nextLine(); + } + public static String readWord(){ + return sc.nextWord(); + } + + public static int readInt(){ + return Integer.parseInt(readWord()); + } + + public static long readLong(){ + return Long.parseLong(readWord()); + } + + public static double readDouble(){ + return Double.parseDouble(readWord()); + } + + public static float readFloat(){ + return Float.parseFloat(readWord()); + } + + public static char readChar(){ + return (char) readInt(); + } + + public static int readIntLine(){ + return Integer.parseInt(readLine().trim()); + } + + public static long readLongLine(){ + return Long.parseLong(readLine().trim()); + } + + public static double readDoubleLine(){ + return Double.parseDouble(readLine().trim()); + } + + public static float readFloatLine(){ + return Float.parseFloat(readLine().trim()); + } + + public static char readCharLine(){ + return (char)readIntLine(); + } + + public static int[] readIntArray(int noOfElements){ + int[] ans=new int[noOfElements]; + for(int x=0;x0)System.out.print(ar[ar.length-1]); + System.out.println(""); + } + public static void printFast(long[][] ar){ + for(int x=0;x0)System.out.print(ar[ar.length-1]); + System.out.println(""); + } + public static void printFast(long[][] ar){ + for(int x=0;x0)System.out.print(ar[ar.length-1]); + System.out.println(""); + } + public static void printFast(long[][] ar){ + for(int x=0;xD){ + if(swapOnce())swaps++; + else break; + } + + if(damage()<=D)IO2.print("Case #"+t+": "+swaps); + else IO2.print("Case #"+t+": "+"IMPOSSIBLE"); + } + + + } + + public static long damage(){ + long ans=0; + long curDamage=1; + + for(int x=0;x=0;x--){ + if(x==0)return false; + else{ + if(ar[x]=='S' && ar[x-1]=='C'){ + ar[x]='C';ar[x-1]='S'; + return true; + } + } + } + return false; + } +} + diff --git a/codeBase/CodeJam/2018/2018_qualification_TroubleSort/Solution.java b/codeBase/CodeJam/2018/2018_qualification_TroubleSort/Solution.java new file mode 100644 index 0000000..4b4e335 --- /dev/null +++ b/codeBase/CodeJam/2018/2018_qualification_TroubleSort/Solution.java @@ -0,0 +1,338 @@ +/* + Code written by gihanjayatilaka[at]eng.pdn.ac.lk during Code Jam 2018 + This solution passed all test cases +*/ +import java.util.*; +import java.io.*; + +class InputReader { + BufferedReader bReader; + StringTokenizer tokenizer; + + InputReader(InputStream inputStream){ + InputStreamReader inStreamReader=new InputStreamReader(inputStream); + bReader=new BufferedReader(inStreamReader); + tokenizer=new StringTokenizer(""); + + } + + public String nextLine(){ + try{ + String inLine= bReader.readLine(); + tokenizer= new StringTokenizer(inLine); + return inLine; + + } + catch(Exception e){ + return null; + } + } + + public String nextWord(){ + while(tokenizer== null || !tokenizer.hasMoreTokens()){ + nextLine(); + //tokenizer=new StringTokenizer(nextLine()); + } + return tokenizer.nextToken(); + } + + public boolean hasNext(){ + try{ + return bReader.ready(); + } + catch(Exception e){ + return false; + } + } + + + +} + +class IO2 { + static InputReader sc=new InputReader(System.in); + + public static String readLine(){ + return sc.nextLine(); + } + public static String readWord(){ + return sc.nextWord(); + } + + public static int readInt(){ + return Integer.parseInt(readWord()); + } + + public static long readLong(){ + return Long.parseLong(readWord()); + } + + public static double readDouble(){ + return Double.parseDouble(readWord()); + } + + public static float readFloat(){ + return Float.parseFloat(readWord()); + } + + public static char readChar(){ + return (char) readInt(); + } + + public static int readIntLine(){ + return Integer.parseInt(readLine().trim()); + } + + public static long readLongLine(){ + return Long.parseLong(readLine().trim()); + } + + public static double readDoubleLine(){ + return Double.parseDouble(readLine().trim()); + } + + public static float readFloatLine(){ + return Float.parseFloat(readLine().trim()); + } + + public static char readCharLine(){ + return (char)readIntLine(); + } + + public static int[] readIntArray(int noOfElements){ + int[] ans=new int[noOfElements]; + for(int x=0;x0)System.out.print(ar[ar.length-1]); + System.out.println(""); + } + public static void printFast(long[][] ar){ + for(int x=0;xar[1][x]){ + ok=false; + wrongIndex=2*x; + break; + } + if(ar[1][x]>ar[0][x+1]){ + ok=false; + wrongIndex=2*x+1; + break; + } + } + + if(ok)if(ar[0][ar[0].length-1]>ar[1][ar[0].length-1]){ + ok=false; + wrongIndex=N-2; + } + + //for(int x=0;x= 0): + strg += '('*tmp + else: + strg += ')'*(-1*tmp) + strg += str(lis[i]) # adding the changes to the final strings to be displayed + strg += ')'*lis[-1] + print("Case #{}: {}".format(t, strg)) # print the final output + + diff --git a/codeBase/CodeJam/2020/Parent Partnering/solution.py b/codeBase/CodeJam/2020/Parent Partnering/solution.py new file mode 100644 index 0000000..00e49cc --- /dev/null +++ b/codeBase/CodeJam/2020/Parent Partnering/solution.py @@ -0,0 +1,103 @@ +# Name - Thilakarathna W M D U +# Email - dtdinidu7@gmail.com +# Date - 08/04/2020 + +class Graph(): # this class is used to check whether the graph is bipartite graph you can find this code with an explanation in geeksforgeeks + def __init__(self, V): + self.V = V + self.graph = [[0 for column in range(V)] + for row in range(V)] + + self.cAr = [-1 for i in range(self.V)] # this array is filled with -1 and 2 as the colors + + def isBipUti(self, src): + q = [] + q.append(src) + while q: + u = q.pop() + if self.graph[u][u] == 1: + return False + + for v in range(self.V): + if (self.graph[u][v] == 1 and + self.cAr[v] == -1): + + self.cAr[v] = 1 - self.cAr[u] + q.append(v) + + elif (self.graph[u][v] == 1 and + self.cAr[v] == self.cAr[u]): + return False + return True + + def isBip(self): + self.cAr = [-1 for i in range(self.V)] + for i in range(self.V): + if self.cAr[i] == -1: + if not self.isBipUti(i): + return False + #print(self.cAr) + return True + + +def isOverlap(s1, e1, s2, e2): # check whether two slots are overlap with each other + if (s1 >= e2 and s2 < s1): + return False + if (s2 >= e1 and s1 < s2): + return False + return True + +tm = int(input()) # number of the test cases + +for t in range(1, tm+1): # loop through the test cases + timeLine = [] + for i in range(1445): + timeLine.append([]) + + #print(timeLine) + v = int(input()) + g = Graph(v) + g.graph = [] + #lis = [] + for i in range(v): # adding events to the timeline + g.graph.append([0]*v) + strat, end = [int(i) for i in input().split()] + #lis.append((strat, end)) + timeLine[strat].append(i+1) + timeLine[end].append(-(i+1)) + + dinQ = set() + #print(timeLine) + + for i in timeLine: # checking for overlaps + if len(i) > 0: + for j in i: + if (j > 0): + dinQ.add(j-1) + else: + dinQ.remove((-j)-1) + + if len(dinQ)>2: # if three slots overlap each other then two people can't dewide them among themselves without overlaping + print("Case #{}: IMPOSSIBLE".format(t)) + break + + tmp = list(dinQ) + + for x in range(len(dinQ)): + for y in range(x+1, len(dinQ)): + g.graph[tmp[x]][tmp[y]] = 1 + g.graph[tmp[y]][tmp[x]] = 1 + else: + #print() + #print(g.graph) + + if (g.isBip()): + strg = "" + for i in g.cAr: + if (i == -1): + strg += "C" + else: + strg += "J" + print("Case #{}: {}".format(t, strg)) + else: + print("Case #{}: IMPOSSIBLE".format(t)) \ No newline at end of file diff --git a/codeBase/CodeJam/2020/Vestigium/solution.py b/codeBase/CodeJam/2020/Vestigium/solution.py new file mode 100644 index 0000000..40d94bc --- /dev/null +++ b/codeBase/CodeJam/2020/Vestigium/solution.py @@ -0,0 +1,31 @@ +# Name - Thilakarathna W M D U +# Email - dtdinidu7@gmail.com +# Date - 08/04/2020 + +tm = int(input()) # number of test cases + +for t in range(1, tm+1): # looping through test cases + n = int(input()) # size of the matrix + mat = [] + trace = 0 # trace calculate variable + rowCount = 0 + colCount = 0 + for r in range(n): + tmp = [int(i) for i in input().split()] + trace += tmp[r] + rowCheck = set(tmp.copy()) + if len(rowCheck) < n: + rowCount += 1 + mat.append(tmp) + + + for c in range(n): + tmp = [] + for r in range(n): + tmp.append(mat[r][c]) + #print(tmp) + if (len(set(tmp)) < n): + colCount += 1 + + print("Case #{}: {} {} {}".format(t, trace, rowCount, colCount)) + \ No newline at end of file diff --git a/codeBase/HackerRank/Algorithms/Dynamic Programming/Bricks Game/Solution.cpp b/codeBase/HackerRank/Algorithms/Dynamic Programming/Bricks Game/Solution.cpp new file mode 100644 index 0000000..25e8d8d --- /dev/null +++ b/codeBase/HackerRank/Algorithms/Dynamic Programming/Bricks Game/Solution.cpp @@ -0,0 +1,34 @@ +/* + Copyright (C) 2020, Sathira Silva. + + Problem Statement: You and your friend decide to play a game using a stack consisting of N bricks. In this game, you can + alternatively remove 1, 2 or 3 bricks from the top, and the numbers etched on the removed bricks are + added to your score. You have to play so that you obtain the maximum possible score. It is given that your + friend will also play optimally and you make the first move. +*/ + +#include +#include + +using namespace std; + +vector split_string(string); + +long long bricksGame(vector arr) { + int n = arr.size(); + long long score[n]; + if (arr.size() <= 3) + return accumulate(arr.begin(), arr.end(), 0); + // Base Cases: + score[n - 1] = arr[n - 1]; + score[n - 2] = score[n - 1] + arr[n - 2]; + score[n - 3] = score[n - 2] + arr[n - 3]; + long long sum = score[n - 3]; + // Build the optimal solution using the optimal solutions of it's subproblems. + // Traverse the array backwards and get the cumulative sum at each state. + for (int i = n - 4; i >= 0; i--) { + sum += arr[i]; + score[i] = sum - min({score[i + 1], score[i + 2], score[i + 3]}); + } + return score[0]; +} diff --git a/codeBase/HackerRank/Algorithms/Dynamic Programming/Cut Tree/Solution.cpp b/codeBase/HackerRank/Algorithms/Dynamic Programming/Cut Tree/Solution.cpp new file mode 100644 index 0000000..7dd2a7b --- /dev/null +++ b/codeBase/HackerRank/Algorithms/Dynamic Programming/Cut Tree/Solution.cpp @@ -0,0 +1,46 @@ +/* + Problem Statement: Given a tree T with n nodes, how many subtrees (T') of T have at most K edges connected to (T - T')? + + Approach: The idea is to depth first traverse the tree and count the subtrees having number of edges connected to the complement + of the current subtree upto k edges. +*/ + +#include + +using namespace std; + +vector split_string(string); + +vector tree[51]; +long long dp[51][51]; +int k; + +void dfs(int u, int parent = -1) { + for (int v: tree[u]) { + if (v == parent) + continue; + dfs(v, u); + for (int j = k; j > 0; j--) { + for (int x = j; x > 0; x--) + dp[u][j] += dp[u][j - x] * dp[v][x]; + dp[u][j] += dp[u][j - 1]; + } + } + return; +} + +long long cutTree(int n, vector> edges) { + for (auto e: edges) { + tree[e[0]].push_back(e[1]); + tree[e[1]].push_back(e[0]); + } + long long subtrees = 0; + memset(dp, 0, sizeof(dp)); + for(int u = 1; u <= n; u++) + dp[u][0] = 1; // Base case + dfs(1); + for(int i = 1; i <= n; i++) + for(int j = 0; j < k; j++) + subtrees += dp[i][j]; + return subtrees + dp[1][k] + 1; +} diff --git a/codeBase/HackerRank/Algorithms/Dynamic Programming/Kingdom Division/solution.py b/codeBase/HackerRank/Algorithms/Dynamic Programming/Kingdom Division/solution.py new file mode 100644 index 0000000..86864f4 --- /dev/null +++ b/codeBase/HackerRank/Algorithms/Dynamic Programming/Kingdom Division/solution.py @@ -0,0 +1,49 @@ +''' + Copyright (C) 2020, Sathira Silva. + + Problem Statement: King Arthur has a large kingdom that can be represented as a tree, where nodes correspond to cities and edges + correspond to the roads between cities. The kingdom has a total of n cities numbered from 1 to n. The King wants to divide his kingdom + between his two children, Reggie and Betty, by giving each of them 0 or more cities; however, they don't get along so he must divide + the kingdom in such a way that they will not invade each other's cities. The first sibling will invade the second sibling's city if + the second sibling has no other cities directly connected to it. + Given a map of the kingdom's n cities, find and print the number of ways King Arthur can divide it between his two children such that + they will not invade each other. As this answer can be quite large, it must be modulo 7 + 10 ^ 9. + + Approach: We have to find the number of ways of colouring subtrees such that its root node has the same colour as the subtree. + This can be easily done with Dynamic Programming and DFS traversal to find the subtrees. +''' + +from collections import defaultdict +sys.setrecursionlimit(10 ** 6) + +mod = 7 + 10 ** 9 + +def dfs(city, kingdom, visited): + global dp + visited[city] = True + for neighbourCity in kingdom[city]: + if visited[neighbourCity]: + continue + dfs(neighbourCity, kingdom, visited) + dp[city][0] = (dp[city][0] * dp[neighbourCity][1]) % mod + dp[city][1] = (dp[city][1] * (2 * dp[neighbourCity][1] + dp[neighbourCity][0])) % mod + dp[city][1] -= dp[city][0] + +def kingdomDivision(n, roads): + global dp + visited = [False] * (n + 1) + kingdom = defaultdict(list) + for u, v in roads: + kingdom[u].append(v) + kingdom[v].append(u) + dfs(1, kingdom, visited) + return (2 * dp[1][1]) % mod + +if __name__ == '__main__': + n = int(stdin.readline()) + roads = [] + for _ in range(n-1): + roads.append(list(map(int, stdin.readline().rstrip().split()))) + dp = [[1, 1] for _ in range(n + 1)] + result = kingdomDivision(n, roads) + stdout.write(str(result) + '\n') diff --git a/codeBase/HackerRank/Algorithms/Dynamic Programming/Knapsack/solution.py b/codeBase/HackerRank/Algorithms/Dynamic Programming/Knapsack/solution.py new file mode 100644 index 0000000..35c633f --- /dev/null +++ b/codeBase/HackerRank/Algorithms/Dynamic Programming/Knapsack/solution.py @@ -0,0 +1,32 @@ +''' + Copyright (C) 2020, Sathira Silva. + + Problem Statement: Given an array of integers and a target sum, determine the sum nearest to but not exceeding + the target that can be created. To create the sum, use any element of your array zero or more times. + + Approach: This's a variation of the 0-1 knapsack problem which can be solved easily using Dynamic Programming. Given the capacity of + the knapsack, we have to pack items from the given list of items (and there're infinitely many items from each item) + such that the total size doesn't exceed the capacity of the knapsack. + + (01). Subproblem: dp[capacity] for all 0 < capacity <= k + Maximum capacity that can be packed from the items such that the total capacity doesn't exceed i. + (02). Guessing: is item i included or not? + (03). Recurrence: dp[capacity] = max(dp[capacity], items[i] + dp[capacity - items[i]]) + (04). Toplogical order: for capacity -> 0,...,k + for item -> 0,...,n - 1 + (05). Original problem: dp[k] + + Time Complexity: O(n(k + 1)) ~= O(mk) ; m <= n +''' + +def unboundedKnapsack(k, items): + # Since the same item can be repeatedly appear in the given list, extract only the unique items. This makes the algorithm + # more efficient. + items = list(set(items)) + n = len(items) + dp = [0] * (k + 1) + for capacity in range(k + 1): + for i in range(n): + if items[i] <= capacity: + dp[capacity] = max(dp[capacity], items[i] + dp[capacity - items[i]]) + return dp[k] diff --git a/codeBase/HackerRank/Algorithms/Dynamic Programming/Red John Is Back/Solution.cpp b/codeBase/HackerRank/Algorithms/Dynamic Programming/Red John Is Back/Solution.cpp new file mode 100644 index 0000000..e8c344b --- /dev/null +++ b/codeBase/HackerRank/Algorithms/Dynamic Programming/Red John Is Back/Solution.cpp @@ -0,0 +1,48 @@ +/* + Problem Statement: https://www.hackerrank.com/challenges/red-john-is-back/problem + + Approach: This problem can be solved using Dynamic Programming and Sieve of Eratosthenes (Or any other algorithm for sieving + primes) easily. First we find the number of ways of covering a 4 x n wall with 4 x 1 and 1 x 4 bricks. Then we count the number of + primes less than or equal to that number. + + (01). Subproblem: dp[i] + (How many ways are there to cover a 4 x i wall) + (02). Guess: dp[i - 1] and dp[i - 4] + (Should we cover the remaining are with a 4 x 1 brick or a 1 x 4 brick?) + (03). Recurrence: dp[i] = dp[i - 1] + dp[i - 4] + (Base Cases: dp[0] = dp[1] = dp[2] = dp[3] = 1) + (04). Toplogical Order: i from 4 to n + (05). Original Problem: dp[n] +*/ + +#include + +using namespace std; + +int dp[61]; +bool prime[10000001]; + +void sieveOfEratosthenes(int n) +{ + memset(prime, true, sizeof(prime)); + for (int p = 2; p * p <= n; p++) + { + if (prime[p] == true) + { + for (int i = p * p; i <= n; i += p) + prime[i] = false; + } + } +} + +int redJohn(int n) { + dp[0] = dp[1] = dp[2] = dp[3] = 1; + for (int i = 4; i <= n; i++) + dp[i] = dp[i - 1] + dp[i - 4]; + int count = 0; + for (int i = 2; i <= dp[n]; i++) { + if (prime[i]) + count++; + } + return count; +} diff --git a/codeBase/HackerRank/Algorithms/Dynamic Programming/Sherlock And Cost/solution.py b/codeBase/HackerRank/Algorithms/Dynamic Programming/Sherlock And Cost/solution.py new file mode 100644 index 0000000..e9bf334 --- /dev/null +++ b/codeBase/HackerRank/Algorithms/Dynamic Programming/Sherlock And Cost/solution.py @@ -0,0 +1,31 @@ + +''' + Copyright (C) 2020, Sathira Silva. + + Problem Statement: In this challenge, you will be given an array B and must determine an array A. There is a special rule: For all i, + A[i] <= B[i]. That is, A[i] can be any number you choose such that 1 <= A[i] <= B[i]. Your task is to select a series of A[i] given B[i] + such that the sum of the absolute difference of consecutive pairs of A is maximized. This will be the array's cost, and will be + represented by the variable S below. + + S = Sum(|A[i] - A[i - 1]) from i = 2 to N + + Approach: To obtain the maximum sum S, there're only two possibilities: A[i] is 1 or B[i]. We don't have to check any number between + 1 and B[i]. Therefore, this's sort of a 0-1 Knapsack problem. It can be solved by 4 lines of code using Dynamic Programming. + + (01). Subproblem: Optimal sum of the absolute difference of consecutive pairs of prefix A[:i + 1]. + max(dp) + Base Case: Initially, dp = [0, 0]. Because When A is empty, maximum sum is 0. + (02). Guessing: Is the maximum sum obtained when A[i] = 1 or A[i] = B[i]? + (03). Recurrence: dp = [max(dp[1] + B[i - 1] - 1, dp[0]), max(dp[1] + abs(B[i] - B[i - 1]), dp[0] + B[i] - 1)] + (04). Topological Order: i from 1 to len(B) - 1 + (05). Original Probblem: max(dp) of A[:len(B)] + + Time Complexity: O(|B| - 1) +''' + +def cost(B): + # Base Case + dp = [0, 0] + for i in range(1,len(B)): + dp = [max(dp[1] + B[i - 1] - 1, dp[0]), max(dp[1] + abs(B[i] - B[i - 1]), dp[0] + B[i] - 1)] + return max(dp) diff --git a/codeBase/HackerRank/Algorithms/Dynamic Programming/The Coin Change Problem/solution.py b/codeBase/HackerRank/Algorithms/Dynamic Programming/The Coin Change Problem/solution.py new file mode 100644 index 0000000..21ad5b1 --- /dev/null +++ b/codeBase/HackerRank/Algorithms/Dynamic Programming/The Coin Change Problem/solution.py @@ -0,0 +1,32 @@ +''' + Copyright (C) 2020, Sathira Silva + + Problem Statement: You are working at the cash counter at a fun-fair, and you have different types of coins available to you in + infinite quantities. The value of each coin is already given. Can you determine the number of ways of making change for a particular + number of units using the given types of coins? + + Approach: This another variant of 0-1 Knapsack problem. Given different types of coins in infinite amounts, we have to find how many + number of subsets of coins are there such that the sum of the values of the coins in the subset is equal to the given amount. This + can be easily solved by Dynamic Programming. + + (01). Subproblem: dp[change] + Number of ways of making change for 'change' units. + (02). Guessing: Include the current coin or not? + (03). Recurrence: dp[change] += dp[change - coin] for all changes that can be made upto n and values of the coins. + dp[change] is dp[change] + number of ways of making change when coin 'coin' is included(for change-coin units). + Base Case: dp[0] - Number of ways of making change for 0 units is 1 i.e. doing nothing. + (04). Topological Order: for coins, the order doesn't matter. for change in coin,...,(n + 1) + (05). Original Problem: dp[n] + Number of ways of making change for n units. + + Time Complexity: Less than O(nm); m = number of different coin types +''' + +def getWays(n, coins): + dp = [0] * (n + 1) + # Base Case: Number of ways of making change for 0 units is 1 i.e. doing nothing. + dp[0] = 1 + for coin in coins: + for change in range(coin, n + 1): + dp[change] += dp[change - coin] + return dp[n] diff --git a/codeBase/HackerRank/Algorithms/Game Theory/Deforestation/Solution.cpp b/codeBase/HackerRank/Algorithms/Game Theory/Deforestation/Solution.cpp new file mode 100644 index 0000000..f4add7d --- /dev/null +++ b/codeBase/HackerRank/Algorithms/Game Theory/Deforestation/Solution.cpp @@ -0,0 +1,27 @@ +/* + Copyright (C) 2020, Sathira Silva. +*/ + +#include + +using namespace std; + +int grundy[501]; + +int dfs(int u, int p, vector>& G){ + for(auto ch : G[u]){ + if(ch != p) grundy[u] ^= dfs(ch,u,G); + } + return u == 1 ? grundy[u] : ++grundy[u]; +} + + +string deforestation(int n, vector> tree) { + memset(gr, 0, sizeof(gr)); + vector> graph(n+1); + for(auto p : tree){ + graph[p[0]].push_back(p[1]); + graph[p[1]].push_back(p[0]); + } + return dfs(1, -1, graph) ? "Alice" : "Bob"; +} diff --git a/codeBase/HackerRank/Algorithms/Game Theory/Game of Stones/solution.cpp b/codeBase/HackerRank/Algorithms/Game Theory/Game of Stones/solution.cpp new file mode 100644 index 0000000..cde2740 --- /dev/null +++ b/codeBase/HackerRank/Algorithms/Game Theory/Game of Stones/solution.cpp @@ -0,0 +1,39 @@ +/* + Copyright (C) 2020, Sathira Silva + + Link to the problem: https://www.hackerrank.com/challenges/game-of-stones-1/problem + + Approach: + (1). Identify the winning and losing states of the game: + This game differs from the 1 pile game because there are two losing states, + namely n = 0 and n = 1 in this game. + (2). Compute grundy numbers (or nimbers) for each state and try to come up with a general expression for nth state if possible: + g(0) = 0 | + g(1) = 0 | (Base Cases) + g(2) = mex({0}) = 1 <- Player can remove 2 stones and go to state1 + g(3) = mex({0}) = 1 <- Player can either remove 2 or 3 stones and go to state1 or state0 respectively + g(4) = mex({0, 1}) = 2 <- Player can either remove 2 or 3 stones and go to state2 or state1 + g(5) = mex({0, 1}) = 2 <- Player can remove 2, 3 or 5 stones and go to the states 3, 2 or 0 respectively + g(6) = mex({0, 1, 2}) = 3 + g(7) = mex({1, 2}) = 0 + g(8) = mex({1, 2, 3}) = 0 + g(9) = mex({0, 2, 3}) = 1 + g(10) = mex({0, 2, 3}) = 1 + ... and so on + + It can be observed that the pattern continues in mod 7. Thus, if n mod 7 is not 0 or 1, the game state is winning. +*/ + +#include + +using namespace std; + +int main() { + int t; + cin >> t; + for (int i = 0; i < t; i++) { + int n; + cin >> n; + cout << (n % 7 < 2 ? "Second" : "First") << endl; + } +} diff --git a/codeBase/HackerRank/Algorithms/Game Theory/Stone Division/solution.cpp b/codeBase/HackerRank/Algorithms/Game Theory/Stone Division/solution.cpp new file mode 100644 index 0000000..23c9d37 --- /dev/null +++ b/codeBase/HackerRank/Algorithms/Game Theory/Stone Division/solution.cpp @@ -0,0 +1,49 @@ +/* + Copyright (C) 2020, Sathira Silva. + + Link to the problem: https://www.hackerrank.com/challenges/stone-division/problem + + Approach: + (1). Identify the winning / losing states of the game: + If there doesn't exist a number s in the in the set S such that s divides n, it is a loosing state. Otherwise, the game divides into s equivalent games (because a + single pile splits into s equal piles of size n / s). So, the grundy number of the total game is the nim-sum (XOR sum) of those equivalent games. Thus, if there exists such s + and n / s is even (i.e. n is even), after the split the nim-sum will be 0 (Hence, it's a winning state). Otherwise, g(n / s) where g is the grundy function for the game. + Therefore, if n is odd, after a split we can think of the game as a single pile of size n / s. If the n / s state is a losing state (i.e g(n / s) = 0), n is a winning + state. + (2). Compute grundy numbers: + Clearly, the grundy number of a state n (a pile of size n) is g(n) = 0 if there is no number in set S that divides n. Otherwise, an expression can be formulated as + winning(n) = (n % 2 == 0) or NOT winning(n / s). Therefore, when there exists an s in S such that s | n we have to use dynamic programming with memoization to compute + the result since the expression for winning(n) is recursive. + + (In conclusion, we didn't have to compute the grundy numbers actually. We only checked whether the grundy number of the state after a split is 0 or not) +*/ + +#include + +using namespace std; + +map memo; +vector S; + +bool solve(long long n) { + if (memo.find(n) != memo.end()) + return memo[n]; + memo[n] = false; + for (long long s : S) { + if (n % s != 0) // s is not a divisor of n + continue; + if (n % 2 == 0 || !solve(n / s)) + memo[n] = true; + } + return memo[n]; +} + +int main() { + long long n; + int m; + cin >> n >> m; + S.resize(m); + for (int i = 0; i < m; i++) + cin >> S[i]; + cout << (solve(n) ? "First" : "Second") << endl; +} diff --git a/codeBase/HackerRank/Algorithms/Game Theory/Tower Breakers Again/Solution.cpp b/codeBase/HackerRank/Algorithms/Game Theory/Tower Breakers Again/Solution.cpp new file mode 100644 index 0000000..d0cd54b --- /dev/null +++ b/codeBase/HackerRank/Algorithms/Game Theory/Tower Breakers Again/Solution.cpp @@ -0,0 +1,31 @@ +/* + Copyright (C) 2020, Sathira Silva. +*/ + +#include + +using namespace std; + +int oddPrime(int num) { + int count = 0; + if (num % 2 == 0) + count++; + while (num % 2 == 0) + num /= 2; + for (int i = 3; i <= sqrt(num); i++) { + while (num % i == 0) { + num /= i; + if (i % 2 != 0) count++; + } + } + if (num > 2) + count++; + return count; + } + +int towerBreakers(vector arr) { + int nim = 0; + for (int i = 0; i < arr.size(); i++) + nim ^= oddPrime(arr[i]); + return (nim) ? 1 : 2; +} diff --git a/codeBase/HackerRank/Algorithms/Game Theory/Tower Breakers Revisited/solution.cpp b/codeBase/HackerRank/Algorithms/Game Theory/Tower Breakers Revisited/solution.cpp new file mode 100644 index 0000000..14c487c --- /dev/null +++ b/codeBase/HackerRank/Algorithms/Game Theory/Tower Breakers Revisited/solution.cpp @@ -0,0 +1,36 @@ +''' + Problem Statement: https://www.hackerrank.com/challenges/tower-breakers-revisited-1/problem + + Approach: In this problem, Grundy Number for each pile is the number of prime factors with multiplicity included. + More about Grundy Numbers: https://www.hackerrank.com/topics/game-theory-and-grundy-numbers + http://web.mit.edu/sp.268/www/nim.pdf +''' + +#include + +using namespace std; + +int primeFactors(int n) { + int count = 0; + while (n % 2 == 0) { + n = n / 2; + count += 1; + } + for (int i = 3; i <= sqrt(n); i += 2) { + while (n % i == 0) { + n = n / i; + count += 1; + } + } + if (n > 2) + count += 1; + return count; +} + +int towerBreakers(vector arr) { + int grundy = 0; + for (int i = 0; i < arr.size(); i++) { + grundy ^= primeFactors(arr[i]); + } + return grundy? 1 : 2; +} diff --git a/codeBase/HackerRank/Algorithms/Game Theory/Tower Breakers/solution.py b/codeBase/HackerRank/Algorithms/Game Theory/Tower Breakers/solution.py new file mode 100644 index 0000000..77f0430 --- /dev/null +++ b/codeBase/HackerRank/Algorithms/Game Theory/Tower Breakers/solution.py @@ -0,0 +1,6 @@ +''' + Copyright (C) 2020, Sathira Silva. +''' + +def towerBreakers(n, m): + return 2 if m == 1 or n % 2 == 0 else 1 diff --git a/codeBase/HackerRank/Algorithms/Graph-theory/BFS Shortest Reach/solution.py b/codeBase/HackerRank/Algorithms/Graph-theory/BFS Shortest Reach/solution.py new file mode 100644 index 0000000..9879283 --- /dev/null +++ b/codeBase/HackerRank/Algorithms/Graph-theory/BFS Shortest Reach/solution.py @@ -0,0 +1,61 @@ +''' + Copyright (C) 2020, Sathira Silva. +''' + +from sys import stdin, stdout + +class Node: + def __init__(self, id): + self.id = id + self.adjacent = set() + + +class Graph: + def __init__(self, size, edges): + self.nodes = {} + self.weights = {} + + for i in range(1, size + 1): + self.nodes[i] = Node(i) + + for edge in edges: + u, v, w = edge + self.nodes.get(u).adjacent.add(self.nodes.get(v)) + self.nodes.get(v).adjacent.add(self.nodes.get(u)) + self.weights[(u, v)] = w + self.weights[(v, u)] = self.weights[(u, v)] + + def shortest_path(self, start_id): + queue = [start_id] + distances = [-1] * len(self.nodes) + distances[start_id - 1] = 0 + + while queue: + current_node = queue.pop(0) + for child in self.nodes.get(current_node).adjacent: + if distances[child.id - 1] == -1: + distances[child.id - 1] = distances[current_node - 1] + self.weights[(current_node, child.id)] + queue.append(child.id) + + del distances[start_id - 1] + return distances + + +def bfs(n, m, edges, s): + for i in range(m): + edges[i].append(6) + + graph = Graph(n, edges) + return graph.shortest_path(s) + + +if __name__ == '__main__': + q = int(stdin.readline()) + for q_itr in range(q): + n, m = map(int, stdin.readline().split()) + edges = [] + for _ in range(m): + edges.append(list(map(int, stdin.readline().rstrip().split()))) + s = int(stdin.readline()) + result = bfs(n, m, edges, s) + stdout.write(' '.join(map(str, result)) + '\n') diff --git a/codeBase/HackerRank/Algorithms/Graph-theory/Computer Game/Solution.cpp b/codeBase/HackerRank/Algorithms/Graph-theory/Computer Game/Solution.cpp new file mode 100644 index 0000000..1c7c660 --- /dev/null +++ b/codeBase/HackerRank/Algorithms/Graph-theory/Computer Game/Solution.cpp @@ -0,0 +1,211 @@ +/* + Copyright (C) 2020, Sathira Silva. + + Problem Statement: Sophia is playing a game on the computer. There are two random arrays A & B, each having the same number of + elements. The game begins with Sophia removing a pair (Ai, Bj) from the array if they are not co-prime. She + keeps a count on the number of times this operation is done. + Sophia wants to find out the maximal number of times(S) she can do this on the arrays. Could you help Sophia + find the value? + + Constraints: 0 < n <= 10^5 + 2 <= A[i], B[i] <= 10^9 + Each element in both arrays are generated randomly between 2 and 10^9 + + Approach: (1). Sieve the prime numbers efficiently which are needed to factorize the numbers in array A and B. + (2). Build a network consisting three layers: array A, primes, array B. + (3). Link elements in A and B with their prime factors in the prime layer (with unit edge capacity). + (4). Find the maximum flow (I've used dinitz algorithm). + +*/ + +#include + +using namespace std; + +struct Edge { + int v, flow; + Edge(int v, int flow) : v(v), flow(flow) {} +}; + +bool prime[32000]; +int fprime[32000]; +vector p; +vector> graph; +vector edges; +vector level; +vector last; + +// Sieve of Eratosthenes (Sieve primes upto sqrt(1e9) i.e. upto 3401th prime which is: +// 31607 * 31607 = 999002449). +void sieve() { + memset(prime, true, sizeof(prime)); + prime[0] = prime[1] = false; + for (int i = 2; i * i <= 32000; ++i) + if (prime[i]) + for (int j = i * i; j < 32000; j += i) + if (prime[j]) + { + prime[j] = false; + fprime[j] = i; + } + for (int i = 0 ; i < 32000; i++) + if (prime[i]) + p.push_back(i); +} + +// Find the prime factors of numbers less than 31607. +vector getFactors(int n) { + vector factors; + while (n > 1) { + int r = prime[n] ? n : fprime[n]; + factors.push_back(r); + while (n % r == 0) + n /= r; + } + return factors; +} + +// Handle the numbers larger than 31607. +vector getFactorsBig(int n) { + if (n < 32000) + return getFactors(n); + vector factors; + for (int i = 0; i < p.size() && p[i] * p[i] <= n; i++) { + if (n % p[i] == 0) { + factors.push_back(p[i]); + while (n % p[i] == 0) + n /= p[i]; + } + } + if (n > 1) + factors.push_back(n); + return factors; +} + +// Find augmenting paths using breadth first search. +bool bfs(int s, int t) +{ + level.assign(graph.size(), -1); + level[s] = 0; + queue q; + q.push(s); + while (!q.empty()) + { + int u = q.front(); + q.pop(); + for (int i = 0; i < graph[u].size(); i++) + { + Edge &e = edges[graph[u][i]]; + if (e.flow > 0 && level[e.v] == -1) + { + level[e.v] = level[u] + 1; + q.push(e.v); + } + } + } + return level[t] != -1; +} + +// Augment the augmenting path which is found by the breadth first search. +int dfs(int s, int t, int u, int flow) +{ + if (u == t) + return flow; + for (int &i = last[u]; i < graph[u].size(); i++) + { + int id = graph[u][i]; + Edge &e = edges[id]; + if (e.flow > 0 && level[e.v] == level[u] + 1) + { + int res = dfs(s, t, e.v, min(flow, e.flow)); + if (res > 0) + { + e.flow -= res; + edges[id ^ 1].flow += res; + return res; + } + } + } + level[u] = -1; + return 0; +} + +int computerGame(int n, int A[], int B[]) { + vector primes; + vector> facA(n), facB(n); + // Primes corresponding to elements in A. + for (int i = 0; i < n; i++) { + facA[i] = getFactorsBig(A[i]); + primes.insert(primes.end(), facA[i].begin(), facA[i].end()); + } + // Primes corresponding to elements in B. + for (int i = 0; i < n; i++) { + facB[i] = getFactorsBig(B[i]); + primes.insert(primes.end(), facB[i].begin(), facB[i].end()); + } + // Remove duplicates. + sort(primes.begin(), primes.end()); + primes.erase(unique(primes.begin(), primes.end()), primes.end()); + + int total = 0, N = 2 * n + primes.size() + 2; + int s = 0, t = N - 1; + // Residual graph. + graph.resize(N); + + // Add edges from source to A and B to sink. + for (int i = 1; i <= n; i++) { + edges.push_back(Edge(i, 1)); + edges.push_back(Edge(s, 0)); + graph[s].push_back(edges.size() - 2); + graph[i].push_back(edges.size() - 1); + + edges.push_back(Edge(t, 1)); + edges.push_back(Edge(n + primes.size() + i, 0)); + graph[n + primes.size() + i].push_back(edges.size() - 2); + graph[t].push_back(edges.size() - 1); + } + // Add edges from A to primes. + for (int i = 1; i <= n; i++) { + for (int j = 0; j < facA[i - 1].size(); j++) { + int k = lower_bound(primes.begin(), primes.end(), facA[i - 1][j]) - primes.begin(); + edges.push_back(Edge(n + k + 1, 1)); + edges.push_back(Edge(i, 0)); + graph[i].push_back(edges.size() - 2); + graph[n + k + 1].push_back(edges.size() - 1); + } + } + // Add edges from primes to B. + for (int i = 1 + n + primes.size(); i <= 2 * n + primes.size(); i++) { + for (int j = 0; j < facB[i - n - primes.size() - 1].size(); j++) { + int k = lower_bound(primes.begin(), primes.end(), facB[i - n - primes.size() - 1][j]) - primes.begin(); + edges.push_back(Edge(i, 1)); + edges.push_back(Edge(n + k + 1, 0)); + graph[n + k + 1].push_back(edges.size() - 2); + graph[i].push_back(edges.size() - 1); + } + } + + // Find augmenting paths and augment. + while (bfs(s, t)) { + last.assign(N, 0); + while (int flow = dfs(s, t, s, INT_MAX)) + total += flow; + } + return total; +} + +int main() +{ + ios_base::sync_with_stdio(0); + cin.tie(0); + int n; + cin >> n; + int A[n], B[n]; + for (int i = 0; i < n; i++) + cin >> A[i]; + for (int i = 0; i < n; i++) + cin >> B[i]; + sieve(); + cout << computerGame(n, A, B) << endl; + return 0; +} diff --git a/codeBase/HackerRank/Algorithms/Graph-theory/Dijkstra - Shortest Reach 2/solution.py b/codeBase/HackerRank/Algorithms/Graph-theory/Dijkstra - Shortest Reach 2/solution.py new file mode 100644 index 0000000..149af99 --- /dev/null +++ b/codeBase/HackerRank/Algorithms/Graph-theory/Dijkstra - Shortest Reach 2/solution.py @@ -0,0 +1,48 @@ +''' + Copyright (C) 2020, Sathira Silva. +''' + +from collections import defaultdict +from heapq import heappop, heappush +from sys import stdin, stdout + +def shortestReach(n, edges, s): + graph = defaultdict(list) + for (u, v), w in edges.items(): + graph[u].append((w, v)) + graph[v].append((w, u)) + + visited = [False for _ in range(n + 1)] + distance = [float("inf") for _ in range(n + 1)] + distance[s] = 0 + minHeap = [(distance[s], s)] + + while minHeap: + d, u = heappop(minHeap) + if visited[u]: + continue + visited[u] = True + for w, v in graph[u]: + if not visited[v] and distance[v] > d + w: + distance[v] = d + w + heappush(minHeap, (distance[v], v)) + del distance[s] + del distance[0] + return [-1 if d == float("inf") else d for d in distance] + +if __name__ == '__main__': + t = int(stdin.readline()) + for t_itr in range(t): + n, m = map(int, stdin.readline().split()) + edges = defaultdict(int) + for _ in range(m): + u, v, w = map(int, stdin.readline().rstrip().split()) + if (u, v) in edges: + edges[(u, v)] = min(edges[(u, v)], w) + elif (v, u) in edges: + edges[(v, u)] = min(edges[(v, u)], w) + else: + edges[(u, v)] = w + s = int(stdin.readline()) + result = shortestReach(n, edges, s) + stdout.write(' '.join(map(str, result)) + '\n') diff --git a/codeBase/HackerRank/Algorithms/Graph-theory/Floyd-City-of-Blinding-Lights/Solution.java b/codeBase/HackerRank/Algorithms/Graph-theory/Floyd-City-of-Blinding-Lights/Solution.java new file mode 100644 index 0000000..600bd59 --- /dev/null +++ b/codeBase/HackerRank/Algorithms/Graph-theory/Floyd-City-of-Blinding-Lights/Solution.java @@ -0,0 +1,142 @@ +/* + gihanjayatilaka[at]eng[dot]pdn[dot]ac[dot]lk + 2016 + https://www.hackerrank.com/challenges/floyd-city-of-blinding-lights/problem + This submission passed all test cases +*/ +import java.util.Scanner; +public class Solution { + static Scanner sc=new Scanner(System.in); + + public static void main(String[] args){ + runOnce(); + } + + public static void runOnce(){ + int N=sc.nextInt(); + int M=sc.nextInt(); + + WeightedGraph graph=new WeightedGraph(N); + + for(int x=0;x=minDistances[x]){ + nodeNo=x; + minDistance=minDistances[x]; + } + } + return nodeNo; + } + + public static boolean unvisitedNodesRemain(boolean[] visitedNodes,int[] minDistances){ + boolean ans=false; + for(int x=0;x connectedTo; + + GraphNode(){ + connectedTo=new ArrayList(); + } + + + public void connectTo(int x){ + connectedTo.add(x); + } + +} + + + +class Solution{ + static Scanner sc=new Scanner(System.in); + static boolean[] covered; + static GraphNode[] ar; + static ArrayList road; + static ArrayList sets=new ArrayList(); + public static void main(String[] args){ + int N=sc.nextInt(); + int M=sc.nextInt(); + + covered=new boolean[N]; + ar=new GraphNode[N]; + + for(int z=0;z(); + dfs(x,road); + sets.add(road.size()); + //System.out.println(x+" "+road.size()); + } + } + + long ans=0; + + for(int x=0;x road){ + covered[x]=true; + road.add(x); + for(int y=0;y= |Px| for all descendants x of u. + + Height of a vertex: The height of a vertex u in a tree T, denoted as height(u), is the number of levels we have to go + through, if we want to travel from u to one of its deepest descendants (which is a leaf). Note that here, the leaves + are defined to have height 1. i.e. height(u) = #vertices on the path from u to one of its deepest descendants + + Ancestor: An ancestor node of a node is any node in the path from that node to the root node (including the root node). + The immediate ancestor of a node is the "parent" node. + + + The Level Ancestor Problem: Let T = (V, E) be a rooted tree with |V| = n, |E| = n - 1. Pre-process the tree and + answer the level ancestor queries (find the ancestor v of the query node u at depth K + depth(u) / Kth ancestor + / Kth parent). + + LA_T(u, K) = v, if v is the unique ancestor of u with depth(v) = depth(u) - K. + LA_T(u, K) = 0, if such an ancestor doesn’t exist. + + NOTE: LA_T (u, root) = u and LA_T (u, depth(u)) = root ∀u ∈ V. + + + There're three different Algorithms to solve the Level Ancestor Problem: + (1). Table Algorithm (O(n^2) time for preprocessing, O(1) time for answer a query) + (2). Jump - Pointer Algorithm (O(nlogn) time for preprocessing, O(logn) for answer a query) + (3). Ladder Algorithm (O(n) time for preprocessing, O(logn) time for answer a query) + + Table Algorithm is a naive approach using Dynamic Programming to fill a table: table[i][j] which is the ancestor of + node j at depth i therefore the table will be n x n in size. + + But I've used the Jump-Pointer Algorithm for this problem because O(nlogn) + O(logn) time is sufficient to pass the + test cases. The solution is coded in an object-oriented way for the simplicity. + + I have created two separate objects as Graph (for graph traversal) and Tree (for the operations in the tree). After the + edges of the tree are added to the graph, a Breadth-First Search traversal is done on it to build the Tree by traversing + level by level while filling the depth dictionary which contains the depths of each vertex. + + When queries are asked the find method is called from the Tree object to find the kth ancestor if exists, using the + parents dictionary and the pre-calculated depth dictionary. To find the kth ancestor, according to the Jump-Pointer + Algorithm, the smallest possible k value of the node is calculated, which is: floor(log2(k)). Then, we set the ancestor + to be floor(log2(k))th ancestor of the node and parent array of the node to be the parents of the floor(log2(k))th + ancestor. Next, k is reduced by 2^floor(log2(k)). These four steps are repeated until the k value is reached 0 (This + is actually a binary search over the ancestors of the node). + + Time Complexity: O((n + 1)log(n)) in total. +''' + +import math +from collections import defaultdict +from sys import stdin, stdout + + +class Graph: + def __init__(self): + self.edges = defaultdict(list) + self.root = None + + def add(self, node, parent): + # Node is the root of the tree + if parent == 0: + self.root = node + self.edges[node] = [] + else: + self.edges[parent].append(node) + self.edges[node] = [] + + # Traverse the tree level by level to find the depths of each node with respect to the root of the node. + def bfs(self, tree): + tree.add(self.root, 0) + visited = {x: False for x in self.edges.keys()} + queue = [self.root] + while queue: + u = queue.pop(0) + for v in self.edges[u]: + if not visited[v]: + tree.add(v, u) + queue.append(v) + visited[u] = True + + +class Tree: + def __init__(self): + self.root = None + self.parents = defaultdict(list) + self.depth = defaultdict(int) + + def add(self, node, parent): + # Node is the root of the tree + if parent == 0: + self.root = node + # Initialize the depth of the root vertex as 0. + self.depth[node] = 0 + return + self.parents[node].append(parent) + ancestors = self.parents[parent] + depth = 0 + # Find the depth of the node using the depths of its parents (ancestors). + while len(ancestors) > depth: + p = ancestors[depth] + self.parents[node].append(p) + ancestors = self.parents[p] + depth += 1 + self.depth[node] = self.depth[parent] + 1 + + def find(self, node, kthAncestor): + # Node is the root of the tree or it doesn't exist in the current tree. + if not self.parents[node]: + return 0 + # Can't find the ancestor of the node because level of the ancestor is less than 0 (below the root). + if kthAncestor > self.depth[node]: + return 0 + ancestor = 0 + ancestors = self.parents[node] + # Binary Search + Jump-Pointer Algorithm + while kthAncestor > 0: + k = int(math.floor(math.log(kthAncestor, 2))) + ancestor = ancestors[k] + ancestors = self.parents[ancestor] + kthAncestor = kthAncestor - (1 << k) + return ancestor + + def delete(self, node): + if node == self.root: + self.root = None + del self.parents[node] + + +T = int(stdin.readline()) +for _ in range(T): + P = int(stdin.readline()) + tree = Tree() + graph = Graph() + for __ in range(P): + x, y = list(map(int, stdin.readline().split())) + graph.add(x, y) + # Preprocessing + graph.bfs(tree) + queries = int(stdin.readline()) + for ___ in range(queries): + query = list(map(int, stdin.readline().split())) + if query[0] == 0: + tree.add(query[2], query[1]) + if query[0] == 1: + tree.delete(query[1]) + if query[0] == 2: + stdout.write(str(tree.find(query[1], query[2])) + '\n') diff --git a/codeBase/HackerRank/Algorithms/Graph-theory/Minimum Penalty Path/solution.py b/codeBase/HackerRank/Algorithms/Graph-theory/Minimum Penalty Path/solution.py new file mode 100644 index 0000000..1054476 --- /dev/null +++ b/codeBase/HackerRank/Algorithms/Graph-theory/Minimum Penalty Path/solution.py @@ -0,0 +1,26 @@ +''' + Copyright (C) 2020, Sathira Silva. +''' + + +from collections import defaultdict +from heapq import heappop, heappush + +def beautifulPath(edges, A, B): + graph = defaultdict(list) + for u, v, w in edges: + graph[u].append((w, v)) + graph[v].append((w, u)) + visited = [[False] * 1024 for _ in range(n + 1)] + visited[A][0] = True + minHeap = [(0, A)] + while minHeap: + d, u = heappop(minHeap) + for w, v in graph[u]: + if not visited[v][d | w]: + visited[v][d | w] = True + heappush(minHeap, (d | w, v)) + for i in range(1024): + if visited[B][i]: + return i + return -1 diff --git a/codeBase/HackerRank/Algorithms/Graph-theory/Prims (MST): Special Subtree/solution.py b/codeBase/HackerRank/Algorithms/Graph-theory/Prims (MST): Special Subtree/solution.py new file mode 100644 index 0000000..e9d65be --- /dev/null +++ b/codeBase/HackerRank/Algorithms/Graph-theory/Prims (MST): Special Subtree/solution.py @@ -0,0 +1,28 @@ +''' + Copyright (C) 2020, Sathira Silva. +''' + +from collections import defaultdict +from heapq import heappop, heappush + +def prim(n, edges, start): + graph = defaultdict(list) + for u, v, w in edges: + graph[u].append((w, v)) + graph[v].append((w, u)) + + weight = [float("inf")] * (n + 1) + visited = [False] * (n + 1) + weight[0] = 0 + weight[start] = 0 + minHeap = [(weight[start], start)] + while minHeap: + _, u = heappop(minHeap) + if visited[u]: + continue + visited[u] = True + for w, v in graph[u]: + if not visited[v] and w < weight[v]: + weight[v] = w + heappush(minHeap, (weight[v], v)) + return sum(weight) diff --git a/codeBase/HackerRank/Algorithms/Graph-theory/Roads In Hackerland/solution(KruskalsAlgorithm).py b/codeBase/HackerRank/Algorithms/Graph-theory/Roads In Hackerland/solution(KruskalsAlgorithm).py new file mode 100644 index 0000000..7007cdc --- /dev/null +++ b/codeBase/HackerRank/Algorithms/Graph-theory/Roads In Hackerland/solution(KruskalsAlgorithm).py @@ -0,0 +1,61 @@ +''' + Copyright (C) 2020, Sathira Silva. +''' + +from sys import stdin, stdout +from collections import defaultdict + + +def dfs(n, source, tree, ans, p=0): + total = 1 + for v, w in tree[source]: + if v != p: + children = dfs(n, v, tree, ans, source) + ans[w] += (n - children) * children + total += children + return total + +# Find the parent vertex of u + + +def find_set(u, inSet): + # Current parent of u = inSet[u] + while u != inSet[inSet[u]]: + # Set parent of u to parent of parent of u + inSet[u] = inSet[inSet[u]] + # Set u to parent of u + u = inSet[u] + return u + + +def union(u, v, s): + # Set parent of parent of v to parent of u + s[find_set(v, s)] = find_set(u, s) + + +def roadsInHackerland(n, roads): + # Kruskal's Algorithm to find the MST + tree = defaultdict(list) + parent = [i for i in range(n)] # Indices of vertices + roads.sort(key=lambda x: x[2]) + for u, v, w in roads: + if find_set(u, parent) != find_set(v, parent): + union(u, v, parent) + tree[u].append((v, w)) + tree[v].append((u, w)) + ans = [0] * 2 * len(roads) # Total number of degrees of vertices + dfs(n, 0, tree, ans) + s = 0 + for i in range(len(ans)): + s += ans[i] * (1 << i) + return bin(s)[2:] + + +if __name__ == '__main__': + n, m = map(int, stdin.readline().split()) + roads = [] + for _ in range(m): + u, v, w = map(int, stdin.readline().rstrip().split()) + roads.append([u - 1, v - 1, w]) + result = roadsInHackerland(n, roads) + stdout.write(result + '\n') diff --git a/codeBase/HackerRank/Algorithms/Graph-theory/Roads In Hackerland/solution(PrimsAlgorithm).py b/codeBase/HackerRank/Algorithms/Graph-theory/Roads In Hackerland/solution(PrimsAlgorithm).py new file mode 100644 index 0000000..36058a4 --- /dev/null +++ b/codeBase/HackerRank/Algorithms/Graph-theory/Roads In Hackerland/solution(PrimsAlgorithm).py @@ -0,0 +1,58 @@ +''' + Copyright (C) 2020, Sathira Silva. +''' + +from collections import defaultdict +from heapq import heappop, heappush + + +def dfs(n, source, tree, ans, p=0): + total = 1 + for v, w in tree[source]: + if v != p: + children = dfs(n, v, tree, ans, source) + ans[w] += (n - children) * children + total += children + return total + + +def roadsInHackerland(n, roads): + # Prim's Algorithm to find the MST + hackerland = defaultdict(list) + parent = dict() + for u, v, w in roads: + hackerland[u].append((w, v)) + hackerland[v].append((w, u)) + + s = 0 + + weight = [float("inf")] * (n + 1) + visited = [False] * (n + 1) + weight[0] = 0 + weight[1] = 0 + minHeap = [(weight[1], 1)] + while minHeap: + _, u = heappop(minHeap) + if visited[u]: + continue + visited[u] = True + for w, v in hackerland[u]: + if not visited[v] and w < weight[v]: + weight[v] = w + parent[v] = (u, weight[v]) + heappush(minHeap, (weight[v], v)) + + mst = defaultdict(list) + + for u, (v, w) in parent.items(): + mst[u].append((v, w)) + mst[v].append((u, w)) + + # Total degree of vertices = 2 * Number of Edges + ans = [0] * 2 * len(roads) + + dfs(n, 1, mst, ans) + for i in range(len(ans)): + s += ans[i] * (1 << i) + + return bin(s)[2:] diff --git a/codeBase/HackerRank/Algorithms/Graph-theory/Roads and Libraries/solution.py b/codeBase/HackerRank/Algorithms/Graph-theory/Roads and Libraries/solution.py new file mode 100644 index 0000000..1a06cf8 --- /dev/null +++ b/codeBase/HackerRank/Algorithms/Graph-theory/Roads and Libraries/solution.py @@ -0,0 +1,51 @@ +''' + Copyright (C) 2020, Sathira Silva. +''' + +class Node: + def __init__(self, id): + self.id = id + self.adjacent = set() + + def __eq__(self, node): + return self.id == node.id + + def __hash__(self): + return hash(self.id) + +class Graph: + def __init__(self, size, edges): + self.nodes = {} + + for i in range(1, size + 1): + self.nodes[i] = Node(i) + + for edge in edges: + u, v = edge + self.nodes.get(u).adjacent.add(self.nodes.get(v)) + self.nodes.get(v).adjacent.add(self.nodes.get(u)) + + def find_clusters(self, node, visited, count): + visited[node] = True + for child in self.nodes.get(node).adjacent: + if not visited[child.id]: + count = 1 + self.find_clusters(child.id, visited, count) + return count + + def rebuild_hackerland_optimally(self, c_lib, c_road): + result = 0 + visited = [False] * (len(self.nodes) + 1) + for node in self.nodes: + if not visited[node]: + cluster_size = self.find_clusters(node, visited, 1) + print(cluster_size) + result += c_lib + if c_lib > c_road: + result += (cluster_size - 1) * c_road + else: + result += (cluster_size - 1) * c_lib + return result + +def roadsAndLibraries(n, c_lib, c_road, cities): + hackerland = Graph(n, cities) + return hackerland.rebuild_hackerland_optimally(c_lib, c_road) diff --git a/codeBase/HackerRank/Algorithms/Graph-theory/Subset Component/solution.py b/codeBase/HackerRank/Algorithms/Graph-theory/Subset Component/solution.py new file mode 100644 index 0000000..47cade1 --- /dev/null +++ b/codeBase/HackerRank/Algorithms/Graph-theory/Subset Component/solution.py @@ -0,0 +1,29 @@ +''' + Copyright (C) 2020, Sathira Silva. +''' + +from sys import stdin, stdout + +def findConnectedComponents(i, previous_components, d): + if i == len(d): + return len(previous_components) + count_cc = findConnectedComponents(i + 1, previous_components, d) + currentComponent = d[i] + components = [] + for cc in previous_components: + if cc & currentComponent: + currentComponent |= cc + else: + components.append(cc) + if currentComponent: + components.append(currentComponent) + count_cc += findConnectedComponents(i + 1, components, d) + return count_cc + + +if __name__ == '__main__': + d_count = int(stdin.readline()) + d = list(map(int, stdin.readline().rstrip().split())) + singletons = [1 << j for j in range(64)] + components = findConnectedComponents(0, singletons, d) + stdout.write(str(components) + '\n') diff --git a/codeBase/HackerRank/Algorithms/Graph-theory/Synchronous Shopping/solution.py b/codeBase/HackerRank/Algorithms/Graph-theory/Synchronous Shopping/solution.py new file mode 100644 index 0000000..4d3502d --- /dev/null +++ b/codeBase/HackerRank/Algorithms/Graph-theory/Synchronous Shopping/solution.py @@ -0,0 +1,45 @@ +from collections import defaultdict +from heapq import heappop, heappush +from sys import stdin, stdout + + +def search(n, k, centers, roads): + city = defaultdict(list) + for a, b, c in roads: + city[a].append((b, c)) + city[b].append((a, c)) + k = (1 << k) - 1 + queue = [[] for _ in range(k + 1)] + visited = [set() for _ in range(k + 1)] + last_cat = {0: 0} + heappush(queue[centers[0]], (0, 1)) + time = float("inf") + for i in range(k + 1): + while queue[i]: + d, u = heappop(queue[i]) + if u == n: + for fishes, dist in last_cat.items(): + if i | fishes == k: + time = min(time, max(dist, d)) + last_cat[i] = min(d, last_cat.get(i, float("inf"))) + if u in visited[i]: + continue + visited[i].add(u) + for v, w in city[u]: + fishes = centers[v - 1] | i + if v not in visited[fishes]: + heappush(queue[fishes], (w + d, v)) + return time + + +if __name__ == '__main__': + n, m, k = map(int, stdin.readline().rstrip().split()) + centers = [] + for _ in range(n): + centers_item = sum(map(lambda x: 1 << (x - 1), map(int, stdin.readline().split()[1:]))) + centers.append(centers_item) + roads = [] + for _ in range(m): + roads.append(list(map(int, stdin.readline().rstrip().split()))) + res = search(n, k, centers, roads) + stdout.write(str(res) + '\n') diff --git a/codeBase/HackerRank/Algorithms/Graph-theory/Tree Flow/README.md b/codeBase/HackerRank/Algorithms/Graph-theory/Tree Flow/README.md new file mode 100644 index 0000000..91eaff6 --- /dev/null +++ b/codeBase/HackerRank/Algorithms/Graph-theory/Tree Flow/README.md @@ -0,0 +1,11 @@ +**Problem Statement**: Recall that a tree is an undirected, connected acyclic graph. We have a weighted tree, ![$T$](https://render.githubusercontent.com/render/math?math=%24T%24), with ![$n$](https://render.githubusercontent.com/render/math?math=%24n%24) vertices; let ![$dist_{u, v}$](https://render.githubusercontent.com/render/math?math=%24dist_%7Bu%2C%20v%7D%24) be the total sum of edge weights on the path between nodes ![$u$](https://render.githubusercontent.com/render/math?math=%24u%24) and ![$v$](https://render.githubusercontent.com/render/math?math=%24v%24). + +Let's consider all the matrices, ![$A_{u, v}$](https://render.githubusercontent.com/render/math?math=%24A_%7Bu%2C%20v%7D%24) such that: + +* ![$A_{u,v} = -A_{u,v}$](https://render.githubusercontent.com/render/math?math=%24A_%7Bu%2Cv%7D%20%3D%20-A_%7Bu%2Cv%7D%24) +* ![$0 \leq |A_{u,v}| \leq dist_{v, u}$](https://render.githubusercontent.com/render/math?math=%240%20%5Cleq%20%7CA_%7Bu%2Cv%7D%7C%20%5Cleq%20dist_%7Bv%2C%20u%7D%24) +* ![$\sum_{i=1}^{n} A_{u,i} = 0$](https://render.githubusercontent.com/render/math?math=%24%5Csum_%7Bi%3D1%7D%5E%7Bn%7D%20A_%7Bu%2Ci%7D%20%3D%200%24) for each ![$u\neq 1,n$](https://render.githubusercontent.com/render/math?math=%24u%5Cneq%201%2Cn%24) for each ![$u\neq 1$](https://render.githubusercontent.com/render/math?math=%24u%5Cneq%201%24) and ![$u\neq n$](https://render.githubusercontent.com/render/math?math=%24u%5Cneq%20n%24) + +We consider the total value of matrix ![$A$](https://render.githubusercontent.com/render/math?math=%24A%24) to be: + ![$\sum_{i=1}^{n} A_{1,i}$](https://render.githubusercontent.com/render/math?math=%24%5Csum_%7Bi%3D1%7D%5E%7Bn%7D%20A_%7B1%2Ci%7D%24) +Calculate and print the maximum total value of ![$A$](https://render.githubusercontent.com/render/math?math=%24A%24) for a given tree, ![$T$](https://render.githubusercontent.com/render/math?math=%24T%24). diff --git a/codeBase/HackerRank/Algorithms/Graph-theory/Tree Flow/solution.py b/codeBase/HackerRank/Algorithms/Graph-theory/Tree Flow/solution.py new file mode 100644 index 0000000..513d804 --- /dev/null +++ b/codeBase/HackerRank/Algorithms/Graph-theory/Tree Flow/solution.py @@ -0,0 +1,35 @@ +''' + Copyright (C) 2020, Sathira Silva. +''' + +from collections import defaultdict +from sys import stdin, stdout +from heapq import heappop, heappush + +def dijkstra(n, graph, u): + distance = [float("inf")] * (n + 1) + distance[u] = 0 + visited = [False] * (n + 1) + visited[u] = True + queue = [(distance[u], u)] + while queue: + d, u = heappop(queue) + for v, w in graph[u]: + if not visited[v] and distance[v] > d + w: + visited[v] = True + distance[v] = d + w + heappush(queue, (distance[v], v)) + return distance[1:] + +def treeFlow(n, tree): + graph = defaultdict(list) + for u, v, w in tree: + graph[u].append((v, w)) + graph[v].append((u, w)) + return min(sum(dijkstra(n, graph, 1)), sum(dijkstra(n, graph, n))) + +if __name__ == '__main__': + n = int(stdin.readline()) + tree = [list(map(int, stdin.readline().rstrip().split())) for _ in range(n - 1)] + result = treeFlow(n, tree) + stdout.write(str(result) + '\n') diff --git a/codeBase/HackerRank/Algorithms/Greedy/Candies/solution.py b/codeBase/HackerRank/Algorithms/Greedy/Candies/solution.py new file mode 100644 index 0000000..efa6615 --- /dev/null +++ b/codeBase/HackerRank/Algorithms/Greedy/Candies/solution.py @@ -0,0 +1,25 @@ +''' + Copyright (C) 2020, Sathira Silva. + + Problem Statement: Alice is a kindergarten teacher. She wants to give some candies to the children in her class. All the children + sit in a line and each of them has a rating score according to his or her performance in the class. Alice wants + to give at least 1 candy to each child. If two children sit next to each other, then the one with the higher + rating must get more candies. Alice wants to minimize the total number of candies she must buy. + + Approach: Since each child must get at least one candy, give one candy per child initially. Then traverse the children starting from + the 1st index and give them one more candy if that child's rating is higher than the previous child. Then traverse the + children backwards starting from the child before the last index and compare the child's rating with the child sitting + next to him. If that child's rating is higher than the child sitting next to him, make a greedy choice to give candies + to him i.e. if the child has candies more than the next child, don't give any candies to him. Otherwise get all the candies + he currently has and give him candies one more than the amount of the next child has. +''' + +def candies(n, arr): + candyCount = [1] * n + for i in range(1, len(arr)): + if arr[i] > arr[i - 1]: + candyCount[i] = candyCount[i - 1] + 1 + for i in range(len(arr) - 2, -1, -1): + if arr[i] > arr[i + 1]: + candyCount[i] = max(candyCount[i], candyCount[i + 1] + 1) + return sum(candyCount) diff --git a/codeBase/HackerRank/Algorithms/Greedy/Chief Hopper/solution.py b/codeBase/HackerRank/Algorithms/Greedy/Chief Hopper/solution.py new file mode 100644 index 0000000..def3316 --- /dev/null +++ b/codeBase/HackerRank/Algorithms/Greedy/Chief Hopper/solution.py @@ -0,0 +1,22 @@ +''' + Copyright (C) 2020, Sathira Silva. + + Problem Statement: https://www.hackerrank.com/challenges/chief-hopper/problem + + Approach: Since the bot must pass the last building with the lowest energy, traverse the bulidings backwards and find the the + energy required using the given formula. +''' + +from sys import stdin, stdout + +def chiefHopper(buildings): + minEnergy = 0 + for height in reversed(buildings): + minEnergy = (1 + height + minEnergy) // 2 + return minEnergy + +if __name__ == '__main__': + n = int(stdin.readline()) + arr = list(map(int, stdin.readline().rstrip().split())) + result = chiefHopper(arr) + stdout.write(str(result) + '\n') diff --git a/codeBase/HackerRank/Algorithms/Search/Bike Racers/Solution.cpp b/codeBase/HackerRank/Algorithms/Search/Bike Racers/Solution.cpp new file mode 100644 index 0000000..c9cf071 --- /dev/null +++ b/codeBase/HackerRank/Algorithms/Search/Bike Racers/Solution.cpp @@ -0,0 +1,130 @@ +/* + Copyright (C) 2020, Sathira Silva. + + Problem Statement: There are N bikers present in a city (shaped as a grid) having M bikes. All the bikers want to participate in + the HackerRace competition, but unfortunately only K bikers can be accommodated in the race. Jack is organizing + the HackerRace and wants to start the race as soon as possible. He can instruct any biker to move towards any + bike in the city. In order to minimize the time to start the race, Jack instructs the bikers in such a way that + the first K bikes are acquired in the minimum time. + Every biker moves with a unit speed and one bike can be acquired by only one biker. A biker can proceed in any + direction. Consider distance between bikes and bikers as Euclidean distance. + Jack would like to know the square of required time to start the race as soon as possible. + + Approach: Assume we know the minimum time required for the K bikers to aquire one bike for each. Now all we have to do is to find + the maximum matches possible to match at most one bike to one biker which is a bipartite matching problem. Then we have + to find the minimum time that K bikes can be aquired. Since we know the lower bound and upper bound for the time + required to aquire bikes, a simple binary search will solve this problem. I've used hopcroft-karp algorithm to match + the bipartites because it only requires O(sqrt(N + M) * NM) time. + + Total Time Complexity: O(log(1e14) * sqrt(N + M) * NM) +*/ + +#include + +using namespace std; + +typedef long long int lli; +int n, m, k; +// d[i][j] : Euclidean squared distance from ith biker to kth bike. +// augDistance[u] : Distance of the current augmenting path to vertex u. +lli d[251][251], augDistance[251]; +// Initially unmatched vertices in each partite to store the matches. +int unmatchedBikers[251], unmatchedBikes[251]; +vector biGraph[251]; +const lli INF = 2e9; + +bool dfs(int biker) { + if (biker != 0) { + for (int bike: biGraph[biker]) { + if (augDistance[unmatchedBikes[bike]] == augDistance[biker] + 1) { + if(dfs(unmatchedBikes[bike])) { + unmatchedBikes[bike] = biker; + unmatchedBikers[biker] = bike; + return true; + } + } + } + augDistance[biker] = INF; + return false; + } + return true; +} + +bool bfs() { + queue q; + for (int i = 1; i <= n; i++) { + if (unmatchedBikers[i] == 0) { + augDistance[i] = 0; + q.push(i); + } + else + augDistance[i] = INF; + } + augDistance[0] = INF; + while (!q.empty()) { + int biker = q.front(); + q.pop(); + if (augDistance[biker] < augDistance[0]) { + for (int bike: biGraph[biker]) { + if (augDistance[unmatchedBikes[bike]] == INF) { + augDistance[unmatchedBikes[bike]] = augDistance[biker] + 1; + q.push(unmatchedBikes[bike]); + } + } + } + } + return augDistance[0] != INF; +} + +int hopcroftKarp() { + memset(unmatchedBikers, 0, sizeof(unmatchedBikers)); + memset(unmatchedBikes, 0, sizeof(unmatchedBikes)); + int matches = 0; + while (bfs()) { + for (int i = 1; i <= n; i++) + if (unmatchedBikers[i] == 0 && dfs(i)) + matches++; + } + return matches; +} + +bool can(lli squaredT) { + for (int i = 1; i <= n; i++) { + biGraph[i].clear(); + for (int j = 1; j <= m; j++) { + if (d[i][j] <= squaredT) { + biGraph[i].push_back(j); + } + } + } + if (hopcroftKarp() >= k) + return true; + return false; +} + +int main() +{ + ios_base::sync_with_stdio(false); + cin.tie(NULL); + cin >> n >> m >> k; + pair bikers[n + 1]; + pair bikes[m + 1]; + for (int i = 1; i <= n; i++) + cin >> bikers[i].first >> bikers[i].second; + for (int i = 1; i <= m; i++) + cin >> bikes[i].first >> bikes[i].second; + // Distances from ith biker to jth bike. + for (int i = 1; i <= n; i++) + for (int j = 1; j <= m; j++) + d[i][j] = (bikers[i].first - bikes[j].first) * (bikers[i].first - bikes[j].first) + (bikers[i].second - bikes[j].second) * (bikers[i].second - bikes[j].second); + // Binary search for the minimum squared time. + lli low = 0, high = 1e14; // (Search upto the squared value of max possible distance) + while (low < high) { + lli minSquaredT = (low + high) / 2; + if (can(minSquaredT)) + high = minSquaredT; + else + low = minSquaredT + 1; + } + cout << low << endl; +} diff --git a/codeBase/HackerRank/Algorithms/Search/Connected Cells in a Grid/Solution.cpp b/codeBase/HackerRank/Algorithms/Search/Connected Cells in a Grid/Solution.cpp new file mode 100644 index 0000000..89d3771 --- /dev/null +++ b/codeBase/HackerRank/Algorithms/Search/Connected Cells in a Grid/Solution.cpp @@ -0,0 +1,60 @@ +/* + Copyright (C) 2020, Sathira Silva. + + Problem Statement: https://www.hackerrank.com/challenges/connected-cell-in-a-grid/problem + + Approach: Run BFS on each cell to find the number of cells in filled regions (Floodfill Algorithm). + + Time Complexity: O(nm) +*/ + +#include + +using namespace std; + +int n, m, cells; +bool visited[11][11]; +int grid[11][11]; +const int directions[8][2] = {{1, 0}, {0, 1}, {1, 1}, {-1, 0}, {0, -1}, {1, -1}, {-1, 1}, {-1, -1}}; + +void bfs(int x, int y) { + visited[x][y] = true; + queue> q; + q.push({x, y}); + while (!q.empty()) { + int x0 = q.front().first; + int y0 = q.front().second; + q.pop(); + for (int i = 0; i < 8; i++) { + int x1 = x0 + directions[i][0]; + int y1 = y0 + directions[i][1]; + if (x1 >= 0 && x1 < n && y1 >= 0 && y1 < m && !visited[x1][y1] && grid[x1][y1]) { + cells++; + visited[x1][y1] = true; + q.push({x1, y1}); + } + } + } +} + +int main() +{ + ios_base::sync_with_stdio(false); + cin.tie(NULL); + int maxCells = -1; + cin >> n >> m; + for (int i = 0; i < n; i++) + for (int j = 0; j < m; j++) + cin >> grid[i][j]; + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + if (!visited[i][j] && grid[i][j]) { + cells = 0; + bfs(i, j); + maxCells = max(maxCells, cells); + } + } + } + cout << maxCells + 1 << endl; + return 0; +} diff --git a/codeBase/HackerRank/Algorithms/Search/Cut The Tree/Solution.cpp b/codeBase/HackerRank/Algorithms/Search/Cut The Tree/Solution.cpp new file mode 100644 index 0000000..48756fc --- /dev/null +++ b/codeBase/HackerRank/Algorithms/Search/Cut The Tree/Solution.cpp @@ -0,0 +1,51 @@ +/* + Copyright (C) 2020, Sathira Silva. + + Problem Statement: Anna loves graph theory! She has a tree where each vertex is numbered from 1 to n, and each contains a data + value. The sum of a tree is the sum of all its nodes' data values. If she cuts an edge in her tree, she forms + two smaller trees. The difference between two trees is the absolute value between their sums. + Given a tree, determine which edge to cut so that the resulting trees have a minimal difference between them, + then return that difference. + + Approach: Run DFS from root vertex to find all the subtree weights. +*/ + +#include + +using namespace std; + +int n, minDifference, totalWeight; +const int MAX = (int) pow(10, 5) + 1; +vector tree[MAX]; +int weight[MAX]; +bool visited[MAX]; + +int dfs(int u) { + int w = weight[u]; + visited[u] = true; + for (int v: tree[u]) + if (!visited[v]) + w += dfs(v); + // Deduct w twice because totalWeight of the tree includes weight of the subtree w. + minDifference = min(minDifference, abs(totalWeight - 2 * w)); + return w; +} + +int main() +{ + ios_base::sync_with_stdio(false); + cin.tie(NULL); + cin >> n; + for (int i = 1; i <= n; i ++) + cin >> weight[i]; + for (int i = 0; i < n; i++) { + int u, v; + cin >> u >> v; + tree[u].push_back(v); + tree[v].push_back(u); + } + minDifference = 1e9, totalWeight = accumulate(weight, weight + n + 1, 0); + dfs(1); + cout << minDifference << endl; + return 0; +} diff --git a/codeBase/HackerRank/Algorithms/Search/KnightL on a Chessboard/Solution.cpp b/codeBase/HackerRank/Algorithms/Search/KnightL on a Chessboard/Solution.cpp new file mode 100644 index 0000000..059a690 --- /dev/null +++ b/codeBase/HackerRank/Algorithms/Search/KnightL on a Chessboard/Solution.cpp @@ -0,0 +1,48 @@ +''' + Copyright (C) 2020, Sathira Silva. + + Problem Statement: https://www.hackerrank.com/challenges/knightl-on-chessboard/copy-from/155879319 + + Approach: Run bfs for each a = 1 to n - 1 and b = a to n - 1 because of the symmetry in the KnightL(a, b) = KnightL(b, a). +''' + +#include + +using namespace std; + +const int INF = 1e9; + +int bfs(int a, int b, int n) { + queue> q; + int distance[n][n]; + for (int i = 0; i < n; i++) + for (int j = 0 ; j < n; j++) + distance[i][j] = INF; + vector> directions = {{a, b}, {b, a}, {a, -b}, {b, -a}, {-a, b}, {-b, a}, {-a, -b}, {-b, -a}}; + q.push({0, 0}); + distance[0][0] = 0; + int x1, y1; + while (!q.empty()) { + x1 = q.front().first; + y1 = q.front().second; + q.pop(); + for (auto dxdy: directions) { + int dx = dxdy.first, dy = dxdy.second; + if (dx + x1 >= 0 && dx + x1 < n && dy + y1 >= 0 && dy + y1 < n && distance[dx + x1][dy + y1] > distance[x1][y1] + 1) { + distance[dx + x1][dy + y1] = distance[x1][y1] + 1; + q.push({dx + x1, dy + y1}); + } + } + } + return (distance[n - 1][n - 1] == INF) ? -1 : distance[n - 1][n - 1]; +} + +vector> knightlOnAChessboard(int n) { + vector> moves(n - 1, vector(n - 1, 1)); + for (int a = 1; a < n; a++) { + for (int b = a; b < n; b++) { + moves[a - 1][b - 1] = moves[b - 1][a - 1] = bfs(a, b, n); + } + } + return moves; +} diff --git a/codeBase/HackerRank/Algorithms/Search/Maximum Subarray Sum/Solution.cpp b/codeBase/HackerRank/Algorithms/Search/Maximum Subarray Sum/Solution.cpp new file mode 100644 index 0000000..05894ac --- /dev/null +++ b/codeBase/HackerRank/Algorithms/Search/Maximum Subarray Sum/Solution.cpp @@ -0,0 +1,54 @@ +/* + Copyright (C) 2020, Sathira Silva. + + Problem Statement: We define the following: + A subarray of array a of length n is a contiguous segment from a[i] through a[j] where 0 <= i <= j < n. + The sum of an array is the sum of its elements. + Given an n element array of integers, a, and an integer, m, determine the maximum value of the sum of any of its + subarrays modulo m. + + Approach: When dealing with subarray sums the most efficient way is to creating a prefix sum because it reduces time for repeating + computations of subarray sums. Here the prefix modulo sum can be defined as: + prefixSum(i) = (arr[0] + ... + arr[i]) % m + Therefore, the subarray mod sum from a[i] to a[j] can be defined as: + subarraySum(i, j) = (prefixSum(j) - prefixSum(i - 1) + m) % m (m is added to handle the negative values) + It can be seen that the subarray sum is maximum when prefixSum(i - 1) = prefixSum(j) + 1 because largest value the + above expression can get is (m - 1). Therefore, we just need to find the indices i having the lowest prefix sum greater + than or equal to prefixSum(j) + 1 for each prefixSum(j). It's easier to use a Binary Search Tree consisting the prefix + sums to search those values efficiently. + + Total Time Complexity: O(nlog(n)) +*/ + +#include + +using namespace std; + +int main() +{ + ios_base::sync_with_stdio(false); + cin.tie(NULL); + int q, n; + long long m; + cin >> q; + for (int i = 0; i < q; i++) { + cin >> n >> m; + long long prefixSum = 0, maxSubarraySum = 0; + set bbst; // Maintain a Balanced Binary Search Tree. + bbst.insert(0); + for (int i = 0; i < n; i++) { + int current; + cin >> current; + prefixSum = (prefixSum + current % m) % m; + maxSubarraySum = max(maxSubarraySum, prefixSum); + // Find the lowest value in the prefix sum larger than or equal to one larger + // than current prefix sum. + auto iter = bbst.lower_bound(prefixSum + 1); + if (iter != bbst.end()) + maxSubarraySum = max(maxSubarraySum, prefixSum - *iter + m); + bbst.insert(prefixSum); + } + cout << maxSubarraySum << endl; + } + return 0; +} diff --git a/codeBase/HackerRank/Algorithms/Search/Minimum Loss/solution.py b/codeBase/HackerRank/Algorithms/Search/Minimum Loss/solution.py new file mode 100644 index 0000000..ead5870 --- /dev/null +++ b/codeBase/HackerRank/Algorithms/Search/Minimum Loss/solution.py @@ -0,0 +1,10 @@ +''' + Copyright (C) 2020, Sathira Silva. +''' + +from sys import stdin, stdout + +if __name__ == '__main__': + n = int(stdin.readline()) + prices = sorted(list(enumerate(map(int, stdin.readline().rstrip().split()))), key=lambda x: x[1]) + stdout.write(str(min(bought - sold for (yearBought, bought), (yearSold, sold) in zip(prices[1:], prices[:-1]) if yearSold > yearBought))) diff --git a/codeBase/HackerRank/Algorithms/Search/Missing Numbers/Solution.cpp b/codeBase/HackerRank/Algorithms/Search/Missing Numbers/Solution.cpp new file mode 100644 index 0000000..051fab1 --- /dev/null +++ b/codeBase/HackerRank/Algorithms/Search/Missing Numbers/Solution.cpp @@ -0,0 +1,38 @@ +/* + Copyright (C) 2020, Sathira Silva. + + Problem Statement: Numeros the Artist had two lists that were permutations of one another. He was very proud. Unfortunately, while + transporting them from one exhibition to another, some numbers were lost out of the first list. Can you find the + missing numbers? +*/ + +#include + +using namespace std; + +int main() +{ + ios_base::sync_with_stdio(false); + cin.tie(NULL); + int n, m, ele; + cin >> n; + // Array to store frequencies of each missing element. + int frequency[10001] = {0}; + for (int i = 0; i < n; i++) { + cin >> ele; + // Decrement the frequencies of available elements so that the frequencies of the missing elements can be counted in the next step. + frequency[ele]--; + } + cin >> m; + for (int i = 0; i < m; i++) { + cin >> ele; + // Increment the frequencies of elements in the original array. This will cause the frequencies of the missing elements to + // be greater than 0. Others will stay as 0. + frequency[ele]++; + } + for (int i = 0; i < 10001; i++) + if (frequency[i] > 0) + cout << i << " "; + cout << endl; + return 0; +} diff --git a/codeBase/HackerRank/Algorithms/Search/Pairs/solution.py b/codeBase/HackerRank/Algorithms/Search/Pairs/solution.py new file mode 100644 index 0000000..94adf1f --- /dev/null +++ b/codeBase/HackerRank/Algorithms/Search/Pairs/solution.py @@ -0,0 +1,14 @@ +''' + Copyright (C) 2020, Sathira Silva. + + Problem Statement: You will be given an array of integers and a target value. Determine the number of pairs of array elements that + have a difference equal to a target value. + + Time Complexity: O(n) for both set conversion and set intersection operation. +''' + +from sys import stdin, stdout + +n, k = map(int, stdin.readline().rstrip().split()) +arr = set(map(int, stdin.readline().rstrip().split())) +stdout.write(str(len(arr & set(d + k for d in arr)))) diff --git a/codeBase/HackerRank/Algorithms/Search/Sherlock and Array/Solution.cpp b/codeBase/HackerRank/Algorithms/Search/Sherlock and Array/Solution.cpp new file mode 100644 index 0000000..1e484ed --- /dev/null +++ b/codeBase/HackerRank/Algorithms/Search/Sherlock and Array/Solution.cpp @@ -0,0 +1,49 @@ +/* + Copyright (C) 2020, Sathira Silva. + + Problem Statement: Watson gives Sherlock an array of integers. His challenge is to find an element of the array such that the sum + of all elements to the left is equal to the sum of all elements to the right. For instance, given the array + arr = [5, 6, 8, 11], 8 is between two subarrays that sum to 11. If your starting array is [1], that element + satisfies the rule as left and right sum to 0. + You will be given arrays of integers and must determine whether there is an element that meets the criterion. + + Approach: Search for a pivot element which satifies the above condition. Maintain a left sum and a right sum where left sum is + initially 0 and right sum is the sum of the entire array except the first element. Then, iterate over the array starting + from 1st element. Check whether the left and right sums are equal. If not, add the previous element to the left sum + and deduct the current element from the right sum (In each iteration we assume the current element to be the pivot). + + Time Complexity: O(n) +*/ + +#include + +using namespace std; + +int main() +{ + ios_base::sync_with_stdio(false); + cin.tie(NULL); + int t, n, leftSum, rightSum; + cin >> t; + for (int k = 0; k < t; k++) { + cin >> n; + int arr[n]; + bool found = false; + leftSum = 0, rightSum = 0; + for (int i = 0; i < n; i++) { + cin >> arr[i]; + rightSum += arr[i]; + } + rightSum -= arr[0]; + for (int i = 1; i < n; i++) { + if (leftSum == rightSum) { + found = true; + break; + } + leftSum += arr[i - 1]; + rightSum -= arr[i]; + } + cout << (found ? "YES" : "NO") << endl; + } + return 0; +} diff --git a/codeBase/HackerRank/Algorithms/Strings/Highest Value Palindrome/Solution.cpp b/codeBase/HackerRank/Algorithms/Strings/Highest Value Palindrome/Solution.cpp new file mode 100644 index 0000000..a3858fa --- /dev/null +++ b/codeBase/HackerRank/Algorithms/Strings/Highest Value Palindrome/Solution.cpp @@ -0,0 +1,59 @@ +/* + Copyright (C) 2020, Sathira Silva. + + Problem Statement: Palindromes are strings that read the same from the left or right, for example madam or 0110. + You will be given a string representation of a number and a maximum number of changes you can make. Alter the + string, one digit at a time, to create the string representation of the largest number possible given the limit + to the number of changes. The length of the string may not be altered, so you must consider 0's left of all + higher digits in your tests. For example 0110 is valid, 0011 is not. + Given a string representing the starting number and a maximum number of changes allowed, create the largest + palindromic string of digits possible or the string -1 if it's impossible to create a palindrome under the + contstraints. +*/ + +#include + +using namespace std; + +string highestValuePalindrome(string s, int n, int k) { + int changes = 0; + bool change[n]; + // Traverse the string upto n / 2, front and end pair wise (s[i] and s[n - i - 1]). + // First copy the large digit to the other in the pair if they're not equal and if there're more moves left. + for (int i = 0; i < n / 2; i++) { + if (s[i] != s[n - i - 1]) { + change[i] = true; + changes++; + if (s[i] > s[n - i - 1]) + s[n - i - 1] = s[i]; + else + s[i] = s[n - i - 1]; + } + if (changes > k) + return "-1"; + } + // If there're more moves left, change the digits which are not 9 to 9. + for (int i = 0; i < n / 2 && changes < k; i++) { + if (s[i] != '9') { + // We could have changed this digit to 9, therefore undo the previous change. + if (change[i]) + changes--; + if (changes < k - 1) { + s[i] = s[n - i - 1] = '9'; + changes += 2; + } + } + } + // Finally handle the middle digit if the number of digits is odd. + if (n % 2 && changes < k) + s[n / 2] = '9'; + return s; +} + +int main() { + int n, k; + string s; + cin >> n >> k >> s; + cout << highestValuePalindrome(s, n, k) << endl; + return 0; +} diff --git a/codeBase/IEEEXtreme/2014/Back to Square 1/Back to Square 1.pdf b/codeBase/IEEEXtreme/2014/Back to Square 1/Back to Square 1.pdf new file mode 100644 index 0000000..11c3812 Binary files /dev/null and b/codeBase/IEEEXtreme/2014/Back to Square 1/Back to Square 1.pdf differ diff --git a/codeBase/IEEEXtreme/2014/Back to Square 1/solution.cpp b/codeBase/IEEEXtreme/2014/Back to Square 1/solution.cpp new file mode 100644 index 0000000..0f91fa7 --- /dev/null +++ b/codeBase/IEEEXtreme/2014/Back to Square 1/solution.cpp @@ -0,0 +1,33 @@ +/* + Copyright (C) 2020, Sathira Silva. + + Approach: This is a pure model for a Markov Chain. The state space is S = {1, 2, ... , n}. The states of the markov chain can be modeled by Geometric random variables because + each random variable has two outcomes: either success to the next square or failure to the 1st square. The ultimate goal is to find how many iterations are needed + to get a transient state to the absorbing state, starting with the given initial state square 1. There are several ways of doing this. One can find the fundamental + matrix and sum up the 1st row (and add 1: number of steps to getting into the first square) as explained in: + https://en.wikipedia.org/wiki/Absorbing_Markov_chain#Expected_number_of_steps + Another one may calculate the number of steps by finding a recurrence formula. But the easiest way is to start from the last state and going backwards untill the + first state. The probability of getting into the nth square from the (n - 1)th square p(n - 1). Thus, the expected value is 1 / p(n - 1) since the random variables + are modeled by geometric distribution. Note that the expected value of getting into the nth square from (n - 1)th square is the number of steps it takes. The + probability of getting into the nth square from the (n - 2)th square is p(n - 2) * p(n - 1). Thus, the expected value is 1 / [p(n - 2) * p(n - 1)]. Then, total number + of steps it takes to reach square n from (n - 2)th square is 1 / p(n - 1) + 1 / [p(n - 2) * p(n - 1)]. Likewise, we can iterate upto the 1st square. +*/ + +#include + +using namespace std; + +int main() { + int n; + while ((cin >> n) && n) { + double res = 1, exp = 1; + double p[n - 1]; + for (int i = 0; i < n - 1; i++) + cin >> p[i]; + for (int i = n - 2; i >= 0; i--) { + exp /= p[i]; + res += exp; + } + cout << (int) (res + 0.5) << endl; // Round to the nearest integer + } +} diff --git a/codeBase/IEEEXtreme/2014/Fibonacci/solution.cpp b/codeBase/IEEEXtreme/2014/Fibonacci/solution.cpp new file mode 100644 index 0000000..c3a81f1 --- /dev/null +++ b/codeBase/IEEEXtreme/2014/Fibonacci/solution.cpp @@ -0,0 +1,42 @@ +/* + Copyright (C) 2020, Sathira Silva. + + Link to the problem: https://csacademy.com/ieeextreme-practice/task/09f92a575cc006d4a6a7f525f370ec30/ + + Approach: The fibonacci sequence under modulo becomes a periodic sequence. That period is also known as the 'Pisano Period'. Therefore, it is enough to find the fibonacci + sequence upto the pisano period. +*/ + +#include + +using namespace std; + +// For m = 10, it turns out that the pisano period is 60 +int pisanoPeriod(int m) { + int prev = 0; + int curr = 1; + int res = 0; + for(int i = 0; i < m * m; i++) { + int temp = 0; + temp = curr; + curr = (prev + curr) % m; + prev = temp; + if (prev == 0 && curr == 1) + res= i + 1; + } + return res; +} + +int main() { + int t; + cin >> t; + int dp[61]; + dp[0] = dp[1] = 1; + for (int i = 2; i < 61; i++) + dp[i] = (dp[i - 1] % 10 + dp[i - 2] % 10) % 10; + for (int _ = 0; _ < t; _++) { + int m; + cin >> m; + cout << dp[m % 60] << endl; + } +} diff --git a/codeBase/IEEEXtreme/2014/Kabloom/Kabloom.pdf b/codeBase/IEEEXtreme/2014/Kabloom/Kabloom.pdf new file mode 100644 index 0000000..4237898 Binary files /dev/null and b/codeBase/IEEEXtreme/2014/Kabloom/Kabloom.pdf differ diff --git a/codeBase/IEEEXtreme/2014/Kabloom/README.md b/codeBase/IEEEXtreme/2014/Kabloom/README.md new file mode 100644 index 0000000..79d425f --- /dev/null +++ b/codeBase/IEEEXtreme/2014/Kabloom/README.md @@ -0,0 +1 @@ +![problem](problem.jpg) diff --git a/codeBase/IEEEXtreme/2014/Kabloom/problem.jpg b/codeBase/IEEEXtreme/2014/Kabloom/problem.jpg new file mode 100644 index 0000000..ee5e62b Binary files /dev/null and b/codeBase/IEEEXtreme/2014/Kabloom/problem.jpg differ diff --git a/codeBase/IEEEXtreme/2014/Kabloom/solution.cpp b/codeBase/IEEEXtreme/2014/Kabloom/solution.cpp new file mode 100644 index 0000000..d8cc06a --- /dev/null +++ b/codeBase/IEEEXtreme/2014/Kabloom/solution.cpp @@ -0,0 +1,54 @@ +/* + Copyright (C) 2020, Sathira Silva. + + Approach: This is purely an Edit Distance problem (or an Optimal Alignment problem) where only the replacements have a cost equal to the matched value. The goal is to + maximize the cost. Thus we can solve it using dynamic programming as follows: + (01). Subproblems: Prefixes of two rows of cards (say first[:i], second[:j]) + #subproblems: n^2 --> O(n^2) + (02). Guessing: One of three possibilities: + * Replace + * Insert + * Delete + (03). Recurrence: dp[i][j] = max(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1] + penalty) + (04). Topological order: Doesn't matter + (05). Original Problem: dp[n][n] +*/ + +#include + +using namespace std; + +int main() { + map points; + for (int i = 0; i < 8; i++) + points[i + '2'] = i + 2; + points['T'] = 10; + points['A'] = 20; + points['J'] = points['Q'] = points['K'] = 15; + int n; + int dp[1001][1001]; + while (cin >> n) { + if (n == 0) break; + char first[n][1], second[n][1]; + for(int i = 0 ; i < n; i++) + scanf("%s", first[i]); + for(int i = 0; i < n; i++) + scanf("%s", second[i]); + memset(dp, 0, sizeof(dp)); + for (int i = 1; i <= n; i++) { + for (int j = 1; j <= n; j++) { + int penalty = 0; // If the ith and jth card doesn't match, no point value + if (first[i - 1][0] == second[j - 1][0] || first[i - 1][0] == 'R' || second[j - 1][0] == 'R') { + if (first[i - 1][0] == 'R' && second[j - 1][0] == 'R') + penalty = 50; + else if (first[i - 1][0] == 'R') + penalty = points[second[j - 1][0]]; + else + penalty = points[first[i - 1][0]]; + } + dp[i][j] = max(dp[i - 1][j], max(dp[i][j - 1], dp[i - 1][j - 1] + penalty)); + } + } + cout << 2 * dp[n][n] << endl; + } +} diff --git a/codeBase/IEEEXtreme/2014/Play with GCD/README.md b/codeBase/IEEEXtreme/2014/Play with GCD/README.md new file mode 100644 index 0000000..79d425f --- /dev/null +++ b/codeBase/IEEEXtreme/2014/Play with GCD/README.md @@ -0,0 +1 @@ +![problem](problem.jpg) diff --git a/codeBase/IEEEXtreme/2014/Play with GCD/problem.jpg b/codeBase/IEEEXtreme/2014/Play with GCD/problem.jpg new file mode 100644 index 0000000..1e05b7c Binary files /dev/null and b/codeBase/IEEEXtreme/2014/Play with GCD/problem.jpg differ diff --git a/codeBase/IEEEXtreme/2014/Play with GCD/solution.cpp b/codeBase/IEEEXtreme/2014/Play with GCD/solution.cpp new file mode 100644 index 0000000..f80bf5f --- /dev/null +++ b/codeBase/IEEEXtreme/2014/Play with GCD/solution.cpp @@ -0,0 +1,66 @@ +/* + Copyright (C) 2020, Sathira Silva. + + Approach: The idea is to store the number of subsets having gcd equal to some x for all possible x's using dynamic programming. Then we can respond to the queries in O(1). + Note that the maximum gcd a sequence can have is the maximum value of that sequence. Also note that the gcd of the sequence is n. So, to find the + number of subsets with gcd x all we have to do is counting the number of occurrences of all possible multiples of x in the array. If the count is c, the number of + valid subsets are 2^c - 1 - {number of subsets with gcd = y (> x)}. We deduct 1 to exclude the empty subset. Since we count the occurrences of multiples of x, + we also include the subsets which doesn't include x but it's other multiples. So we have to deduct those number of subsets too. +*/ + +#include + +#define mod 1000000007 + +using namespace std; + +typedef long long ll; + +ll modpow(ll x, ll y) { + ll res = 1; + x %= mod; + if (x == 0) return 0; + while (y) { + if (y & 1) + res = (res * x) % mod; + y >>= 1; + x = (x * x) % mod; + } + return res; +} + +int main() { + int n; + cin >> n; + ll balls[n], freq[10001], dp[10001], maxn = INT_MIN; + memset(freq, 0, sizeof(freq)); + for (int i = 0; i < n; i++) { + cin >> balls[i]; + // Count the frequencies of the numbers + freq[balls[i]]++; + // The maximum possible gcd is the maximum number in the array + maxn = max(maxn, balls[i]); + } + memset(dp, 0, sizeof(dp)); + for (ll x = maxn; x >= 1; x--) { + ll c = 0; + // Check all multiples of x + for (ll y = x; y <= maxn; y+=x) { + // Count number of occurrences of the current multiple of x + c += freq[y]; + // Subtract the number of subsets with gcd = y (> x) since the gcd of subsets that doesn't include x but multiples of x is not x + if (y > x) + dp[x] = (dp[x] - dp[y] + mod) % mod; + } + // The number of subsets with gcd = x is dp[x] (we have already subtracted the subsets that includes multiples of x except x) + 2^c - 1 (excluding the empty set) + dp[x] = (dp[x] + modpow(2, c) - 1 + mod) % mod; + } + int q; + cin >> q; + for (int _ = 0; _ < q; _++) { + int x; + cin >> x; + // Answer the queries in O(1) complexity + cout << dp[x] << endl; + } +} diff --git a/codeBase/IEEEXtreme/2014/Vangelis the Batbear and the Bubbles Challenge/solution.cpp b/codeBase/IEEEXtreme/2014/Vangelis the Batbear and the Bubbles Challenge/solution.cpp new file mode 100644 index 0000000..4751082 --- /dev/null +++ b/codeBase/IEEEXtreme/2014/Vangelis the Batbear and the Bubbles Challenge/solution.cpp @@ -0,0 +1,44 @@ +/* + Copyright (C) 2020, Sathira Silva. + + Link to the problem: https://csacademy.com/ieeextreme-practice/task/979a09a0cd8c4e98dd0a690f39a55bd2/ + + Approach: Union each edge. If the end points of an edge belongs to the same set, a loop is found. +*/ + +#include + +using namespace std; + +int findSet(int u, int parent[]) { + if (parent[u] == -1) + return u; + return findSet(parent[u], parent); +} + +void makeUnion(int u, int v, int parent[]) { + parent[findSet(u, parent)] = findSet(v, parent); +} + +int main() { + int t; + cin >> t; + for (int _ = 0; _ < t; _++) { + int n, m; + cin >> n >> m; + int parent[n]; + memset(parent, -1, sizeof(parent)); + bool found = false; + for (int i = 0; i < m; i++) { + int u, v; + cin >> u >> v; + if (!found) { + int pu = findSet(u, parent), pv = findSet(v, parent); + if (pu == pv) + found = true; + makeUnion(u, v, parent); + } + } + cout << found << endl; + } +} diff --git a/codeBase/KickStart/2020A/Allocation/Solution.py b/codeBase/KickStart/2020A/Allocation/Solution.py new file mode 100644 index 0000000..0c4e9fd --- /dev/null +++ b/codeBase/KickStart/2020A/Allocation/Solution.py @@ -0,0 +1,23 @@ +''' + Dinindu Udana + dtdinidu7@gmail.com + 22/03/2020 +''' + +n = int(input()) + +for t in range(n): + n, c = [int(i) for i in input().split()] + arr = [int(i) for i in input().split()] + + arr.sort() # sort the array + count = 0 + cost = 0 + for i in arr: + cost += i # add current value to count + if cost <= c: + count += 1 # count if cost is less than the given value + else: + break + print("Case #{}: {}".format(t+1, count)) + \ No newline at end of file diff --git a/codeBase/KickStart/2020A/Plates/Solution.py b/codeBase/KickStart/2020A/Plates/Solution.py new file mode 100644 index 0000000..2036492 --- /dev/null +++ b/codeBase/KickStart/2020A/Plates/Solution.py @@ -0,0 +1,56 @@ +''' + gihanjayatilaka[at]eng[dot]pdn[dot]ac[dot]lk 2020-03-22 +''' +ar=None- +dpAns=None +K=None +N=None +P=None + +T = int(input()) + + +def dp(n,pp,deb): + # print("funcIn",deb,n,pp) + if n>=N or pp<=0: + # print(deb+"dpAns[{}][{}]={}".format(n, pp, 0)) + return 0 + if dpAns[n][pp]>-1: + return dpAns[n][pp] + + + + tempAns=dp(n+1,pp,deb+" ") + + for k in range(min(pp,K)): + tempAns=max(tempAns,ar[n][k]+dp(n+1,pp-k-1,deb+" ")) + + dpAns[n][pp]=tempAns + # print(deb+"dpAns[{}][{}]={}".format(n,pp,tempAns)) + + return dpAns[n][pp] +- +for t in range(1, T + 1): + NKP=list(map(int, input().strip().split())) + N=NKP[0] + K=NKP[1] + P=NKP[2] + ar=[] + dpAns=[[-1 for _ in range(P+1)] for n in range(N)] + for i in range(N): + ar.append(list(map(int, input().strip().split()))) + + # print(ar) + + for i in range(N): + for j in range(1,K): + ar[i][j]=ar[i][j-1]+ar[i][j] + # print(ar) + # for i in range(N,-1,-1): + + + + + + + print("Case #{}: {}".format(t,dp(0,P," "))) diff --git a/codeBase/KickStart/2020A/Workout/Solution.py b/codeBase/KickStart/2020A/Workout/Solution.py new file mode 100644 index 0000000..cf14daf --- /dev/null +++ b/codeBase/KickStart/2020A/Workout/Solution.py @@ -0,0 +1,31 @@ +''' + Dinindu Udana + dtdinidu7@gmail.com + 22/03/2020 +''' + +n = int(input()) +import heapq +import math + +for t in range(n): + tmp, k = [int(i) for i in input().split()] + arr = [int(i) for i in input().split()] + count = [1]*(tmp-1) # array to hole the number of new items to be put between these elements + diff = [0]*(tmp-1) # array to hold the initiall differences + Q = [] + + for i in range(tmp-1): + diff[i] = arr[i+1]-arr[i] # saving initial differences + heapq.heappush(Q, (-diff[i], i)) # saving the current difference values + #print(Q) + + for i in range(k): + val, ind = heapq.heappop(Q) # pop the max diff + count[ind] += 1 # add new item between that pair to reduce the difference + val = math.ceil(diff[ind]/count[ind]) # calculate the max difference + heapq.heappush(Q, (-val, ind)) # push new diffrence to the heapq + #print(Q) + val, ind = heapq.heappop(Q) # pop the max difference + print("Case #{}: {}".format(t+1, -val)) + diff --git a/codeBase/moraXtreme Past Problems/moraXtreme1.0/1000 Shades of Grey/README.md b/codeBase/moraXtreme Past Problems/moraXtreme1.0/1000 Shades of Grey/README.md new file mode 100644 index 0000000..79d425f --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme1.0/1000 Shades of Grey/README.md @@ -0,0 +1 @@ +![problem](problem.jpg) diff --git a/codeBase/moraXtreme Past Problems/moraXtreme1.0/1000 Shades of Grey/problem.jpg b/codeBase/moraXtreme Past Problems/moraXtreme1.0/1000 Shades of Grey/problem.jpg new file mode 100644 index 0000000..8f2572c Binary files /dev/null and b/codeBase/moraXtreme Past Problems/moraXtreme1.0/1000 Shades of Grey/problem.jpg differ diff --git a/codeBase/moraXtreme Past Problems/moraXtreme1.0/1000 Shades of Grey/solution.cpp b/codeBase/moraXtreme Past Problems/moraXtreme1.0/1000 Shades of Grey/solution.cpp new file mode 100644 index 0000000..f6bd9be --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme1.0/1000 Shades of Grey/solution.cpp @@ -0,0 +1,54 @@ +/* + Copyright (C) 2020, Sathira Silva. + + Link to the problem: https://www.hackerrank.com/contests/moraxtreme1/challenges/1000-shades-of-grey + + Approach: In simple terms the problem asks to find the maximum length subsequence of the indices of the array, when sorted, either all of the indices in the subsequence are + strictly increasing or first decreasing then increasing (reverse bitonic). Because, the lower indices belong to the tiles which are firstly plastered onto the floor + and the higher indices are the ones which are plastered later. Therefore, when sorted by the magnitude of the shade, always the indices increase right to left or + increase right to left ending at 0 and increase left to right starting from 0. So the goal is to find the longest length of the subsequence. +*/ + +#include + +using namespace std; + +int main() { + int t; + cin >> t; + for (int _ = 0; _ < t; _++) { + int m; + cin >> m; + vector> shades(m); + for (int i = 0; i < m; i++) { + cin >> shades[i].first; + shades[i].second = i; + } + sort(shades.begin(), shades.end()); + // Calculate dp1[i] : longest strictly increasing subsequence ending at ith index + int dp1[m], dp2[m], dp3[m]; + for (int i = 0; i < m; i++) + dp1[i] = 1, dp2[i] = 1, dp3[i] = 1; + for (int i = 1; i < m; i++) { + for (int j = 0; j < i; j++) + if (shades[i].second > shades[j].second && dp1[i] < dp1[j] + 1) + dp1[i] = dp1[j] + 1; + } + // Calculate dp2[i] : longest strictly decreasing subsequence ending at ith index + for (int i = 1; i < m; i++) { + for (int j = 0; j < i; j++) + if (shades[i].second < shades[j].second && dp2[i] < dp2[j] + 1) + dp2[i] = dp2[j] + 1; + } + // Calculate dp3[i] : longest strictly decreasing subsequence ending at ith index from right to left + for (int i = m - 2; i >= 0; i--) { + for (int j = m - 1; j > i; j--) + if (shades[i].second < shades[j].second && dp3[i] < dp3[j] + 1) + dp3[i] = dp3[j] + 1; + } + int M = dp2[0] + dp3[0] - 1; // Longest length of the reverse bitonic subsequence + for (int i = 1; i < m; i++) + M = max(M, dp2[i] + dp3[i] - 1); + cout << max(*max_element(dp1, dp1 + m), M) << endl; + } +} diff --git a/codeBase/moraXtreme Past Problems/moraXtreme1.0/Beachfull Islands/README.md b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Beachfull Islands/README.md new file mode 100644 index 0000000..1ff925d --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Beachfull Islands/README.md @@ -0,0 +1 @@ +![problem](https://github.com/sathiiii/codeBase/blob/master/codeBase/moraXtreme%20Past%20Problems/moraXtreme1.0/Beachfull%20Islands/problem.jpg) diff --git a/codeBase/moraXtreme Past Problems/moraXtreme1.0/Beachfull Islands/problem.jpg b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Beachfull Islands/problem.jpg new file mode 100644 index 0000000..86ba155 Binary files /dev/null and b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Beachfull Islands/problem.jpg differ diff --git a/codeBase/moraXtreme Past Problems/moraXtreme1.0/Beachfull Islands/solution.cpp b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Beachfull Islands/solution.cpp new file mode 100644 index 0000000..7632294 --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Beachfull Islands/solution.cpp @@ -0,0 +1,39 @@ +/* + Copyright (C) 2020, Sathira Silva. +*/ + +#include + +using namespace std; + +int dir[8][2] = {{0, -1}, {1, -1}, {1, 0}, {1, 1}, {0, 1}, {-1, 1}, {-1, 0}, {-1, -1}}; + +int main() { + int t; + cin >> t; + for (int tt = 0; tt < t; tt++) { + int m, n; + cin >> m >> n; + int grid[m][n]; + for (int i = 0; i < m; i++) { + char c; + for (int j = 0; j < n; j++) { + cin >> c; + grid[i][j] = c - '0'; + } + } + for (int i = 0; i < m; i++) + for (int j = 0; j < n; j++) + if (grid[i][j] == 1) + for (int k = 0; k < 8; k++) + if (i + dir[k][0] >= 0 && i + dir[k][0] < m && j + dir[k][1] >= 0 && j + dir[k][1] < n && grid[i + dir[k][0]][j + dir[k][1]] == 0) + grid[i + dir[k][0]][j + dir[k][1]] = 2; + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) + cout << grid[i][j]; + cout << endl; + } + + } + return 0; +} diff --git a/codeBase/moraXtreme Past Problems/moraXtreme1.0/Colombo Pokemon Go/README.md b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Colombo Pokemon Go/README.md new file mode 100644 index 0000000..d618162 --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Colombo Pokemon Go/README.md @@ -0,0 +1 @@ +![problem](https://github.com/sathiiii/codeBase/blob/master/codeBase/moraXtreme%20Past%20Problems/moraXtreme1.0/Colombo%20Pokemon%20Go/problem.jpg) diff --git a/codeBase/moraXtreme Past Problems/moraXtreme1.0/Colombo Pokemon Go/problem.jpg b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Colombo Pokemon Go/problem.jpg new file mode 100644 index 0000000..aa2ed6f Binary files /dev/null and b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Colombo Pokemon Go/problem.jpg differ diff --git a/codeBase/moraXtreme Past Problems/moraXtreme1.0/Colombo Pokemon Go/solution.cpp b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Colombo Pokemon Go/solution.cpp new file mode 100644 index 0000000..c37f7cf --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Colombo Pokemon Go/solution.cpp @@ -0,0 +1,77 @@ +/* + Copyright (C) 2020, Sathira Silva. + + Link to the problem: https://www.hackerrank.com/contests/moraxtreme1/challenges/pokemon-go-3-1 + + Approach: The problem can be modeled as a maximum-cardinality bipartite matching problem with minimum edge weights. i.e. we have to assign a pokemon trainer per each pokemon + such that the time to reach out a pokemon is minimum. A brute force solution would be to check all possible assignments which is of order O(TChooseP) where T is + the number of trainers and P is the number of pokemons (Because there exists T choose P number of perfect matchings). But a minimum-cost bipartite matching + problem can be converted into a continuous optimization (a linear program) problem which can be solved using linear programming. Such algorithm exists and it's + called the 'Hungarian Algorithm'. The algorithm consumes O(P^2T) (O(PT) to process the matrix and O(P) to recalculate the potentials). +*/ + +#include + +#define INF 1e9 + +using namespace std; + +int main() { + int n; + cin >> n; + for (int t = 0; t < n; t++) { + int P, T; + cin >> P >> T; + double time[P + 1][T + 1]; // Stores the costs of the matchings. 1st row and column is kept for the convenience. + for (int i = 1; i <= P; i++) + for (int j = 1; j <= T; j++) + cin >> time[i][j]; + vector u (P + 1), v (T + 1); // Potentials such that u[i] + v[j] <= time[i][j] (i = 1...P, j = 1...T) + // p[j] contains the matching: for each column j = 1...T it stores the index of the corresponding row (0 if nothing is selected. Thus it's a free vertex). + // (p[0] is maintained to store the current row under consideration) + // The vector way stores the information (the parent pointers) to reconstruct the augmenting path. + vector p (T + 1), way (T + 1); + // Iterate through all left vertices (Pokemons) + for (int i = 1; i <= P; i++) { + p[0] = i; + int j0 = 0; + vector minv (T + 1, INF); // Used to recalculate the potentials + vector used (T + 1, false); // To mark whether a right vertex is used or not + // Iterate until a free right vertex (A free trainer) is found + while (p[j0] != 0) { + used[j0] = true; // Mark the vertex (trainer) as used + int i0 = p[j0], j1; + double delta = INF; + for (int j = 1; j <= T; j++) + if (!used[j]) { + double cur = time[i0][j] - u[i0] - v[j]; + if (cur < minv[j]) + minv[j] = cur, way[j] = j0; + if (minv[j] < delta) + delta = minv[j], j1 = j; + } + for (int j = 0; j <= T; j++) + if (used[j]) + u[p[j]] += delta, v[j] -= delta; + else + minv[j] -= delta; + j0 = j1; + } + + while (j0) { + int j1 = way[j0]; + p[j0] = p[j1]; + j0 = j1; + } + } + // Restore the answer (for each trainer, find the index of the pokemon he has been assigned) + vector ans(P + 1); + for (int j = 1; j <= T; j++) + ans[p[j]] = j; + double res = 0; + for (int i = 1; i <= P; i++) + res += time[i][ans[i]]; + cout << fixed << setprecision(2) << res / P << endl; + } + return 0; +} diff --git a/codeBase/moraXtreme Past Problems/moraXtreme1.0/Complex Problem/README.md b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Complex Problem/README.md new file mode 100644 index 0000000..99e2f73 --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Complex Problem/README.md @@ -0,0 +1,16 @@ +# Evaluation of p: + + + + +Therfore, Let +Now plug them into the expression: + + + + + + +# Problem Statement: + +![problem](https://github.com/sathiiii/codeBase/blob/master/codeBase/moraXtreme%20Past%20Problems/moraXtreme1.0/Complex%20Problem/problem.jpg) diff --git a/codeBase/moraXtreme Past Problems/moraXtreme1.0/Complex Problem/problem.jpg b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Complex Problem/problem.jpg new file mode 100644 index 0000000..297ec06 Binary files /dev/null and b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Complex Problem/problem.jpg differ diff --git a/codeBase/moraXtreme Past Problems/moraXtreme1.0/Complex Problem/solution.cpp b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Complex Problem/solution.cpp new file mode 100644 index 0000000..e29cd94 --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Complex Problem/solution.cpp @@ -0,0 +1,24 @@ +/* + Copyright (C) 2020, Sathira Silva. + + Link to the problem: https://www.hackerrank.com/contests/moraxtreme1/challenges/single-input + + Approach: This is an easy math problem. Find the roots of the given equation. It's obvious that they're complex hence conjugates which implies that when the given expression + is evaluated, the result is real for all n. The proof is added to the README. + The final answer for p is: 4cos(npi/3) + NOTE: if n is divisible by 3 and n / 3 is odd cos(npi/3) = -1, if n / 3 is even cos(npi/3) = 1; If n is not divisible by 3 but odd, cos(npi/3) = 1/2 and -1/2 + if n is even otherwise. + + >>> The 6th test case is wrong. For n = 900000000000000000, the result should be p = 4 because cos(900000000000000000pi/3) = 1. But -4 has been put as the expected output. +*/ + +#include + +using namespace std; + +int main() { + long long n; + cin >> n; + cout << (n % 3 == 0 ? ((n / 3) & 1 ? -4 : 4) : (n & 1 ? 2 : -2)); + return 0; +} diff --git a/codeBase/moraXtreme Past Problems/moraXtreme1.0/Fabric/README.md b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Fabric/README.md new file mode 100644 index 0000000..4370169 --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Fabric/README.md @@ -0,0 +1 @@ +![problem](https://github.com/sathiiii/codeBase/blob/master/codeBase/moraXtreme%20Past%20Problems/moraXtreme1.0/Fabric/problem.jpg) diff --git a/codeBase/moraXtreme Past Problems/moraXtreme1.0/Fabric/problem.jpg b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Fabric/problem.jpg new file mode 100644 index 0000000..e6a0d64 Binary files /dev/null and b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Fabric/problem.jpg differ diff --git a/codeBase/moraXtreme Past Problems/moraXtreme1.0/Fabric/solution.cpp b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Fabric/solution.cpp new file mode 100644 index 0000000..d50ab3f --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Fabric/solution.cpp @@ -0,0 +1,49 @@ +/* + Copyright (C) 2020, Sathira Silva. + + Link to the problem: https://www.hackerrank.com/contests/moraxtreme1/challenges/fabric + + Approach: The naive brute force solution is to iterate through all possible squares and find the largest area rectangle which doesn't contain 1's. But if we can pre-calculate + the number of 1's inside the rectangles, we only need to iterate over the four indices, say (i1, j1) and (i2, j2) where i1 <= i2 < h, j1 <= j2 < w. So the time + complexity boils down from O(H^3W^3) to O(H^2W^2) because we can find rectangles without 1's in it in O(1) from the pre-calculated values. The pre-calculation can + be done using dynamic programming as follows: + (01). Subproblems: The goal is to find the number of 1's inside the rectangle (i1, j1), (i2, j2) where i1 <= i2 < h, j1 <= j2 < w. But we can break this down to + a subproblem of finding the number of 1's inside the rectangle (0, 0), (i, j). i.e. dp[i + 1][j + 1]. + Base Cases: dp[i][0] = 0, dp[0][j] = 0 + + (02). Recurrence: dp[i][j] = dp[i - 1][j] + dp[i][j - 1] - dp[i - 1][j - 1] + fabric[i - 1][j - 1] for H >= i >= 1, W >= j >= 1 + (03). Original Problem: Number of 1's inside the rectangle (i1, j1), (i2, j2) = dp[i2][j2] - dp[i1 - 1][j2] - dp[i2][j1 - 1] + dp[i1 - 1][j1 - 1] +*/ + +#include + +using namespace std; + +int main() { + int t; + cin >> t; + for (int tt = 0; tt < t; tt++) { + int h, w; + cin >> h >> w; + int fabric[h][w]; + for (int i = 0; i < h; i++) + for (int j = 0; j < w; j++) + cin >> fabric[i][j]; + int dp[h + 1][w + 1]; // dp[i + 1][j + 1] = number of 1's inside the rectangle starting at (0, 0) and ending at (i, j) + for (int i = 0; i <= h; i++) + dp[i][0] = 0; + for (int j = 0; j <= w; j++) + dp[0][j] = 0; + for (int i = 1; i <= h; i++) + for (int j = 1; j <= w; j++) + dp[i][j] = dp[i][j - 1] + dp[i - 1][j] - dp[i - 1][j - 1] + fabric[i - 1][j - 1]; + int area = 0; + for (int i1 = 1; i1 <= h; i1++) + for (int j1 = 1; j1 <= w; j1++) + for (int i2 = i1; i2 <= h; i2++) + for (int j2 = j1; j2 <= w; j2++) + if (dp[i2][j2] - dp[i1 - 1][j2] - dp[i2][j1 - 1] + dp[i1 - 1][j1 - 1] == 0) + area = max(area, (i2 - i1 + 1) * (j2 - j1 + 1)); + cout << area << endl; + } +} diff --git a/codeBase/moraXtreme Past Problems/moraXtreme1.0/Fair and Square/README.md b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Fair and Square/README.md new file mode 100644 index 0000000..46885de --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Fair and Square/README.md @@ -0,0 +1 @@ +![problem](https://github.com/sathiiii/codeBase/blob/master/codeBase/moraXtreme%20Past%20Problems/moraXtreme1.0/Fair%20and%20Square/problem.jpg) diff --git a/codeBase/moraXtreme Past Problems/moraXtreme1.0/Fair and Square/problem.jpg b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Fair and Square/problem.jpg new file mode 100644 index 0000000..2b9aaf8 Binary files /dev/null and b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Fair and Square/problem.jpg differ diff --git a/codeBase/moraXtreme Past Problems/moraXtreme1.0/Fair and Square/solution.cpp b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Fair and Square/solution.cpp new file mode 100644 index 0000000..eafe769 --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Fair and Square/solution.cpp @@ -0,0 +1,32 @@ +/* + Copyright (C) 2020, Sathira Silva. + + Link to the problem: https://www.hackerrank.com/contests/moraxtreme1/challenges/fair-and-square + + Approach: Any number can be represented as the sum of perfect squares. Since a number N can always be expressed as the sum of squares of 1, the maximum count of perfect squares + that sums to N is N for any number N. But that can be minimized for numbers larger than 3. Let dp(x) = minimum number of perfect squares that sums to x. + Thus, dp(x) = x if x <= 3; min(x, 1 + dp(x - i * i) for i in range(1, ceiling(sqrt(x))) Otherwise) where i * i is a perfect square less than x. + Therefore, a dynamic programming approach can be used to efficiently calculate the count. +*/ + +#include + +using namespace std; + +int main() { + int t; + cin >> t; + int dp[20001]; + dp[0] = 0, dp[1] = 1, dp[2] = 2, dp[3] = 3; // Base Cases + for (int n = 4; n <= 20000; n++) { + dp[n] = n; // n can be always represented as sum of n square of 1s and it's the maximum perfect square count + for (int i = 1; i * i <= n; i++) + dp[n] = min(dp[n], 1 + dp[n - i * i]); + } + for (int tt = 0; tt < t; tt++) { + int a; + cin >> a; + cout << dp[a] << endl; + } + return 0; +} diff --git a/codeBase/moraXtreme Past Problems/moraXtreme1.0/Function Maximum/README.md b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Function Maximum/README.md new file mode 100644 index 0000000..d712b52 --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Function Maximum/README.md @@ -0,0 +1 @@ +![problem](https://github.com/sathiiii/codeBase/blob/master/codeBase/moraXtreme%20Past%20Problems/moraXtreme1.0/Function%20Maximum/problem.jpg) diff --git a/codeBase/moraXtreme Past Problems/moraXtreme1.0/Function Maximum/problem.jpg b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Function Maximum/problem.jpg new file mode 100644 index 0000000..427614e Binary files /dev/null and b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Function Maximum/problem.jpg differ diff --git a/codeBase/moraXtreme Past Problems/moraXtreme1.0/Function Maximum/solution.py b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Function Maximum/solution.py new file mode 100644 index 0000000..7a649dd --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Function Maximum/solution.py @@ -0,0 +1,17 @@ +''' + Copyright (C) 2020, Sathira Silva. + + Link to the problem: https://www.hackerrank.com/contests/moraxtreme1/challenges/maximum-2 + + Approach: There exists an O(1) solution for this problem. Since f(kn) = n and f(kn + r) = f(kn) + r = f(n) + r (Note that r = the remainder of (kn + r) / k), f(n) can be + expressed as f(n) = f(k * k * ... k * x + n % k) = f(x) + n % k where x (< k) is the largest multiplier that n can be expressed with a product of as much as k's. + Therefore, the least value of n in range (0, b] which maximizes f(n) is the [largest multiple of largest exponent of k less than b] - 1. We have deduct 1 in order + to maximize the modulo term. + In mathematical terms: floor(b / (k ^ floor(logk(b - 1)))) * (k ^ floor(logk(b - 1))) - 1. +''' + +from math import log + +k, b = map(int, input().split()) +p = k ** int(log(b - 1, k)) +print(b // p * p - 1) diff --git a/codeBase/moraXtreme Past Problems/moraXtreme1.0/Lazy Pleas/README.md b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Lazy Pleas/README.md new file mode 100644 index 0000000..c3fc5fd --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Lazy Pleas/README.md @@ -0,0 +1 @@ +![problem](https://github.com/sathiiii/codeBase/blob/master/codeBase/moraXtreme%20Past%20Problems/moraXtreme1.0/Lazy%20Pleas/problem.jpg) diff --git a/codeBase/moraXtreme Past Problems/moraXtreme1.0/Lazy Pleas/problem.jpg b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Lazy Pleas/problem.jpg new file mode 100644 index 0000000..895c2eb Binary files /dev/null and b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Lazy Pleas/problem.jpg differ diff --git a/codeBase/moraXtreme Past Problems/moraXtreme1.0/Lazy Pleas/solution.cpp b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Lazy Pleas/solution.cpp new file mode 100644 index 0000000..89dc5b8 --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Lazy Pleas/solution.cpp @@ -0,0 +1,38 @@ +/* + Copyright (C) 2020, Sathira Silva. + + Link to the problem: https://www.hackerrank.com/contests/moraxtreme1/challenges/lazy-pleas + + Approach: Save the words in a map. For each plea, count the occurrences of the saved words in the plea and store the plea having the maximum so far count of words. +*/ + +#include + +using namespace std; + +int main() { + int a, b; + cin >> a >> b; + map words; + for (int i = 0; i < a; i++) { + string s; + cin >> s; + words[s] = 0; + } + int res = 0; + string result; + for (string s; getline(cin, s);) { + stringstream ss(s); + int temp = 0; + string word; + while (ss >> word) + if (words.count(word) > 0) + temp++; + if (res < temp) { + res = temp; + result = s; + } + } + cout << result << endl; + return 0; +} diff --git a/codeBase/moraXtreme Past Problems/moraXtreme1.0/README.md b/codeBase/moraXtreme Past Problems/moraXtreme1.0/README.md new file mode 100644 index 0000000..2c2b55d --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme1.0/README.md @@ -0,0 +1 @@ +Link to the contest: https://www.hackerrank.com/contests/moraxtreme1/ diff --git a/codeBase/moraXtreme Past Problems/moraXtreme1.0/Window Summing/README.md b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Window Summing/README.md new file mode 100644 index 0000000..e0b2dad --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Window Summing/README.md @@ -0,0 +1 @@ +![problem](https://github.com/sathiiii/codeBase/blob/master/codeBase/moraXtreme%20Past%20Problems/moraXtreme1.0/Window%20Summing/problem.jpg) diff --git a/codeBase/moraXtreme Past Problems/moraXtreme1.0/Window Summing/problem.jpg b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Window Summing/problem.jpg new file mode 100644 index 0000000..c4c24d4 Binary files /dev/null and b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Window Summing/problem.jpg differ diff --git a/codeBase/moraXtreme Past Problems/moraXtreme1.0/Window Summing/solution.cpp b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Window Summing/solution.cpp new file mode 100644 index 0000000..e415b21 --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme1.0/Window Summing/solution.cpp @@ -0,0 +1,26 @@ +/* + Copyright (C) 2020, Sathira Silva. + + Link to the problem: https://www.hackerrank.com/contests/moraxtreme1/challenges/window-summing +*/ + +#include + +using namespace std; + +int main() { + ios_base::sync_with_stdio(false); + cin.tie(NULL); + int n, w, window = 0; + cin >> n >> w; + vector seq(n); + for (int i = 0; i < n; i++) + cin >> seq[i]; + for (int i = 0; i < n; i++) { + window += seq[i]; + if (i >= w) + window -= seq[i - w]; + cout << window << " "; + } + return 0; +} diff --git a/codeBase/moraXtreme Past Problems/moraXtreme2.0/Cubes Cubes Everywhere/README.md b/codeBase/moraXtreme Past Problems/moraXtreme2.0/Cubes Cubes Everywhere/README.md new file mode 100644 index 0000000..019e2e3 --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme2.0/Cubes Cubes Everywhere/README.md @@ -0,0 +1 @@ +![problem](https://github.com/sathiiii/codeBase/blob/master/codeBase/moraXtreme%20Past%20Problems/moraXtreme2.0/Cubes%20Cubes%20Everywhere/problem.jpg) diff --git a/codeBase/moraXtreme Past Problems/moraXtreme2.0/Cubes Cubes Everywhere/problem.jpg b/codeBase/moraXtreme Past Problems/moraXtreme2.0/Cubes Cubes Everywhere/problem.jpg new file mode 100644 index 0000000..ac68d71 Binary files /dev/null and b/codeBase/moraXtreme Past Problems/moraXtreme2.0/Cubes Cubes Everywhere/problem.jpg differ diff --git a/codeBase/moraXtreme Past Problems/moraXtreme2.0/Cubes Cubes Everywhere/solution.py b/codeBase/moraXtreme Past Problems/moraXtreme2.0/Cubes Cubes Everywhere/solution.py new file mode 100644 index 0000000..2049dcc --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme2.0/Cubes Cubes Everywhere/solution.py @@ -0,0 +1,18 @@ +def sumOfCubes(n): + return ((n * (n + 1) // 2) % 10000000000 * (n * (n + 1) // 2) % 10000000000) % 10000000000 + +t = int(input()) +for _ in range(t): + n = int(input()) + res = 0 + for i in range(1, n + 1): + d = n // i + if d >= i: + res += sumOfCubes(d) + else: + i -= 1 + lastd = n // i + res += sum(((j ** 3) % 10000000000 * (n // j - i) % 10000000000) % 10000000000 for j in range(1, lastd)) + break + res = res % 10000000000 + print(res % 1000000000) diff --git a/codeBase/moraXtreme Past Problems/moraXtreme2.0/Diagonal Warm Up/README.md b/codeBase/moraXtreme Past Problems/moraXtreme2.0/Diagonal Warm Up/README.md new file mode 100644 index 0000000..6a33081 --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme2.0/Diagonal Warm Up/README.md @@ -0,0 +1,34 @@ +**Problem Statement** + +You are given a square matrix of integers. Sum up the numbers on the diagonals and output the sum. + +**Input Format** + +* First line contains the number of rows/columns of the matrix. +* Each next lines contains number of matrix elements separated by a single space character. + +**Constraints** + +* +* + +**Output Format** + +* One line containing the sum of the diagonals of the matrix + +**Sample Input 0** +``` +3 +4 5 3 +8 5 7 +6 4 7 +``` +**Sample Output 0** +``` +25 +``` + +**Explanation 0** +```math +4 + 5 + 7 + 3 + 6 = 25 +``` diff --git a/codeBase/moraXtreme Past Problems/moraXtreme2.0/Diagonal Warm Up/solution.cpp b/codeBase/moraXtreme Past Problems/moraXtreme2.0/Diagonal Warm Up/solution.cpp new file mode 100644 index 0000000..1b1cb91 --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme2.0/Diagonal Warm Up/solution.cpp @@ -0,0 +1,17 @@ +#include + +using namespace std; + +int main() { + int n, t; + long sum = 0; + cin >> n; + for (int i = 0; i < n; i++) + for (int j = 0; j < n; j++) { + cin >> t; + if (i == j || i == n - j - 1) + sum += t; + } + cout << sum; + return 0; +} diff --git a/codeBase/moraXtreme Past Problems/moraXtreme2.0/Gem Mining/README.md b/codeBase/moraXtreme Past Problems/moraXtreme2.0/Gem Mining/README.md new file mode 100644 index 0000000..1633c11 --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme2.0/Gem Mining/README.md @@ -0,0 +1 @@ +![problem](https://github.com/sathiiii/codeBase/blob/patch-1/codeBase/moraXtreme%20Past%20Problems/moraXtreme2.0/Gem%20Mining/probem.png) diff --git a/codeBase/moraXtreme Past Problems/moraXtreme2.0/Gem Mining/probem.png b/codeBase/moraXtreme Past Problems/moraXtreme2.0/Gem Mining/probem.png new file mode 100644 index 0000000..d16d716 Binary files /dev/null and b/codeBase/moraXtreme Past Problems/moraXtreme2.0/Gem Mining/probem.png differ diff --git a/codeBase/moraXtreme Past Problems/moraXtreme2.0/Gem Mining/solution.cpp b/codeBase/moraXtreme Past Problems/moraXtreme2.0/Gem Mining/solution.cpp new file mode 100644 index 0000000..2f7a317 --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme2.0/Gem Mining/solution.cpp @@ -0,0 +1,65 @@ +#include + +#define INF (int) 1e9 + +using namespace std; + +typedef pair> zone; + +class cmp +{ +public: + bool operator() (const zone &a, const zone &b) const + { + return (a.first > b.first); + } +}; + +int main() { + int n, p, xg, yg; + char c; + int prices[3]; + int dxdy[8][2] = {{0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1}, {-1, 0}, {-1, 1}}; + cin >> n >> p; + int grid[n][n], cost[n][n]; + cin >> xg; + cin.ignore(); + cin >> yg; + for (int i = 0; i < 3; i++) { + if (cin.peek() == ',') + cin.ignore(); + cin >> prices[i]; + } + for (int i = 0; i < n; i++) + for (int j = 0; j < n; j++) { + cost[i][j] = INF; + cin >> c; + if (c == 's') + grid[i][j] = prices[0]; + else if (c == 'r') + grid[i][j] = prices[1]; + else if (c == 'w') + grid[i][j] = prices[2]; + else + grid[i][j] = 0; + } + cost[0][0] = 0; + priority_queue, cmp> q; + q.push({0, {0, 0}}); + + while (!q.empty()) { + zone currZone = q.top(); + q.pop(); + int x = currZone.second.first, y = currZone.second.second; + for (int i = 0; i < 8; i++) { + int x_n = x + dxdy[i][0], y_n = y + dxdy[i][1]; + if (x_n >= 0 && x_n < n && y_n >= 0 && y_n < n && cost[x_n][y_n] > cost[x][y] + grid[x_n][y_n]) { + cost[x_n][y_n] = cost[x][y] + grid[x_n][y_n]; + q.push({cost[x_n][y_n], {x_n, y_n}}); + } + } + } + + cout << p - cost[xg][yg]; + return 0; +} diff --git a/codeBase/moraXtreme Past Problems/moraXtreme2.0/Help the Merchant/solution.py b/codeBase/moraXtreme Past Problems/moraXtreme2.0/Help the Merchant/solution.py new file mode 100644 index 0000000..81b4e1c --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme2.0/Help the Merchant/solution.py @@ -0,0 +1,27 @@ +# Problem: https://www.hackerrank.com/contests/moraxtreme-2/challenges/money-money-money + +from sys import stdin, stdout + +INF = 1e9 +N, I = map(int, stdin.readline().split()) +cost = [[int(c) if c != 'X' else INF for c in stdin.readline().split()] for _ in range(N)] +profit = [[0] * I] + [list(map(int, stdin.readline().split())) for _ in range(N - 1)] +T = int(stdin.readline()) +for t in range(T): + items = list(map(int, stdin.readline().split())) + S = len(items) + dp = [[-INF] * S for _ in range(N)] + #Sell the last item + for i in range(N): + dp[i][S - 1] = profit[i][items[S - 1]] + + for k in range(S - 2, -1, -1): + for i in range(N): + for j in range(N): + dp[i][k] = max(dp[i][k], dp[j][k + 1] + profit[i][items[k]] - cost[i][j]) + + res = -INF + for i in range(1, N): + res = max(res, dp[i][0] - cost[0][i]) + + stdout.write('{}\n'.format(res)) diff --git a/codeBase/moraXtreme Past Problems/moraXtreme2.0/Network Latency/README.md b/codeBase/moraXtreme Past Problems/moraXtreme2.0/Network Latency/README.md new file mode 100644 index 0000000..437ab17 --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme2.0/Network Latency/README.md @@ -0,0 +1 @@ +![problem](https://github.com/sathiiii/codeBase/blob/patch-1/codeBase/moraXtreme%20Past%20Problems/moraXtreme2.0/Network%20Latency/problem.png) diff --git a/codeBase/moraXtreme Past Problems/moraXtreme2.0/Network Latency/problem.png b/codeBase/moraXtreme Past Problems/moraXtreme2.0/Network Latency/problem.png new file mode 100644 index 0000000..51abda6 Binary files /dev/null and b/codeBase/moraXtreme Past Problems/moraXtreme2.0/Network Latency/problem.png differ diff --git a/codeBase/moraXtreme Past Problems/moraXtreme2.0/Network Latency/solution.cpp b/codeBase/moraXtreme Past Problems/moraXtreme2.0/Network Latency/solution.cpp new file mode 100644 index 0000000..1e02fd7 --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme2.0/Network Latency/solution.cpp @@ -0,0 +1,50 @@ +#include + +#define MAXN 10000 + +using namespace std; + +vector primes; +long ways[MAXN + 1]; + +void sieve() { + bool prime[MAXN + 1]; + for (int i = 2; i * i <= MAXN; i++) + if (!prime[i]) + for (int j = i * i; j <= MAXN; j += i) + prime[j] = true; + for (int i = 2; i <= MAXN; i++) + if (!prime[i]) + primes.push_back(i); +} + +int count(int n) +{ + memset(ways, 0, sizeof(ways)); + ways[0] = 1; + for(int i = 0; i < (int) primes.size(); i++) + for(int j = primes[i]; j <= MAXN; j++) + ways[j] += ways[j - primes[i]]; + int left = 0, right = 80, res = -1; + ways[0] = ways[1] = 0; + while (left <= right) { + int mid = left + (right - left) / 2; + if (ways[mid] <= n) + left = mid + 1; + else { + right = mid - 1; + res = mid; + } + } + return res; +} + +int main() { + int n; + cin >> n; + sieve(); + cout << count(n) << endl; + // for (int i = 0; i <= MAXN; i++) + // cout << ways[i] << " "; + return 0; +} diff --git a/codeBase/moraXtreme Past Problems/moraXtreme2.0/Prime Challenge/README.md b/codeBase/moraXtreme Past Problems/moraXtreme2.0/Prime Challenge/README.md new file mode 100644 index 0000000..5d06d18 --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme2.0/Prime Challenge/README.md @@ -0,0 +1 @@ +![problem](https://github.com/sathiiii/codeBase/blob/patch-1/codeBase/moraXtreme%20Past%20Problems/moraXtreme2.0/Prime%20Challenge/probem.png) diff --git a/codeBase/moraXtreme Past Problems/moraXtreme2.0/Prime Challenge/probem.png b/codeBase/moraXtreme Past Problems/moraXtreme2.0/Prime Challenge/probem.png new file mode 100644 index 0000000..40ee29c Binary files /dev/null and b/codeBase/moraXtreme Past Problems/moraXtreme2.0/Prime Challenge/probem.png differ diff --git a/codeBase/moraXtreme Past Problems/moraXtreme2.0/Prime Challenge/randomized.py b/codeBase/moraXtreme Past Problems/moraXtreme2.0/Prime Challenge/randomized.py new file mode 100644 index 0000000..466c106 --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme2.0/Prime Challenge/randomized.py @@ -0,0 +1,60 @@ +''' + Copyright (C) Sathira Silva, 2020. + + Link to the problem: https://www.hackerrank.com/contests/moraxtreme-2/challenges/prime-challenge + + Approach: The following is a randomized algorithm for the above problem. Goldbach's first and second conjectures are used to solve the problem. His first conjecture says + that "Every even integer greater than 2 can be expressed as the sum of two primes". His second conjecture states "Every odd integer greater than 5 can be expressed + as the sum of three primes". The first prime can always be chosen as 3 because when the first prime is 3 and since n is odd, n - 3 will be even. From goldbach's + second conjecture, n - 3 can be expressed as the sum of two primes because of the given upper bound of n. Below algorithm sets 3 to be the first prime and + generates a random integer less than n. When both generated integer (say p2) and n - 3 - p2 are primes, it prints the result. Miller - Rabin primality test is + used for the primality checks. +''' + +import random + +def power(x, y, p): + res = 1 + x = x % p + while (y > 0): + if (y & 1): + res = (res * x) % p + y = y >> 1 + x = (x * x) % p + return res + +def millerTest(d, n): + a = 2 + random.randint(1, n - 4); + x = power(a, d, n); + if (x == 1 or x == n - 1): + return True + while (d != n - 1): + x = (x * x) % n + d *= 2 + if (x == 1): + return False + if (x == n - 1): + return True + return False + +def isPrime(n, k): + if (n <= 1 or n == 4): + return False + if (n <= 3): + return True + d = n - 1 + while (d % 2 == 0): + d //= 2 + for i in range(k): + if (millerTest(d, n) == False): + return False + return True + +n = int(input()) +while True: + p1 = 3 + p2 = random.randint(4, n) + p3 = n - p1 - p2 + if isPrime(p2, 20) and isPrime(p3, 20): + print(p1, p2, p3) + break diff --git a/codeBase/moraXtreme Past Problems/moraXtreme2.0/Prime Challenge/solution.java b/codeBase/moraXtreme Past Problems/moraXtreme2.0/Prime Challenge/solution.java new file mode 100644 index 0000000..36a9f44 --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme2.0/Prime Challenge/solution.java @@ -0,0 +1,52 @@ +import java.io.*; +import java.util.*; +import java.math.BigInteger; + +public class Solution { + public static boolean[] sieve(int n) { + boolean prime[] = new boolean[n + 1]; + for(int i = 0; i < n; i++) + prime[i] = true; + for(int p = 2; p * p <= n; p++) + { + if(prime[p] == true) + { + for(int i = p * 2; i <= n; i += p) + prime[i] = false; + } + } + return prime; + } + + public static void main(String[] args) { + Scanner sc=new Scanner(System.in); + long N = sc.nextLong(); + StringBuffer sb = new StringBuffer(); + if (N <= Integer.MAX_VALUE / 10) { + N -= 3; + sb.append("3 "); + int n = (int) N; + boolean[] isPrime = sieve((int) n); + for (int i = 2; i < n; i++) + if (isPrime[i] && isPrime[n - i]) { + sb.append(i + " " + (n - i)); + break; + } + } + else { + BigInteger n = BigInteger.valueOf(N); + BigInteger xxx = n.subtract(new BigInteger("1000000")); + BigInteger nn = xxx.nextProbablePrime(); + n = n.subtract(nn); + int xx = Integer.parseInt(n.toString()); + sb.append(nn.toString() + " "); + boolean[] isPrime = sieve(xx); + for (int x = 2; x < xx; x++) + if (isPrime[x] && isPrime[xx - x]) { + sb.append(x + " " + (xx - x)); + break; + } + } + System.out.println(sb.toString()); + } +} diff --git a/codeBase/moraXtreme Past Problems/moraXtreme2.0/README.md b/codeBase/moraXtreme Past Problems/moraXtreme2.0/README.md new file mode 100644 index 0000000..865a8f4 --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme2.0/README.md @@ -0,0 +1 @@ +Link to the contest: https://www.hackerrank.com/contests/moraxtreme-2/ diff --git a/codeBase/moraXtreme Past Problems/moraXtreme2.0/Stranger Games/README.md b/codeBase/moraXtreme Past Problems/moraXtreme2.0/Stranger Games/README.md new file mode 100644 index 0000000..ed0bd7b --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme2.0/Stranger Games/README.md @@ -0,0 +1 @@ +![problem](https://github.com/sathiiii/codeBase/blob/patch-1/codeBase/moraXtreme%20Past%20Problems/moraXtreme2.0/Stranger%20Games/probem.png) diff --git a/codeBase/moraXtreme Past Problems/moraXtreme2.0/Stranger Games/Solution.cpp b/codeBase/moraXtreme Past Problems/moraXtreme2.0/Stranger Games/Solution.cpp new file mode 100644 index 0000000..327fa93 --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme2.0/Stranger Games/Solution.cpp @@ -0,0 +1,44 @@ +#include + +#define INF (int) 1e9 + +using namespace std; + +int dfs(int u, vector graph[], bool visited[], int& count) { + visited[u] = true; + int currentCount = 0; + for (int v : graph[u]) { + if (!visited[v]) { + int subCount = dfs(v, graph, visited, count); + if (subCount % 2 == 0) + count++; + else + currentCount += subCount; + } + } + return currentCount + 1; +} + +int main() { + int N, M, n = 0; + cin >> N >> M; + vector graph[N]; + map m; + for (int i = 0; i < M; i++) { + string u, v; + cin >> u >> v; + if (m.find(u) == m.end()) + m[u] = n++; + if (m.find(v) == m.end()) + m[v] = n++; + graph[m.at(u)].push_back(m.at(v)); + graph[m.at(v)].push_back(m.at(u)); + } + bool visited[N]; + for (int i = 0; i < N; i++) + visited[i] = false; + int count = 0; + dfs(0, graph, visited, count); + cout << count + 1 << endl; + return 0; +} diff --git a/codeBase/moraXtreme Past Problems/moraXtreme2.0/Stranger Games/probem.png b/codeBase/moraXtreme Past Problems/moraXtreme2.0/Stranger Games/probem.png new file mode 100644 index 0000000..9cd6695 Binary files /dev/null and b/codeBase/moraXtreme Past Problems/moraXtreme2.0/Stranger Games/probem.png differ diff --git a/codeBase/moraXtreme Past Problems/moraXtreme3.0/Count Divisors/README.md b/codeBase/moraXtreme Past Problems/moraXtreme3.0/Count Divisors/README.md new file mode 100644 index 0000000..5eaa4e3 --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme3.0/Count Divisors/README.md @@ -0,0 +1 @@ +![problem](https://github.com/sathiiii/codeBase/blob/master/codeBase/moraXtreme%20Past%20Problems/moraXtreme3.0/Count%20Divisors/problem.jpg) diff --git a/codeBase/moraXtreme Past Problems/moraXtreme3.0/Count Divisors/problem.jpg b/codeBase/moraXtreme Past Problems/moraXtreme3.0/Count Divisors/problem.jpg new file mode 100644 index 0000000..625243c Binary files /dev/null and b/codeBase/moraXtreme Past Problems/moraXtreme3.0/Count Divisors/problem.jpg differ diff --git a/codeBase/moraXtreme Past Problems/moraXtreme3.0/Count Divisors/solution.cpp b/codeBase/moraXtreme Past Problems/moraXtreme3.0/Count Divisors/solution.cpp new file mode 100644 index 0000000..122b574 --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme3.0/Count Divisors/solution.cpp @@ -0,0 +1,27 @@ +/* + Copyright (C) 2020, Sathira Silva. + + Link to the problem: https://www.hackerrank.com/contests/moraxtreme3-0/challenges/count-divisors-1-1 +*/ + +#include + +using namespace std; + +int main() { + int T; + cin >> T; + for (int t = 0; t < T; t++) { + int n, m; + cin >> n; + m = n; + int count = 0; + while (m > 0) { + if (m % 10 != 0 && n % (m % 10) == 0) + count++; + m /= 10; + } + cout << count << endl; + } + return 0; +} diff --git a/codeBase/moraXtreme Past Problems/moraXtreme3.0/Counting the Triangles/README.md b/codeBase/moraXtreme Past Problems/moraXtreme3.0/Counting the Triangles/README.md new file mode 100644 index 0000000..3ef8c3e --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme3.0/Counting the Triangles/README.md @@ -0,0 +1 @@ +![problem](https://github.com/sathiiii/codeBase/blob/master/codeBase/moraXtreme%20Past%20Problems/moraXtreme3.0/Counting%20the%20Triangles/problem.jpg) diff --git a/codeBase/moraXtreme Past Problems/moraXtreme3.0/Counting the Triangles/problem.jpg b/codeBase/moraXtreme Past Problems/moraXtreme3.0/Counting the Triangles/problem.jpg new file mode 100644 index 0000000..eef5834 Binary files /dev/null and b/codeBase/moraXtreme Past Problems/moraXtreme3.0/Counting the Triangles/problem.jpg differ diff --git a/codeBase/moraXtreme Past Problems/moraXtreme3.0/Counting the Triangles/solution.cpp b/codeBase/moraXtreme Past Problems/moraXtreme3.0/Counting the Triangles/solution.cpp new file mode 100644 index 0000000..4c364e2 --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme3.0/Counting the Triangles/solution.cpp @@ -0,0 +1,41 @@ +/* + Copyright (C) 2020, Sathira Silva. + + Link to the problem: https://www.hackerrank.com/contests/moraxtreme3-0/challenges/triangles-6 + + Apporach: There are 3 cases to form a right triangle OPQ where O is the origin: + (1). Right angle at O + (2). Right angle at P + (3). Right angle at Q + Therefore, the problem can be broken down into 3 parts. It is easy to see that the number of traingles for the 1st case is n * n. Because when the right angle is at + O, P and Q must lie on the x and y axes. The 2nd and 3rd cases are symmetrical so we can treat them as one. Therefore, let's consider the 2nd case where the right + angle is at P. Suppose P lies on x or y axis. Again since the y-coordinate of P has the degree of freedom to be on anywhere in (1, n) and the x-coordinate of Q can + be anywhere in (1, n), there are n * n such triangles. Thus, there are 2 * n * n total triangles whose right angle is at P or Q which one of the points lie on x or + y axis. Therefore, there are 3 * n * n total number of triangles that we can find trivially. + + For the other triangles in case (2) and (3) (P or Q being a right angle and doesn't lie on x or y axes), we have to search for the number of triangles by varying one + point (say P) on integer non-zero x-y plane. Suppose P has coordinates (x, y). The gradient of the vector OP is y / x. In order to have a right angle at P, the slope + of the vector PQ must be -x / y. So, we can find for possible integer coordinate Q points along the PQ line when P is fixed until we hit the x axis or when the x + coordinate of Q reach n. Therefore, to find the number of triangles we have to find how many integer steps we can come down along the vector PQ starting from P + until we reach y = 0 or x = n. Let dx and dy be the lengths of corresponding x and y integer steps: dx = y / gcd(x, y), dy = x / gcd(x, y) + Therefore, the number of triangles is the minimum of (n - x) / dx and y / dy + + (This's the 91st problem in Project Euler) +*/ + +#include + +using namespace std; + +int main() { + int n; + cin >> n; + int result = 3 * n * n; // Trivially found solution + for (int x = 1; x <= n; x++) + for (int y = 1; y <= n; y++) { + int g = __gcd(x, y); + result += min(y * g / x, (n - x) * g / y) * 2; + } + cout << result; + return 0; +} diff --git a/codeBase/moraXtreme Past Problems/moraXtreme3.0/Knight Placement Problem/README.md b/codeBase/moraXtreme Past Problems/moraXtreme3.0/Knight Placement Problem/README.md new file mode 100644 index 0000000..87ea622 --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme3.0/Knight Placement Problem/README.md @@ -0,0 +1 @@ +![problem](https://github.com/sathiiii/codeBase/blob/master/codeBase/moraXtreme%20Past%20Problems/moraXtreme3.0/Knight%20Placement%20Problem/problem.jpg) diff --git a/codeBase/moraXtreme Past Problems/moraXtreme3.0/Knight Placement Problem/problem.jpg b/codeBase/moraXtreme Past Problems/moraXtreme3.0/Knight Placement Problem/problem.jpg new file mode 100644 index 0000000..e050861 Binary files /dev/null and b/codeBase/moraXtreme Past Problems/moraXtreme3.0/Knight Placement Problem/problem.jpg differ diff --git a/codeBase/moraXtreme Past Problems/moraXtreme3.0/Knight Placement Problem/solution.cpp b/codeBase/moraXtreme Past Problems/moraXtreme3.0/Knight Placement Problem/solution.cpp new file mode 100644 index 0000000..98f58be --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme3.0/Knight Placement Problem/solution.cpp @@ -0,0 +1,36 @@ +/* + Copyright (C) 2020, Sathira Silva. + + Link to the problem: https://www.hackerrank.com/contests/moraxtreme3-0/challenges/knight-placement-problem + + Approach: There exists only one optimal configuration for any size of a chess board and it's as follows: + + K 0 K 0 ... + 0 K 0 K ... + K 0 K 0 ... + . . . . . + . . . . . + + Therefore, a general pattern can be recognized. Let K(n) be the maximum number of knights that can be placed without attcking each other. + K(1) = 1 + K(2) = 2 + K(3) = 5 + K(4) = 8 + K(5) = 13 + K(6) = 18 + ... and so on + + Thus, if n is even K(n) = n * n / 2 + if n is odd K(n) = (n * n + 1) / 2 +*/ + +#include + +using namespace std; + +int main() { + long n; + cin >> n; + cout << ((n % 2 == 0) ? n * n / 2 : (n * n + 1) / 2); + return 0; +} diff --git a/codeBase/moraXtreme Past Problems/moraXtreme3.0/Megamind/README.md b/codeBase/moraXtreme Past Problems/moraXtreme3.0/Megamind/README.md new file mode 100644 index 0000000..2169f32 --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme3.0/Megamind/README.md @@ -0,0 +1 @@ +![problem](https://github.com/sathiiii/codeBase/blob/master/codeBase/moraXtreme%20Past%20Problems/moraXtreme3.0/Megamind/problem.jpg) diff --git a/codeBase/moraXtreme Past Problems/moraXtreme3.0/Megamind/problem.jpg b/codeBase/moraXtreme Past Problems/moraXtreme3.0/Megamind/problem.jpg new file mode 100644 index 0000000..628f63a Binary files /dev/null and b/codeBase/moraXtreme Past Problems/moraXtreme3.0/Megamind/problem.jpg differ diff --git a/codeBase/moraXtreme Past Problems/moraXtreme3.0/README.md b/codeBase/moraXtreme Past Problems/moraXtreme3.0/README.md new file mode 100644 index 0000000..cb68f81 --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme3.0/README.md @@ -0,0 +1 @@ +Link to the contest: https://www.hackerrank.com/contests/moraxtreme3-0/challenges diff --git a/codeBase/moraXtreme Past Problems/moraXtreme3.0/Save the cities/README.md b/codeBase/moraXtreme Past Problems/moraXtreme3.0/Save the cities/README.md new file mode 100644 index 0000000..cb6ea5a --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme3.0/Save the cities/README.md @@ -0,0 +1 @@ +![problem](https://github.com/sathiiii/codeBase/blob/master/codeBase/moraXtreme%20Past%20Problems/moraXtreme3.0/Save%20the%20cities/problem.jpg) diff --git a/codeBase/moraXtreme Past Problems/moraXtreme3.0/Save the cities/problem.jpg b/codeBase/moraXtreme Past Problems/moraXtreme3.0/Save the cities/problem.jpg new file mode 100644 index 0000000..137c189 Binary files /dev/null and b/codeBase/moraXtreme Past Problems/moraXtreme3.0/Save the cities/problem.jpg differ diff --git a/codeBase/moraXtreme Past Problems/moraXtreme3.0/Save the cities/solution.cpp b/codeBase/moraXtreme Past Problems/moraXtreme3.0/Save the cities/solution.cpp new file mode 100644 index 0000000..614f643 --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme3.0/Save the cities/solution.cpp @@ -0,0 +1,42 @@ +/* + Copyright (C) 2020, Sathira Silva. + + Link to the problem: https://www.hackerrank.com/contests/moraxtreme3-0/challenges/save-the-cities + + Approach: The main idea is to find the number of connected components. Two cells are connected if they're adjacent and the cell value is 1. Maintain a visited array and + traverse through the city matrix. If the current cell is 1, depth first traverse the matrix and mark all the 1 cells that found as visited during the traversal. + If the depth first traversal ends, then all those marked 1's are a single connected component. Therefore, increase the count at the end of the DFS. +*/ + +#include + +using namespace std; + +int m, n; +int adj[1000][1000]; +bool visited[1000][1000]; +int dir[8][2] = {{-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1}}; + +void dfs(int i, int j) { + visited[i][j] = true; + for (int x = 0; x < 8; x++) + if (i + dir[x][0] >= 0 && j + dir[x][1] >= 0 && i + dir[x][0] < m && j + dir[x][1] < n && adj[i + dir[x][0]][j + dir[x][1]] && !visited[i + dir[x][0]][j + dir[x][1]]) + dfs(i + dir[x][0], j + dir[x][1]); +} + +int main() { + cin >> m >> n; + for (int i = 0; i < m; i++) + for (int j = 0; j < n; j++) + cin >> adj[i][j]; + memset(visited, 0, sizeof(visited)); + int count = 0; + for (int i = 0; i < m; i++) + for (int j = 0; j < n; j++) + if (adj[i][j] && !visited[i][j]) { + dfs(i, j); + count++; + } + cout << count << endl; + return 0; +} diff --git a/codeBase/moraXtreme Past Problems/moraXtreme3.0/Sunimal FTW/README.md b/codeBase/moraXtreme Past Problems/moraXtreme3.0/Sunimal FTW/README.md new file mode 100644 index 0000000..a1e1fe9 --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme3.0/Sunimal FTW/README.md @@ -0,0 +1 @@ +![problem](https://github.com/sathiiii/codeBase/blob/master/codeBase/moraXtreme%20Past%20Problems/moraXtreme3.0/Sunimal%20FTW/problem.jpg) diff --git a/codeBase/moraXtreme Past Problems/moraXtreme3.0/Sunimal FTW/problem.jpg b/codeBase/moraXtreme Past Problems/moraXtreme3.0/Sunimal FTW/problem.jpg new file mode 100644 index 0000000..2a4c143 Binary files /dev/null and b/codeBase/moraXtreme Past Problems/moraXtreme3.0/Sunimal FTW/problem.jpg differ diff --git a/codeBase/moraXtreme Past Problems/moraXtreme3.0/Sunimal FTW/solution.cpp b/codeBase/moraXtreme Past Problems/moraXtreme3.0/Sunimal FTW/solution.cpp new file mode 100644 index 0000000..ac89ede --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme3.0/Sunimal FTW/solution.cpp @@ -0,0 +1,42 @@ +/* + Copyright (C) 2020, Sathira Silva. + + Link to the problem: https://www.hackerrank.com/contests/moraxtreme3-0/challenges/sunimal-ftw + + Approach: This is a variant of the Nim game with zero move is allowed per each heap. As in a regular Nim game, we can break down the game into n number of single heap Nim + games and calculate a grundy number per each heap. Thus, the grundy number for the whole game is the XOR sum of each heap. But since 0-move is allowed, the grundy + number has to be modified per each heap. The grundy number calculation is as follows: + Let g be the grundy function for a single heap Nim game. + g(0) = mex({}) = 0 (Cannot reach any state. Minimum excluded value of the null set is 0) + g(1) = mex{{0, 1}) = 2 (We can reach the n = 1 state by using the zero move and n = 0 state by removing one stone) + g(2) = mex({0, 2, 2}) = 1 (We can reach the n = 2 state by using the zero move and n = 0, 1 states by removing stones. Note that g(1) = 2 and g(0) = 0) + g(3) = mex({0, 2, 1, 3}) = 4 + g(4) = mex({0, 2, 1, 4, 4}) = 3 + ... and so on. + It's obvious that g(n) = n - 1 if n is even and g(n) = n + 1 for all n > 0 +*/ + +#include + +using namespace std; + +int main() { + ios_base::sync_with_stdio(false); + cin.tie(NULL); + int t; + cin >> t; + for (int i = 0; i < t; i++) { + int n, res = 0; + cin >> n; + for (int j = 0; j < n; j++) { + int p; + cin >> p; + if (p & 1) + res ^= p + 1; + else + res ^= p - 1; + } + cout << (res ? "W" : "L") << endl; + } + return 0; +} diff --git a/codeBase/moraXtreme Past Problems/moraXtreme4.0/Alien Agreement/README.md b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Alien Agreement/README.md new file mode 100644 index 0000000..86e2988 --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Alien Agreement/README.md @@ -0,0 +1 @@ +![problem](https://github.com/sathiiii/codeBase/blob/master/codeBase/moraXtreme%20Past%20Problems/moraXtreme4.0/Alien%20Agreement/problem.jpg) diff --git a/codeBase/moraXtreme Past Problems/moraXtreme4.0/Alien Agreement/problem.jpg b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Alien Agreement/problem.jpg new file mode 100644 index 0000000..68ed851 Binary files /dev/null and b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Alien Agreement/problem.jpg differ diff --git a/codeBase/moraXtreme Past Problems/moraXtreme4.0/Alien Agreement/solution.cpp b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Alien Agreement/solution.cpp new file mode 100644 index 0000000..9e2ce6d --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Alien Agreement/solution.cpp @@ -0,0 +1,39 @@ +/* + Copyright (C) 2020, Sathira Silva. + + Link to the problem: https://www.hackerrank.com/contests/moraxtreme-4-0/challenges/alien-agreement/ + + Apporach: This is an easy problem when the city is viewed as a graph. The problem is to find the minimum number of + aliens to remove such that an alien in S is not connected with an alien in T. Therefore, we only need to + consider the edges between S and T. When only those edges and vertices are considered as a sub-graph is + a Bipartite graph since we do not care about the edges inside S or T. Then, to disconnect those edges + such that the removals are minimum all we have to do is remove the minimum of the number of vertices + in partitions that belongs to S and T. +*/ + +#include + +using namespace std; + +int main() { + int n, m, left = 0, right = 0; + cin >> n >> m; + bool vertices[2 * n]; + memset(vertices, false, sizeof(vertices)); + for (int i = 0; i < m; i++) { + int u, v; + cin >> u >> v, u--, v--; + if (u / n != v / n) { + if (!vertices[u]) { + vertices[u] = true; + left++; + } + if (!vertices[v]) { + vertices[v] = true; + right++; + } + } + } + cout << min(left, right); + return 0; +} diff --git a/codeBase/moraXtreme Past Problems/moraXtreme4.0/Are you sick?/README.md b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Are you sick?/README.md new file mode 100644 index 0000000..d5e94ec --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Are you sick?/README.md @@ -0,0 +1 @@ +![problem](https://github.com/sathiiii/codeBase/blob/master/codeBase/moraXtreme%20Past%20Problems/moraXtreme4.0/Are%20you%20sick%3F/problem.jpg) diff --git a/codeBase/moraXtreme Past Problems/moraXtreme4.0/Are you sick?/problem.jpg b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Are you sick?/problem.jpg new file mode 100644 index 0000000..1bb8c0f Binary files /dev/null and b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Are you sick?/problem.jpg differ diff --git a/codeBase/moraXtreme Past Problems/moraXtreme4.0/Are you sick?/solution.cpp b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Are you sick?/solution.cpp new file mode 100644 index 0000000..ea3bdeb --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Are you sick?/solution.cpp @@ -0,0 +1,70 @@ +/* + Copyright (C) 2020, Sathira Silva. + + Link to the problem: https://www.hackerrank.com/contests/moraxtreme-4-0/challenges/are-you-sick/ + + Apporach: The problem is to find matches of given patterns in queried strings. String matching can be efficiently + done using string hashing. Instead of comparing character by character, hashes for each patterns can be + pre-calculated and compared with the hash value of the queried string. I've used the Rabin-Karp algorithm + which uses that idea. +*/ + +#include + +using namespace std; + +const int x = 123; // Any random integer between 1 and p - 1 + +int main() { + int g, t, p = 100007; // Any large prime number + cin >> g; + vector susPatterns(g); // To store the susceptable patterns + vector susHashes(g, 0); // To store the hash values of the patterns + vector h(g, 1); // Used for rehashing (h[i] = x^(length of the pattern) % p for ith pattern) + for (int i = 0; i < g; i++) { + cin >> susPatterns[i]; + // Pre-calculate the hashes of patterns + for (int j = 0; j < susPatterns[i].length(); j++) + susHashes[i] = (x * susHashes[i] + susPatterns[i][j]) % p; + // Pre-calculate the h-values for rehashing + for (int j = 0; j < susPatterns[i].length() - 1; j++) + h[i] = (h[i] * x) % p; + } + cin >> t; + for (int i = 0; i < t; i++) { + string dna; + cin >> dna; + bool found = false; + for (int j = 0; j < g; j++) { + if (dna.length() < susPatterns[j].length()) + continue; + int hash = 0; + // Calculate the hash value of the string for the initial window + for (int k = 0; k < susPatterns[j].length(); k++) + hash = (x * hash + dna[k]) % p; + for (int k = 0; k <= dna.length() - susPatterns[j].length(); k++) { + // If hashes are equal, check whether the strings are actually equal. If not, it's a collision of hashes + if (susHashes[j] == hash) { + int m; + for (m = 0; m < susPatterns[j].length(); m++) + if (dna[m + k] != susPatterns[j][m]) + break; + if (m == susPatterns[j].length()) { + found = true; + break; + } + } + // Rehashing for the next window + if (k < dna.length() - susPatterns[j].length()) { + hash = (x * (hash - dna[k] * h[j]) + dna[k + susPatterns[j].length()]) % p; + if (hash < 0) + hash += p; + } + } + if (found) + break; + } + cout << (found ? "YES" : "NO") << endl; + } + return 0; +} diff --git a/codeBase/moraXtreme Past Problems/moraXtreme4.0/Bi-colored Tree/README.md b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Bi-colored Tree/README.md new file mode 100644 index 0000000..dd02a79 --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Bi-colored Tree/README.md @@ -0,0 +1 @@ +![problem](https://github.com/sathiiii/codeBase/blob/master/codeBase/moraXtreme%20Past%20Problems/moraXtreme4.0/Bi-colored%20Tree/problem.jpg) diff --git a/codeBase/moraXtreme Past Problems/moraXtreme4.0/Bi-colored Tree/problem.jpg b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Bi-colored Tree/problem.jpg new file mode 100644 index 0000000..71e227f Binary files /dev/null and b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Bi-colored Tree/problem.jpg differ diff --git a/codeBase/moraXtreme Past Problems/moraXtreme4.0/Bi-colored Tree/solution.cpp b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Bi-colored Tree/solution.cpp new file mode 100644 index 0000000..5d12ecc --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Bi-colored Tree/solution.cpp @@ -0,0 +1,88 @@ +/* + Copyright (C) 2020, Sathira Silva. + + Link to the problem: https://www.hackerrank.com/contests/moraxtreme-4-0/challenges/bi-colored-tree + + Approach: Finding the number of red vertices in the path from root (0) to any vertex is easy and can be responded to queries in O(1). All we have to do is start from the + root of the tree and breadth-first or depth-first traverse through the tree to accumulate the number of red vertices and store it in the same array. Using that + pre-calculated array, we can answer any query. Suppose the queried vertices x and y are such that their lowest common ancestor is the root of the tree. + Then, the number of red vertices in the path from x to y = tree[x] + tree[y] - tree[0]. + We have to deduct the number of red vertices in the path from root to root i.e. tree[0] because it has been counted twice from both tree[x] and tree[y]. + But if the lowest common ancestor of x and y are not the root, we also have to deduct both tree[lca] and tree[parent of lca] also. Because the numner of red + vertices in the path from lca to lca = tree[lca] - tree[parent of lca] + + Lowest Common Ancestor of two vertices can be found in O(logn) for each query using the algorithm below. The 2D array parent[i][j] stores the jth ancestor of + ith node. depth[i] stores the depth of the ith node. +*/ + +#include + +#define MAXLEVEL 17 + +using namespace std; + +int lca(int u, int v, int parent[][MAXLEVEL], int depth[]) +{ + if (depth[v] < depth[u]) + swap(u, v); + int diff = depth[v] - depth[u]; + for (int i = 0; i< MAXLEVEL; i++) + if ((diff >> i) & 1) + v = parent[v][i]; + if (u == v) + return u; + for (int i = MAXLEVEL - 1; i >=0 ; i--) + if (parent[u][i] != parent[v][i]) + { + u = parent[u][i]; + v = parent[v][i]; + } + return parent[u][0]; +} + +int main() { + int n, T; + cin >> n >> T; + int tree[n], parent[n][MAXLEVEL], depth[n]; + vector> graph(n); + for (int i = 0; i < n; i++) + for (int j = 0; j < MAXLEVEL; j++) + parent[i][j] = -1; + for (int i = 0; i < n; i++) + cin >> tree[i]; + for (int i = 1; i < n; i++) { + int p; + cin >> p; + parent[i][0] = p - 1; + graph[p - 1].push_back(i); + } + queue q; + bool visited[n]; + memset(visited, false, sizeof(visited)); + int u = 0; + visited[u] = true; + depth[u] = 0; + q.push(0); + while (!q.empty()) { + u = q.front(); + q.pop(); + for (int v : graph[u]) + if (!visited[v]) { + visited[v] = true; + tree[v] += tree[u]; + depth[v] = depth[u] + 1; + q.push(v); + } + } + for (int i = 1; i < MAXLEVEL; i++) + for (int u = 0; u < n; u++) + if (parent[u][i - 1] != -1) + parent[u][i] = parent[parent[u][i - 1]][i - 1]; + for (int t = 0; t < T; t++) { + int a, b, _lca; + cin >> a >> b; + _lca = lca(a - 1, b - 1, parent, depth); + cout << (tree[a - 1] + tree[b - 1] - (_lca == 0 ? tree[_lca] : tree[_lca] + tree[parent[_lca][0]])) << endl; + } + return 0; +} diff --git a/codeBase/moraXtreme Past Problems/moraXtreme4.0/Dividing Candies/README.md b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Dividing Candies/README.md new file mode 100644 index 0000000..d0733e0 --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Dividing Candies/README.md @@ -0,0 +1 @@ +![problem](https://github.com/sathiiii/codeBase/blob/master/codeBase/moraXtreme%20Past%20Problems/moraXtreme4.0/Dividing%20Candies/problem.jpg) diff --git a/codeBase/moraXtreme Past Problems/moraXtreme4.0/Dividing Candies/problem.jpg b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Dividing Candies/problem.jpg new file mode 100644 index 0000000..794236c Binary files /dev/null and b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Dividing Candies/problem.jpg differ diff --git a/codeBase/moraXtreme Past Problems/moraXtreme4.0/Dividing Candies/solution.cpp b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Dividing Candies/solution.cpp new file mode 100644 index 0000000..07e432e --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Dividing Candies/solution.cpp @@ -0,0 +1,40 @@ +/* + Copyright (C) 2020, Sathira Silva. + + Link to the problem: https://www.hackerrank.com/contests/moraxtreme-4-0/challenges/candy-distribution-3-1 + + Approach: This can be solved efficiently using dynamic programming. We have to find the largest sum divisible by 3 that can be obtained by the given array. There are three + ways to make the sum divisible by 3. Let x be the element in the array we're currently looking at. So, we have to look at (x % 3 + lastRem) % 3 where lastRem is + the remainder when the previous sum (sum of first i - 1 elements) is divided by 3. + (1). If lastRem = 0, x % 3 = 0 + (2). If lastRem = 1, x % 3 = 2 + (3). If lastRem = 2, x % 3 = 1 can make the sum divisible by 3. + + (01). Subproblems: dp[i][j] = the largest sum that can be made using the first i elements of the array with sum % 3 = k + Base Cases: dp[0][0] = 0, dp[0][1] = -inf, dp[0][2] = -inf + (02). Guessing: is ith element included in the sum or not? + (03). Recurrence: dp[i][j] = max(dp[i - 1][j], candies[i - 1] + dp[i - 1][(j + 3 - candies[i - 1] % 3) % 3]) + (04). Topological order: for i in (1, n) + for j in (0, 3] + (05). Original Problem: dp[n][0] +*/ + +#include + +using namespace std; + +int main() { + int n; + cin >> n; + int candies[n]; + for (int i = 0; i < n; i++) + cin >> candies[i]; + int dp[n + 1][3]; + dp[0][0] = 0, dp[0][1] = INT_MIN, dp[0][2] = INT_MIN; + for (int i = 1; i <= n; i++) { + for (int j = 0; j < 3; j++) + dp[i][j] = max(dp[i - 1][j], candies[i - 1] + dp[i - 1][(j + 3 - candies[i - 1] % 3) % 3]); + } + cout << dp[n][0]; + return 0; +} diff --git a/codeBase/moraXtreme Past Problems/moraXtreme4.0/Gems of Twopow/README.md b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Gems of Twopow/README.md new file mode 100644 index 0000000..df718e8 --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Gems of Twopow/README.md @@ -0,0 +1 @@ +![problem](https://github.com/sathiiii/codeBase/blob/master/codeBase/moraXtreme%20Past%20Problems/moraXtreme4.0/Gems%20of%20Twopow/problem.jpg) diff --git a/codeBase/moraXtreme Past Problems/moraXtreme4.0/Gems of Twopow/problem.jpg b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Gems of Twopow/problem.jpg new file mode 100644 index 0000000..8523a08 Binary files /dev/null and b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Gems of Twopow/problem.jpg differ diff --git a/codeBase/moraXtreme Past Problems/moraXtreme4.0/Gems of Twopow/solution.cpp b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Gems of Twopow/solution.cpp new file mode 100644 index 0000000..86459fc --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Gems of Twopow/solution.cpp @@ -0,0 +1,39 @@ +/* + Copyright (C) 2020, Sathira Silva. + + Link to the problem: https://www.hackerrank.com/contests/moraxtreme-4-0/challenges/gems-of-twopow + + Approach: Consider each m_i as binary bit positions. The sum of pair of same bit makes the next bit. Initially, each bit belongs to it's own bit group. Just after a + pair of same bit group is made, move it to the next bit group recursively. +*/ + +#include + +using namespace std; + +int c[10001]; + +void makeset(int p) { + if (c[p] > 1) { + c[p + 1]++; + c[p] = 0; + makeset(p + 1); + } +} + +int main() { + int n; + cin >> n; + memset(c, 0, sizeof(c)); + for (int i = 0; i < n; i++) { + int p; + cin >> p; + c[p]++; + makeset(p); + } + int res = 0; + for (int i = 0; i < 10001; i++) + res += c[i] > 0; + cout << res; + return 0; +} diff --git a/codeBase/moraXtreme Past Problems/moraXtreme4.0/Ghoul Lover/README.md b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Ghoul Lover/README.md new file mode 100644 index 0000000..a7c80ac --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Ghoul Lover/README.md @@ -0,0 +1 @@ +![problem](https://github.com/sathiiii/codeBase/blob/master/codeBase/moraXtreme%20Past%20Problems/moraXtreme4.0/Ghoul%20Lover/problem.jpg) diff --git a/codeBase/moraXtreme Past Problems/moraXtreme4.0/Ghoul Lover/problem.jpg b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Ghoul Lover/problem.jpg new file mode 100644 index 0000000..77fe4be Binary files /dev/null and b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Ghoul Lover/problem.jpg differ diff --git a/codeBase/moraXtreme Past Problems/moraXtreme4.0/Ghoul Lover/solution.cpp b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Ghoul Lover/solution.cpp new file mode 100644 index 0000000..dc47e80 --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Ghoul Lover/solution.cpp @@ -0,0 +1,49 @@ +/* + Copyright (C) 2020, Sathira Silva. + + Link to the problem: https://www.hackerrank.com/contests/moraxtreme-4-0/challenges/ghoul-lover +*/ + +#include + +using namespace std; + +int main() { + int m; + cin >> m; + vector> energy(m); + for (int i = 0; i < m; i++) { + int p, e; + cin >> p >> e; + energy[i] = {p, e}; + } + // Sort by the position of a ghoul + sort(energy.begin(), energy.end()); + // Pre-calculate the indices of the lastly killed ghouls (sorted by their positions) by an attack from positive infinity ending at position x = i + int lastKill[1000001], p = 0; + for (int j = 0, i = 0; i <= energy[m - 1].first && j < m; i++) { + lastKill[i] = p; + if (energy[j].first == i) { + j++; + p = j; + } + } + int minKills = 1000001; + // Try killing the last half of the ghouls + for (int i = m; i >= (m + 1) / 2; i--) { + // Check how many kills can the current ghoul do + int kills = 0; + for (int j = i - 1; j >= 0;) { + int last = energy[j].first - energy[j].second; // Last position the energy can reach at + if (last < 0) + last = 0; + kills += j - lastKill[last]; + j = lastKill[last] - 1; + } + // m - i is the number of ghouls we're trying to kill in order to minimize the number of kills + minKills = min(minKills, kills + m - i); + if (m - i > minKills) + break; + } + cout << minKills; +} diff --git a/codeBase/moraXtreme Past Problems/moraXtreme4.0/New Range Query/README.md b/codeBase/moraXtreme Past Problems/moraXtreme4.0/New Range Query/README.md new file mode 100644 index 0000000..4b53cba --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme4.0/New Range Query/README.md @@ -0,0 +1 @@ +![problem](https://github.com/sathiiii/codeBase/blob/master/codeBase/moraXtreme%20Past%20Problems/moraXtreme4.0/New%20Range%20Query/problem.jpg) diff --git a/codeBase/moraXtreme Past Problems/moraXtreme4.0/New Range Query/problem.jpg b/codeBase/moraXtreme Past Problems/moraXtreme4.0/New Range Query/problem.jpg new file mode 100644 index 0000000..b7d39ff Binary files /dev/null and b/codeBase/moraXtreme Past Problems/moraXtreme4.0/New Range Query/problem.jpg differ diff --git a/codeBase/moraXtreme Past Problems/moraXtreme4.0/New Range Query/solution.cpp b/codeBase/moraXtreme Past Problems/moraXtreme4.0/New Range Query/solution.cpp new file mode 100644 index 0000000..ef71843 --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme4.0/New Range Query/solution.cpp @@ -0,0 +1,26 @@ +/* + Copyright (C) 2020, Sathira Silva. + + Link to the problem: https://www.hackerrank.com/contests/moraxtreme-4-0/challenges/range-query-1-1 + + Approach: Binary search for the lower and upper boundaries. +*/ + +#include + +using namespace std; + +int main() { + int n, m, q; + cin >> n, cin.ignore(), cin >> m, cin.ignore(), cin >> q; + int arr[m]; + for (int i = 0; i < m; i++) + cin >> arr[i]; + sort(arr, arr + m); + for (int Q = 0; Q < q; Q++) { + int a, b; + cin >> a, cin.ignore(), cin >> b; + cout << (upper_bound(arr, arr + m, b) - lower_bound(arr, arr + m, a)) << endl; + } + return 0; +} diff --git a/codeBase/moraXtreme Past Problems/moraXtreme4.0/Playing With Matrices/README.md b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Playing With Matrices/README.md new file mode 100644 index 0000000..6ff5760 --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Playing With Matrices/README.md @@ -0,0 +1 @@ +![problem](https://github.com/sathiiii/codeBase/blob/master/codeBase/moraXtreme%20Past%20Problems/moraXtreme4.0/Playing%20With%20Matrices/problem.jpg) diff --git a/codeBase/moraXtreme Past Problems/moraXtreme4.0/Playing With Matrices/problem.jpg b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Playing With Matrices/problem.jpg new file mode 100644 index 0000000..a6217ba Binary files /dev/null and b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Playing With Matrices/problem.jpg differ diff --git a/codeBase/moraXtreme Past Problems/moraXtreme4.0/Playing With Matrices/solution.cpp b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Playing With Matrices/solution.cpp new file mode 100644 index 0000000..a6f173d --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Playing With Matrices/solution.cpp @@ -0,0 +1,31 @@ +/* + Copyright (C) 2020, Sathira Silva. + + Link to the problem: https://www.hackerrank.com/contests/moraxtreme-4-0/challenges/matrix-game-1-1 + + Approach: If the input matrix is produced using beta operations, the 1st half of the 1st column and the 2nd half of the 1st row must be equal (or the other way around). If + so, we have to check the same condition of its half size matrix until size 1. When the condition is unsatisfied or the size is odd, then we break from the iteration + and return the size of the previous matrix. +*/ + +#include + +using namespace std; + +int main() { + int n; + cin >> n; + int m[n][n]; + for (int i = 0; i < n; i++) + for (int j = 0; j < n; j++) + cin >> m[i][j]; + int size; + for (size = n; size > 1; size/=2) { + if (size & 1) break; + int left = 0, right = 0; + for (int i = 0; i < size / 2; i++) + left += m[i][0], right += m[0][i + size / 2]; + if (left != right) break; + } + cout << size; +} diff --git a/codeBase/moraXtreme Past Problems/moraXtreme4.0/README.md b/codeBase/moraXtreme Past Problems/moraXtreme4.0/README.md new file mode 100644 index 0000000..3cac5dc --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme4.0/README.md @@ -0,0 +1 @@ +Link to the contest: https://www.hackerrank.com/contests/moraxtreme-4-0/challenges/ diff --git a/codeBase/moraXtreme Past Problems/moraXtreme4.0/Sad Meier's Trivilization/README.md b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Sad Meier's Trivilization/README.md new file mode 100644 index 0000000..e3247c0 --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Sad Meier's Trivilization/README.md @@ -0,0 +1 @@ +![problem](https://github.com/sathiiii/codeBase/blob/master/codeBase/moraXtreme%20Past%20Problems/moraXtreme4.0/Sad%20Meier's%20Trivilization/problem.jpg) diff --git a/codeBase/moraXtreme Past Problems/moraXtreme4.0/Sad Meier's Trivilization/problem.jpg b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Sad Meier's Trivilization/problem.jpg new file mode 100644 index 0000000..ed90d55 Binary files /dev/null and b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Sad Meier's Trivilization/problem.jpg differ diff --git a/codeBase/moraXtreme Past Problems/moraXtreme4.0/Sad Meier's Trivilization/solution.cpp b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Sad Meier's Trivilization/solution.cpp new file mode 100644 index 0000000..a566035 --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Sad Meier's Trivilization/solution.cpp @@ -0,0 +1,36 @@ +/* + Copyright (C) 2020, Sathira Silva. + + Link to the problem: https://www.hackerrank.com/contests/moraxtreme-4-0/challenges/sad-meiers-trivilization + + Approach: An extremely easy problem using the Sprague-Grundy theorem for impartial games. Let g be the grundy function for the game and n be the current state of the game i.e. + the current HP. + g(0) = 0 (Because the grundy number of a zero game is 0 i.e. the first player loses) + g(1) = mex{0} = 1 (the 1st player can shoot with a damage level of 1 and win) + g(2) = mex{0, 1} = 2 (the 1st player can shoot with a damage level of 2 and win) + ... + g(26) = mex{0, 1, ..., 25} = 26 (the 1st player can shoot with a damage level of 26 and win) + g(27) = mex{1, 2, ...., 26} = 0 (Because the maximum damage level the 1st player can do is 26) + ... and so on + Therefore, we can obtain a general formula for g(n) by observing the pattern: + g(n) = n % 27 + So, if the initial HP is divisible by 27, the 1st player loses. Also, in order for first player to win he must always make the grundy number of the next state to + zero. Which implies the initial damage level should be the grundy number of the initial state (because x ^ x = 0). + + + For more details about Sprague-Grundy theorem and it's applications: + https://www.hackerrank.com/topics/game-theory-and-grundy-numbers + https://cp-algorithms.com/game_theory/sprague-grundy-nim.html + https://www.topcoder.com/community/competitive-programming/tutorials/algorithm-games/ +*/ + +#include + +using namespace std; + +int main() { + int n; + cin >> n; + cout << n % 27; + return 0; +} diff --git a/codeBase/moraXtreme Past Problems/moraXtreme4.0/Speed Dating/README.md b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Speed Dating/README.md new file mode 100644 index 0000000..3dca92c --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Speed Dating/README.md @@ -0,0 +1 @@ +![problem](https://github.com/sathiiii/codeBase/blob/master/codeBase/moraXtreme%20Past%20Problems/moraXtreme4.0/Speed%20Dating/problem.jpg) diff --git a/codeBase/moraXtreme Past Problems/moraXtreme4.0/Speed Dating/problem.jpg b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Speed Dating/problem.jpg new file mode 100644 index 0000000..cb774bd Binary files /dev/null and b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Speed Dating/problem.jpg differ diff --git a/codeBase/moraXtreme Past Problems/moraXtreme4.0/Speed Dating/solution.cpp b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Speed Dating/solution.cpp new file mode 100644 index 0000000..4506fa5 --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Speed Dating/solution.cpp @@ -0,0 +1,44 @@ +/* + Copyright (C) 2020, Sathira Silva. + + Link to the problem: https://www.hackerrank.com/contests/moraxtreme-4-0/challenges/speed-dating/ + + Approach: Instead of finding the maximum sum attainable with the limit of k consecutive elements maximum, find the minimum sum of the elements which needs to be skipped + (or removed) in order to get the maximum sum of elements with k consecutive integers maximum. The other way around (finding the maximum sum directly) is + also possible in the same time complexity O(nk) but it gives TLE for the last test case. The dynamic programming steps are as follows: + (01). Subproblems: dp[i] the minimum sum of elements to skip using first i elements + Base cases: from i = 0 upto k, dp[i] = 0 + (02). Guessing: should we remove the jth element or not? (for j from i - k to i) + (03). Recursion: dp[i] = min(dp[j - 1] + arr[j] for all j from i - k to i) + (04). Topological order: for i from k + 1 to n + for j from i - k to i + (05). Original problem: sum of the array - dp[n] + + There is a better O(n) solution for this problem using a monotone priority queue but O(nk) was enough to pass all of the test cases. +*/ + +#include + +using namespace std; + +typedef long long ll; + +int main() { + int n, k; + cin >> n >> k; + ll desirabilities[n], sum = 0; + for (int i = 0; i < n; i++) { + cin >> desirabilities[i]; + sum += desirabilities[i]; + } + ll dp[n + 1]; + // Base Cases: + for (int i = 0; i <= k; i++) + dp[i] = 0; + for (int i = k + 1; i <= n; i++) { + dp[i] = dp[i - k - 1] + desirabilities[i - k - 1]; + for (int j = i - k + 1; j <= i; j++) + dp[i] = min(dp[i], dp[j - 1] + desirabilities[j - 1]); + } + cout << (sum - dp[n]); +} diff --git a/codeBase/moraXtreme Past Problems/moraXtreme4.0/Strange House/README.md b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Strange House/README.md new file mode 100644 index 0000000..9358da3 --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Strange House/README.md @@ -0,0 +1 @@ +![problem](https://github.com/sathiiii/codeBase/blob/master/codeBase/moraXtreme%20Past%20Problems/moraXtreme4.0/Strange%20House/problem.jpg) diff --git a/codeBase/moraXtreme Past Problems/moraXtreme4.0/Strange House/problem.jpg b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Strange House/problem.jpg new file mode 100644 index 0000000..b5efe41 Binary files /dev/null and b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Strange House/problem.jpg differ diff --git a/codeBase/moraXtreme Past Problems/moraXtreme4.0/Strange House/solution.cpp b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Strange House/solution.cpp new file mode 100644 index 0000000..4ebe45a --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Strange House/solution.cpp @@ -0,0 +1,36 @@ +/* + Copyright (C) 2020, Sathira Silva. + + Link to the problem: https://www.hackerrank.com/contests/moraxtreme-4-0/challenges/strange-house + + Approach: Note that two walls in two regions getting aligned is equivalent to the number of rooms in those reigions have a common factor. So, in order to partition the whole + house into isolated parts, all three reigions must have a common factor in their number of rooms. Therefore, if gcd(n, m, k) = 1 any room is reachable from any + other room because there will be no isolated partitions. But if it's not the case, we have to check whether both rooms are in the same isolated partition or not. + Because any room in a particular isolated partition is reachable from any other room inside that partition. We can simply check that by dividing the 0-indexed + index number of the rooms by the number of rooms inside an isolated partition of their corresponding reigion and comparing whether they're equal or not. +*/ + +#include + +using namespace std; + +int main() { + long long region[3]; + int q; + cin >> region[0], cin.ignore(), cin >> region[1], cin.ignore(), cin >> region[2], cin.ignore(), cin >> q; + long long g = __gcd(region[0], __gcd(region[1], region[2])); + if (g != 1) + region[0] /= g, region[1] /= g, region[2] /= g; // Calculate the number of rooms inside an isolated partition for each region + for (int t = 0; t < q; t++) { + long long x, y, w, z; + cin >> x, cin.ignore(), cin >> y, cin.ignore(), cin >> w, cin.ignore(), cin >> z; + if (g == 1) + cout << "YES" << endl; + else if ((y - 1) / region[x - 1] == (z - 1) / region[w - 1]) { + cout << "YES" << endl; + } + else + cout << "NO" << endl; + } + return 0; +} diff --git a/codeBase/moraXtreme Past Problems/moraXtreme4.0/Tony Shark/README.md b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Tony Shark/README.md new file mode 100644 index 0000000..764ceb9 --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Tony Shark/README.md @@ -0,0 +1 @@ +![problem](https://github.com/sathiiii/codeBase/blob/master/codeBase/moraXtreme%20Past%20Problems/moraXtreme4.0/Tony%20Shark/problem.jpg) diff --git a/codeBase/moraXtreme Past Problems/moraXtreme4.0/Tony Shark/problem.jpg b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Tony Shark/problem.jpg new file mode 100644 index 0000000..4f4b12b Binary files /dev/null and b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Tony Shark/problem.jpg differ diff --git a/codeBase/moraXtreme Past Problems/moraXtreme4.0/Tony Shark/solution.cpp b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Tony Shark/solution.cpp new file mode 100644 index 0000000..0905391 --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme4.0/Tony Shark/solution.cpp @@ -0,0 +1,86 @@ +/* + Copyright (C) 2020, Sathira Silva. + + Link to the problem: https://www.hackerrank.com/contests/moraxtreme-4-0/challenges/tony-shark + + Approach: Sing 'Tony shark do-do-do-do-do-do/// Tony shark!' until you get a solution :) +*/ + +#include + +using namespace std; + +int main() { + int n; + cin >> n; + if (n < 3 || n > 12) + cout << "invalid"; + else { + string s = ""; + int tail = 0; + int len = 6 * n + 2 * n * n; // Length of the middle line + // Print the top fin + for (int i = 0; i < n; i++) { + for (int j = 0; j < n * n - i; j++) + s += " "; + for (int j = 0; j < 2 * i + 1; j++) + s += "M"; + // Print the tail + if (i != 0) { + for (int j = 0; j <= len - n * n - 3 + n - 2 * i; j++) + s += " "; + for (int j = 0; j < 1 + tail / 2; j++) + s += "M"; + tail++; + } + s += "\n"; + } + // Print the top body + for (int i = 0; i < n; i++) { + for (int j = 0; j < (n - i) * (n - 2); j++) + s += " "; + for (int j = 0; j < 6 * n + 2 * n * i; j++) + s += "M"; + for (int j = 0; j < 2 + 6 * n + 2 * n * (n - 1) + (n - 2) + (n - i - 1) - (n - i) * (n - 2) - (6 * n + 2 * n * i); j++) + s += " "; + for (int j = 0; j < 1 + tail / 2; j++) + s += "M"; + tail++; + s += "\n"; + } + // Middle Line + for (int j = 0; j < 6 * n + 2 * n * n; j++) + s += "M"; + s += "\n"; + tail--; + // Print the bottom body + for (int i = n - 1; i >= 0; i--) { + for (int j = 0; j < (n - i) * (n - 2); j++) + s += " "; + for (int j = 0; j < 6 * n + 2 * n * i; j++) + s += "M"; + for (int j = 0; j < 2 + 6 * n + 2 * n * (n - 1) + (n - 2) + (n - i - 1) - (n - i) * (n - 2) - (6 * n + 2 * n * i); j++) + s += " "; + for (int j = 0; j < 1 + tail / 2; j++) + s += "M"; + tail--; + s += "\n"; + } + // Print the bottom fin + for (int i = n - 2; i >= 0; i--) { + for (int j = 0; j < n * n - i; j++) + s += " "; + for (int j = 0; j < 2 * i + 1; j++) + s += "M"; + // Print the tail + for (int j = 0; j < len - n * n - 3 + n - 2 * i; j++) + s += " "; + for (int j = 0; j < 1 + tail / 2; j++) + s += "M"; + tail--; + s += "\n"; + } + cout << s; + } + return 0; +} diff --git a/codeBase/moraXtreme Past Problems/moraXtreme5.0/1939/README.md b/codeBase/moraXtreme Past Problems/moraXtreme5.0/1939/README.md new file mode 100644 index 0000000..79d425f --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme5.0/1939/README.md @@ -0,0 +1 @@ +![problem](problem.jpg) diff --git a/codeBase/moraXtreme Past Problems/moraXtreme5.0/1939/problem.jpg b/codeBase/moraXtreme Past Problems/moraXtreme5.0/1939/problem.jpg new file mode 100644 index 0000000..55ed9c8 Binary files /dev/null and b/codeBase/moraXtreme Past Problems/moraXtreme5.0/1939/problem.jpg differ diff --git a/codeBase/moraXtreme Past Problems/moraXtreme5.0/1939/solution.cpp b/codeBase/moraXtreme Past Problems/moraXtreme5.0/1939/solution.cpp new file mode 100644 index 0000000..1e95328 --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme5.0/1939/solution.cpp @@ -0,0 +1,53 @@ +/* + Copyright (C) 2020, Sathira Silva. + + Link to the problem: https://www.hackerrank.com/contests/moraxtreme-5-0/challenges/1939 + + Apporach: If voco is a leaf vertex (number of adjacent vertices = 1) it can be captured by the first player immediately thus, Stalind wins. Otherwise, they both have to + capture the other vertices alternatively before they capture the city voco. Therefore, start a BFS / DFS from the city voco and count the number of grandchildern + of voco. Since the requirement to capture a city is at most having one grandchild, if (#grandchildren - 1) is even, always the first player wins and if it is odd, + the second player wins. + + Time Complexity: O(n) since the graph is a tree +*/ + +#include + +using namespace std; + +int main() { + int t; + cin >> t; + for (int _ = 0; _ < t; _++) { + int n, voco; + cin >> n >> voco; + vector> graph(n + 1); + for (int i = 0; i < n - 1; i++) { + int u, v; + cin >> u >> v; + graph[u].push_back(v); + graph[v].push_back(u); + } + if (graph[voco].size() == 1) // Check if Hitalnd can win immediately + cout << "Hitland" << endl; + else { // Otherwise, traverse the tree Breadth-First + bool visited[n + 1]; + memset(visited, false, sizeof(visited)); + int grandchildren = 0; + queue q; + int u = voco; + q.push(voco); + while (!q.empty()) { + u = q.front(); + q.pop(); + visited[u] = true; + for (int v : graph[u]) + if (!visited[v]) { + q.push(v); + grandchildren++; + } + } + cout << ((grandchildren - 1) & 1 ? "Stalind" : "Hitland") << endl; + } + } +} diff --git a/codeBase/moraXtreme Past Problems/moraXtreme5.0/README.md b/codeBase/moraXtreme Past Problems/moraXtreme5.0/README.md new file mode 100644 index 0000000..113e34f --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme5.0/README.md @@ -0,0 +1 @@ +Link to the contest: https://www.hackerrank.com/contests/moraxtreme-5-0/challenges/1939 diff --git a/codeBase/moraXtreme Past Problems/moraXtreme5.0/Return to One/README.md b/codeBase/moraXtreme Past Problems/moraXtreme5.0/Return to One/README.md new file mode 100644 index 0000000..79d425f --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme5.0/Return to One/README.md @@ -0,0 +1 @@ +![problem](problem.jpg) diff --git a/codeBase/moraXtreme Past Problems/moraXtreme5.0/Return to One/problem.jpg b/codeBase/moraXtreme Past Problems/moraXtreme5.0/Return to One/problem.jpg new file mode 100644 index 0000000..8f5bbf2 Binary files /dev/null and b/codeBase/moraXtreme Past Problems/moraXtreme5.0/Return to One/problem.jpg differ diff --git a/codeBase/moraXtreme Past Problems/moraXtreme5.0/Return to One/solution.cpp b/codeBase/moraXtreme Past Problems/moraXtreme5.0/Return to One/solution.cpp new file mode 100644 index 0000000..da37044 --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme5.0/Return to One/solution.cpp @@ -0,0 +1,37 @@ +/* + Copyright (C) 2020, Sathira Silva. + + Link to the problem: https://www.hackerrank.com/contests/moraxtreme-5-0/challenges/return-to-1 + + Approach: Collatz Conjecture (https://en.wikipedia.org/wiki/Collatz_conjecture) says 'no matter what value of n, the sequence will always reach 1'. Therefore, recursively + apply the operations and count the number of steps a needed until the number reaches 1 using memoization. +*/ + +#include + +using namespace std; + +map memo; + +int steps(int n) { + // Base Case: + if (n == 1) + return 0; + if (memo.count(n)) + return memo[n]; + if ((n & 1) == 0) + return memo[n] = steps(n >> 1) + 1; + return memo[n] = steps(3 * n + 1) + 1; +} + +int main() { + int n; + cin >> n; + for (int _ = 0; _ < n; _++) { + int kapila, kalpa; + cin >> kapila >> kalpa; + int s = steps(kalpa), t = steps(kapila); + cout << (s < t ? "Kalpa" : s == t ? "-" : "Kapila") << endl; + } + return 0; +} diff --git a/codeBase/moraXtreme Past Problems/moraXtreme5.0/Subset Sum/README.md b/codeBase/moraXtreme Past Problems/moraXtreme5.0/Subset Sum/README.md new file mode 100644 index 0000000..79d425f --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme5.0/Subset Sum/README.md @@ -0,0 +1 @@ +![problem](problem.jpg) diff --git a/codeBase/moraXtreme Past Problems/moraXtreme5.0/Subset Sum/problem.jpg b/codeBase/moraXtreme Past Problems/moraXtreme5.0/Subset Sum/problem.jpg new file mode 100644 index 0000000..2f11be3 Binary files /dev/null and b/codeBase/moraXtreme Past Problems/moraXtreme5.0/Subset Sum/problem.jpg differ diff --git a/codeBase/moraXtreme Past Problems/moraXtreme5.0/Subset Sum/solution.cpp b/codeBase/moraXtreme Past Problems/moraXtreme5.0/Subset Sum/solution.cpp new file mode 100644 index 0000000..5b51aa9 --- /dev/null +++ b/codeBase/moraXtreme Past Problems/moraXtreme5.0/Subset Sum/solution.cpp @@ -0,0 +1,40 @@ +/* + Copyright (C) 2020, Sathira Silva. + + Link to the problem: https://www.hackerrank.com/contests/moraxtreme-5-0/challenges/noi-subset-sum + + Approach: This problem can be solved easily with dynamic programming (the recurrence is similar to the discrete knapsack without repetition problem). + + (01). Subproblems: let dp[i][x] be the number of subsets using the first i elements having sum equal to x. + Base Cases: dp[i][0] = 1 for all i = 0 to n + dp[0][x] = 0 for all x except 0 + (02). Guessing: Is ith number included in the subset or not? + (03). Recurrence: dp[i][x] = dp[i - 1][x] + dp[i - 1][x - A[i - 1]] if i >= 1 else dp[i - 1][x] + (04). Topological order: for i = 1,...n + for x = 1,...s + (05). Original problem: dp[n][s] +*/ +#include + +using namespace std; + +typedef unsigned long long ull; + +int main() { + int n, s; + cin >> n >> s; + int A[n]; + for (int i = 0; i < n; i++) + cin >> A[i]; + ull dp[n + 1][s + 1]; + // Base Cases: number of sets having sum = 0 from the first i items is 1 (the null set) + for (int i = 0; i <= n; i++) + dp[i][0] = 1ULL; + // Base Cases: no items having a sum (except sum = 0) is 0 + for (int x = 1; x <= s; x++) + dp[0][x] = 0; + for (int i = 1; i <= n; i++) + for (int x = 1; x <= s; x++) + dp[i][x] = dp[i - 1][x] + (x >= A[i - 1]) * dp[i - 1][x - A[i - 1]]; + cout << dp[n][s]; +}