diff --git a/AlgorithmConcepts/Graphs/graph.py b/AlgorithmConcepts/Graphs/graph.py new file mode 100644 index 0000000..11b17af --- /dev/null +++ b/AlgorithmConcepts/Graphs/graph.py @@ -0,0 +1,67 @@ +### Graph Theory Datastructure +# Helper: https://www.python-course.eu/graphs_python.php + +# * Directed graph -> no reversible flow, the flow or edge remains in single direction +# * UnDirected graph -> reversible flow, the flow or edge in on both the direction + + +## Represent a Graph with list and dictionary + +# Undirected +graph1 = { + "node1": ["node2", "node4"], + "node2": ["node1", "node3"], + "node3": ["node2"], + "node4": ["node1"] +} + +# If nodes are index of a list then we can use list representation +graph2 = [[2, 4], [1, 3], [2], [1]] + +# Directed +graph3 = { + "node1": ["node2", "node4"], + "node2": ["node3"], + "node3": ["node4"], + "node4": [] +} + +graph4 = [[2, 4], [3], [4], []] + + +## Create a Graph - when given a list of relationships +example_relations = [("c1","c2"), ("c2","c3"), ("c1","c4"), ("c2","c1"), ("c3","c2"), ("c4","c1")] +graph5 = {} +for relation in example_relations: + node1 = relation[0] + node2 = relation[1] + if node1 not in graph5: + graph5[node1] = [] + if node2 not in graph5: + graph5[node2] = [] + if node2 not in graph5[node1]: + graph5[node1].append(node2) +print(graph5) + +## Get Edges and Vertices +nodes = graph3.keys() +edges = [] +for node in graph3.keys(): + for node2 in graph3[node]: + edges.append((node, node2)) +print(nodes, edges) + +## Breath First Traverse or Topological Sort + +# Iterative + +# Recursive + +## Depth First Traverse Graph + +# Iterative + +# Recursive + +## Traverse through all the nodes of the Graph - Give relative ordering of all the nodes + diff --git a/AlgorithmConcepts/dynamicProgramming/fibo.py b/AlgorithmConcepts/dynamicProgramming/fibo.py new file mode 100644 index 0000000..dfa74ed --- /dev/null +++ b/AlgorithmConcepts/dynamicProgramming/fibo.py @@ -0,0 +1,43 @@ +# Dynamic Programming +## * Problem solved by dividing into sub-problems which are dependent and reused to create the solution + +# Example: Fibonacci - sum of last 2 digits form the third digit + +# Recursion Method +## * Essence of divide and conquer a problem with subproblems to obtain the solution + +def fibonacci(n): + if n == 0: + return 0 + elif n == 1: + return 1 + else: + return fibonacci(n-1) + fibonacci(n-2) + +# Top Down Approach - Memoization +## * Create a table to store sub-problem solutions that can be reused +## * On-demand storing of sub-problem that only need to be reused +## * First lookup the table for sub-problem solution then calculate + +memo = [0, 1] +def fibonacci_top(n): + + if n < len(memo): + return memo[n] + else: + memo.append(fibonacci(n-1) + fibonacci(n-2)) + return memo[-1] + +# Bottom Up Approach - Mandatory tabulation to find the answer ( build from ground to answer ) +def fibonacci_bottom(n): + + table = [0,1] + + for i in range(2, n+1): + table.append(table[i-1]+table[i-2]) + + return table[-1] + +print fibonacci(4) +print fibonacci_top(4) +print fibonacci_bottom(4) diff --git a/AlgorithmConcepts/dynamicProgramming/notes.pdf b/AlgorithmConcepts/dynamicProgramming/notes.pdf new file mode 100644 index 0000000..595913b Binary files /dev/null and b/AlgorithmConcepts/dynamicProgramming/notes.pdf differ diff --git a/AlgorithmConcepts/sorting/heapSort/heap.py b/AlgorithmConcepts/sorting/heapSort/heap.py new file mode 100644 index 0000000..916a534 --- /dev/null +++ b/AlgorithmConcepts/sorting/heapSort/heap.py @@ -0,0 +1,35 @@ +# Logic reference to geekOfGeeks + +def heapify(a, n, index): + largest = index + + left = 2*index+1 + right = 2*index+2 + + if left < n and a[left] > a[largest]: + largest = left + + if right < n and a[right] > a[largest]: + largest = right + + if largest != index: + a[index], a[largest] = a[largest], a[index] + heapify(a, n, largest) + +def heapSort(a): + n = len(a) + + for i in range(n, -1, -1): + heapify(a, n, i) + + for i in range(n-1, 0, -1): + a[i], a[0] = a[0], a[i] + heapify(a, i, 0) + +def main(): + a = [5,2,6,7,9,3,1,0] + heapSort(a) + print a + +main() + diff --git a/AlgorithmConcepts/sorting/mergeSort/mergeN.py b/AlgorithmConcepts/sorting/mergeSort/mergeN.py new file mode 100644 index 0000000..2356c77 --- /dev/null +++ b/AlgorithmConcepts/sorting/mergeSort/mergeN.py @@ -0,0 +1,41 @@ +class Solution(object): + def mergeSort(self, nums): + if len(nums) > 1: + n = len(nums) + mid = n//2 + l = nums[:mid] + r = nums[mid:] + + self.mergeSort(l) + self.mergeSort(r) + + i = j = k = 0 + + while i < len(l) and j < len(r): + if l[i] < r[j]: + nums[k] = l[i] + i += 1 + else: + nums[k] = r[j] + j += 1 + k += 1 + + while i < len(l): + nums[k] = l[i] + i += 1 + k += 1 + + while j < len(r): + nums[k] = r[j] + j += 1 + k += 1 + + def sortArray(self, arr): + """ + :type nums: List[int] + :rtype: List[int] + """ + self.mergeSort(arr) + return arr + + diff --git a/Go Lang/101_1.go b/GoLang/101_1.go similarity index 100% rename from Go Lang/101_1.go rename to GoLang/101_1.go diff --git a/Go Lang/101_2.go b/GoLang/101_2.go similarity index 100% rename from Go Lang/101_2.go rename to GoLang/101_2.go diff --git a/Go Lang/101_3.go b/GoLang/101_3.go similarity index 100% rename from Go Lang/101_3.go rename to GoLang/101_3.go diff --git a/Go Lang/101_4.go b/GoLang/101_4.go similarity index 100% rename from Go Lang/101_4.go rename to GoLang/101_4.go diff --git a/Go Lang/101_5.go b/GoLang/101_5.go similarity index 100% rename from Go Lang/101_5.go rename to GoLang/101_5.go diff --git a/Go Lang/101_6.go b/GoLang/101_6.go similarity index 100% rename from Go Lang/101_6.go rename to GoLang/101_6.go diff --git a/Go Lang/101_7.go b/GoLang/101_7.go similarity index 100% rename from Go Lang/101_7.go rename to GoLang/101_7.go diff --git a/Go Lang/101_8.go b/GoLang/101_8.go similarity index 100% rename from Go Lang/101_8.go rename to GoLang/101_8.go diff --git a/Go Lang/101_9.go b/GoLang/101_9.go similarity index 100% rename from Go Lang/101_9.go rename to GoLang/101_9.go diff --git a/Go Lang/Fibonacci.go b/GoLang/Fibonacci.go similarity index 100% rename from Go Lang/Fibonacci.go rename to GoLang/Fibonacci.go diff --git a/Go Lang/Hello.go b/GoLang/Hello.go similarity index 100% rename from Go Lang/Hello.go rename to GoLang/Hello.go diff --git a/GoLang/README.md b/GoLang/README.md new file mode 100644 index 0000000..26d6f2c --- /dev/null +++ b/GoLang/README.md @@ -0,0 +1,4 @@ +# Go Language Algorithms +* Basics - 101s +* ProblemSolving - started with golang problemsolving (dominant in python until now). Will maintian a redundancy here on problem solving in golang. Will move towards the main folder once more contributions are made. + diff --git a/Go Lang/array_rotate.go b/GoLang/array_rotate.go similarity index 100% rename from Go Lang/array_rotate.go rename to GoLang/array_rotate.go diff --git a/Go Lang/bst.go b/GoLang/bst.go similarity index 100% rename from Go Lang/bst.go rename to GoLang/bst.go diff --git a/Go Lang/memo_fibo.go b/GoLang/memo_fibo.go similarity index 100% rename from Go Lang/memo_fibo.go rename to GoLang/memo_fibo.go diff --git a/GoLang/problemSolving/numberOfUniqueEmails.go b/GoLang/problemSolving/numberOfUniqueEmails.go new file mode 100644 index 0000000..2423322 --- /dev/null +++ b/GoLang/problemSolving/numberOfUniqueEmails.go @@ -0,0 +1,37 @@ +func numUniqueEmails(emails []string) int { + + result := []string{} + + for _, email := range emails { + + // split local and domain name with "@" + e := strings.Split(email, "@") + localname, domainname := e[0], e[1] + + if strings.Contains(localname, ".") { + localname = strings.Replace(localname, ".", "", -1) + } + + if strings.Contains(localname, "+") { + localname = strings.Split(localname, "+")[0] + } + + // Debug + //fmt.Println(localname+"@"+domainname) + filtered_email := localname+"@"+domainname + + existence := 0 + for _, val := range result { + if val == filtered_email { + existence = 1 + } + } + + if existence == 0 { + result = append(result, filtered_email) + } + + } + + return len(result) +} diff --git a/Go Lang/rfibo_recur.go b/GoLang/rfibo_recur.go similarity index 100% rename from Go Lang/rfibo_recur.go rename to GoLang/rfibo_recur.go diff --git a/Jam/codeJam1.py b/Jam/codeJam1.py new file mode 100644 index 0000000..4674d12 --- /dev/null +++ b/Jam/codeJam1.py @@ -0,0 +1,14 @@ +def give_check(amount): + other = "" + for i in str(amount): + if i == "4": + other += "1" + else: + other += i + return other, str(int(amount)-int(other)) + + +tcs = input() +for i in range(int(tcs)): + one, two = give_check(input()) + print "Case #"+str(i+1)+": "+one+" "+two \ No newline at end of file diff --git a/Jam/codeJam2.py b/Jam/codeJam2.py new file mode 100644 index 0000000..4c9c9db --- /dev/null +++ b/Jam/codeJam2.py @@ -0,0 +1,18 @@ +def solve_maze(grid, lydia_movement): + path = (0,0) + lydia = [(0,0)] + me = "E" if lydia_movement[0] == "S" else "S" + for direction in lydia_movement[1:]: + if direction == "E": + lydia.append((lydia[-1][0]+1, lydia[-1][1])) + me += "S" + else: + lydia.append((lydia[-1][0], lydia[-1][1]+1)) + me += "E" + return me + +tcs = input() +for i in range(int(tcs)): + grid = input() + lydia_movement = raw_input() + print "Case #"+str(i+1)+": "+solve_maze(grid, lydia_movement) \ No newline at end of file diff --git a/Jam/codeJam3.go b/Jam/codeJam3.go new file mode 100644 index 0000000..6b7cc15 --- /dev/null +++ b/Jam/codeJam3.go @@ -0,0 +1,18 @@ +package main + +import ( + "fmt" +) + +func main() { + var testcases int + fmt.Scanf("%d", &testcases) + for i := 0; i < testcases; i++ { + var N, L int + fmt.Scanf("%d %d", &N, &L) + fmt.Println(N, L) + var ciphertext string + fmt.Scanf("%s", &ciphertext) + fmt.Println(ciphertext) + } +} diff --git a/Jam/codeJam3.py b/Jam/codeJam3.py new file mode 100644 index 0000000..76c0a51 --- /dev/null +++ b/Jam/codeJam3.py @@ -0,0 +1,94 @@ +def is_a_prime(number): + #import math + # Assume number is odd, Neglecting 1 and number itself + # 2 is the only even prime + if number%2 == 0: + return False + #for i in range(3, int(math.sqrt(number))+1, 2): + for i in range(3, int(number**(1/2.0))+1, 2): + if number%i == 0: + return False + return True + +def prime_list_under(N): + # Get All the Prime Numbers + # Just get the first 2 primes to get this done... --> this would work when the plaintext is ABC in order? + # Iterate only odd number --> potential prime candidates + primes = [] + for i in range(3, N+1, 2): + if is_a_prime(i): + #if target//i in primes: + # return i, target//i + #else: + primes.append(i) + return primes + +def decrypt(N, ciphertext): + # Get all the primes under N + # get first 2 primes to calculate others? Wont work + primes = prime_list_under(N) + #print primes + crypto_key = [] # Selected primes + # Find the First prime that is divisible here + target = int(ciphertext[0]) + #for prime in primes: + # if target%prime == 0: + # crypto_key.append(prime) + # crypto_key.append(target//prime) + # break + k = 0 + while target%primes[k] != 0: + k += 1 + crypto_key.append(primes[k]) + crypto_key.append(target//primes[k]) + if len(ciphertext) > 1 and int(ciphertext[1])%crypto_key[0] == 0: + crypto_key = crypto_key[::-1] + #print crypto_key + next = crypto_key[-1] + count = 1 + while count < len(ciphertext): + next = int(ciphertext[count])//next + #print ciphertext[count], crypto_key[-1], next, crypto_key + crypto_key.append(next) + count += 1 + """ + stack = [crypto_key[-1], target//crypto_key[-1]] + while stack: + current = stack.pop(0) + if current not in crypto_key: + crypto_key.append(current) + for cipher in ciphertext: + if int(cipher)%current == 0 and (int(cipher)//current not in crypto_key): + stack.append(int(cipher)//current) + """ + alphabets = sorted(set(crypto_key)) + #print crypto_key, alphabets + result = "" + for c in crypto_key: + result += chr(65+alphabets.index(c)) + return result + + +# Encryption Scheme +# * Given N and Length of the ciphertext +# * Ans: +# * Length og the plaintext is len(ciphertext)+1 +# * Choose prime numbers (26) upto N and compute product of adjacent numbers + +""" +# Input Format +2 +103 31 +217 1891 4819 2291 2987 3811 1739 2491 4717 445 65 1079 8383 5353 901 187 649 1003 697 3239 7663 291 123 779 1007 3551 1943 2117 1679 989 3053 +10000 25 +3292937 175597 18779 50429 375469 1651121 2102 3722 2376497 611683 489059 2328901 3150061 829981 421301 76409 38477 291931 730241 959821 1664197 3057407 4267589 4729181 5335543 +""" +tcs = raw_input() +for i in range(int(tcs)): + N, L = raw_input().split(" ") + ciphertext= raw_input().split(" ") + print ciphertext, N, L + if len(ciphertext) != int(L): + print "Case #"+str(i+1)+": "+"Length Not Equal!" + else: + print "Case #"+str(i+1)+": "+decrypt(int(N), ciphertext) \ No newline at end of file diff --git a/Jam/codeJam3_1.py b/Jam/codeJam3_1.py new file mode 100644 index 0000000..79169c3 --- /dev/null +++ b/Jam/codeJam3_1.py @@ -0,0 +1,57 @@ +def is_a_prime(number): + if number%2 == 0: + return False + for i in range(3, int(number**(1/2.0))+1, 2): + if number%i == 0: + return False + return True + +def prime_list_under(N): + primes = [2] + for i in range(3, N+1, 2): + if is_a_prime(i): + primes.append(i) + return primes + +def decrypt(N, ciphertext): + primes = prime_list_under(N) + print primes + crypto_key = [] + future = None + while ciphertext: + target = int(ciphertext.pop(0)) + if not crypto_key and not future: + p = 0 + while p < len(primes) and future == None: + if target%primes[p] == 0 and target//primes[p] in primes: + future = target//primes[p] + p += 1 + crypto_key.append(primes[p-1]) + crypto_key.append(future) + if len(ciphertext) > 1: + if int(ciphertext[1])%crypto_key[0] == 0: + crypto_key = crypto_key[::-1] + future = crypto_key[-1] + else: + if future and target//future in primes: + crypto_key.append(target//future) + future = crypto_key[-1] + + alphabets = sorted(set(crypto_key)) + result = "" + for c in crypto_key: + result += chr(65+alphabets.index(c)) + print crypto_key, alphabets + return result + +tcs = raw_input() +for i in range(int(tcs)): + N, L = raw_input().split(" ") + ciphertext= raw_input().split(" ") + #print ciphertext, N, L + if ciphertext == "": + print "Case #"+str(i+1)+": "+"" + elif len(ciphertext) != int(L): + print "Case #"+str(i+1)+": "+"Length Not Equal!" + else: + print "Case #"+str(i+1)+": "+decrypt(int(N), ciphertext) \ No newline at end of file diff --git a/Jam/codeJamRound1A1.py b/Jam/codeJamRound1A1.py new file mode 100644 index 0000000..1ddd7e5 --- /dev/null +++ b/Jam/codeJamRound1A1.py @@ -0,0 +1,221 @@ +# codeJamRound1A1.py + +# Attempt 1 --> Went bruteforce + greedy without taking care of the maximum possibility +# - Sample testcases pass but fails with Wrong answer when submit +""" +def longestSubset(word1, word2): + n = min(len(word1), len(word2)) + count = 0 + for i in range(1, n+1): + if word1[-i:] == word2[-i:]: + count += 1 + return count + +def alien_rhymes(words): + # BruteForce Logic + n = len(words) + pairs = [] + count = 0 + for i in range(n): + for j in range(n): + if i != j and words[i] not in pairs and words[j] not in pairs: + if longestSubset(words[i], words[j]) != 0: + pairs.append(words[i]) + pairs.append(words[j]) + count += longestSubset(words[i], words[j]) + j = n-1 + return count + + + +tcs = raw_input() +for i in range(int(tcs)): + lines = int(raw_input()) + words = [] + for line in range(lines): + words.append(raw_input()) + print "Case #"+str(i+1)+": "+str(alien_rhymes(words)) +""" + + +# Better logic to maximum the subset length +# Still needs work... +""" +def longestSubset(word1, word2): + n = min(len(word1), len(word2)) + count = 0 + for i in range(1, n+1): + if word1[-i:] == word2[-i:]: + count += 1 + return count + +def alien_rhymes(words): + # BruteForce Logic + n = len(words) + pairs = [] + count = 0 + records = {} # Max subset: pair + # Get all possible combination + for i in range(n): + for j in range(n): + if i != j and words[i]: #not in pairs and words[j] not in pairs: + subset = longestSubset(words[i], words[j]) + if subset != 0: + if subset not in records: + records[subset] = (words[i], words[j]) + else: + #while subset in records: + # subset = subset + if type(records[subset]) != list: + records[subset] = list([records[subset]]) + records[subset].append((words[i], words[j])) + #pairs.append(words[i]) + #pairs.append(words[j]) + #count += longestSubset(words[i], words[j]) + #j = n-1 + subsets = sorted(records.keys(), reverse=True) + #print records + for sub in subsets: + while records[sub]: + current = records[sub].pop() + if current[0] not in pairs and current[1] not in pairs: + count += sub + pairs.append(current[0]) + pairs.append(current[1]) + return count + +tcs = raw_input() +for i in range(int(tcs)): + lines = int(raw_input()) + words = [] + for line in range(lines): + words.append(raw_input()) + print "Case #"+str(i+1)+": "+str(alien_rhymes(words)) +""" + +# codeJamRound1A1.py + +# Attempt 1 --> Went bruteforce + greedy without taking care of the maximum possibility +# - Sample testcases pass but fails with Wrong answer when submit +""" +def longestSubset(word1, word2): + n = min(len(word1), len(word2)) + count = 0 + for i in range(1, n+1): + if word1[-i:] == word2[-i:]: + count += 1 + return count + +def alien_rhymes(words): + # BruteForce Logic + n = len(words) + pairs = [] + count = 0 + for i in range(n): + for j in range(n): + if i != j and words[i] not in pairs and words[j] not in pairs: + if longestSubset(words[i], words[j]) != 0: + pairs.append(words[i]) + pairs.append(words[j]) + count += longestSubset(words[i], words[j]) + j = n-1 + return count + + + +tcs = raw_input() +for i in range(int(tcs)): + lines = int(raw_input()) + words = [] + for line in range(lines): + words.append(raw_input()) + print "Case #"+str(i+1)+": "+str(alien_rhymes(words)) +""" + +def longestSubset(word1, word2): + n = min(len(word1), len(word2)) + count = 0 + for i in range(1, n+1): + if word1[-i:] == word2[-i:]: + count += 1 + return count + +def alien_rhymes(words): + # BruteForce Logic + n = len(words) + pairs = [] + count = 0 + records = {} # Max subset: pair + weight = {} + # Get all possible combination + for i in range(n): + for j in range(n): + if i != j and words[i]: #not in pairs and words[j] not in pairs: + subset = longestSubset(words[i], words[j]) + if subset != 0: + if subset not in records: + records[subset] = (words[i], words[j]) + else: + #while subset in records: + # subset = subset + if type(records[subset]) != list: + records[subset] = list([records[subset]]) + records[subset].append((words[i], words[j])) + + if (words[i], words[j]) not in weight: + weight[(words[i], words[j])] = [subset] + else: + weight[(words[i], words[j])].append(subset) + #pairs.append(words[i]) + #pairs.append(words[j]) + #count += longestSubset(words[i], words[j]) + #j = n-1 + subsets = sorted(records.keys(), reverse=True) + #print records + for sub in subsets: + records[sub] = sorted(records[sub], key=lambda x: len(weight[x])) + while records[sub]: + current = records[sub].pop() + if current[0] not in pairs and current[1] not in pairs: + count += sub + pairs.append(current[0]) + pairs.append(current[1]) + return count + +tcs = raw_input() +for i in range(int(tcs)): + lines = int(raw_input()) + words = [] + for line in range(lines): + words.append(raw_input()) + print "Case #"+str(i+1)+": "+str(alien_rhymes(words)) + + +""" +# Input set +4 +2 +TARPOL +PROL +3 +TARPOR +PROL +TARPRO +6 +CODEJAM +JAM +HAM +NALAM +HUM +NOLOM +4 +PI +HI +WI +FI + +Case #1: 2 +Case #2: 0 +Case #3: 6 +Case #4: 2 +""" \ No newline at end of file diff --git a/Jam/codeJamRound1C1.py b/Jam/codeJamRound1C1.py new file mode 100644 index 0000000..94bd5cd --- /dev/null +++ b/Jam/codeJamRound1C1.py @@ -0,0 +1,86 @@ +# Rock, Paper, Scissors Game +# * Make the Robot win against all the oponents +# - R Wins S losses P +# - P Wins R losses S +# - S Wins P losses R +# No Matter How the Numbers are assigned? Means you should win all the oponents individually!!!! + +# In order to win what you require +win = { + "S": "R", + "P": "S", + "R": "P" +} + +def match(o1, o2): + for i, j in zip(o1, o2): + if i == j: + continue + else: + if win[j] == i: + return o1 + else: + return o2 + +# Function to create the winning program +def win_match(program, winner): + # Find all the winning combinations... + if program in each_win: + return winner + + # the first win move + #each_win[program].append(win[program[0]]) + + # Other possibilities + if len(each_win.keys()) == 0: + each_win[program] = [] + n = len(program) + for i in range(n+1): + if i < n: + possible = program[:i] + win[program[i]] + each_win[program].append(possible) + else: + possible = program[:i] + win[program[0]] + each_win[program].append(possible) + + if winner == "": + return each_win[program] + else: + if type(winner) == list: + for winp in each_win: + for w in each_win[winp]: + #print w, program + if match(w, program) == w: + return w + else: + if len(winner) >= len(program) and match(winner, program) != winner: + return None + elif len(winner) < len(program): + return winner+win[program[len(winner)]] + else: + return winner + +# Test cases handle +tcs = raw_input() +for i in range(int(tcs)): + Oponents = int(raw_input()) + winning_combination = "" + fail = 0 + # Record win program of each oponent program + each_win = {} + for j in range(Oponents): + Program = raw_input() + if fail == 0: + winning_combination = win_match(Program, winning_combination) + if not winning_combination: + fail = 1 + #print winning_combination, each_win + if fail == 1: + print "Case #"+str(i+1)+": "+"IMPOSSIBLE" + else: + if type(winning_combination) == list: + winning_combination = winning_combination[0] + print "Case #"+str(i+1)+": "+winning_combination + + + diff --git a/ProblemSolving/.DS_Store b/ProblemSolving/.DS_Store deleted file mode 100644 index 2d67b5c..0000000 Binary files a/ProblemSolving/.DS_Store and /dev/null differ diff --git a/ProblemSolving/01Matrix/01.py b/ProblemSolving/01Matrix/01.py new file mode 100644 index 0000000..19b508e --- /dev/null +++ b/ProblemSolving/01Matrix/01.py @@ -0,0 +1,40 @@ +# Reference: https://leetcode.com/problems/01-matrix/discuss/142584/Python-simple-and-readable-solution-beats-100 +class Solution(object): + def updateMatrix(self, matrix): + """ + :type matrix: List[List[int]] + :rtype: List[List[int]] + """ + + # 2 x O(mn) logic + # 1. Iteration 1 from left to right updated with min distance + # 2. Iteration 2 from right to left updated with min distance + + m = len(matrix) + n = len(matrix[0]) + + # 1 + for i in range(m): + for j in range(n): + if matrix[i][j] != 0: + matrix[i][j] = float('inf') + if i > 0 and matrix[i-1][j] +1 < matrix[i][j]: + matrix[i][j] = matrix[i-1][j] + 1 + if j > 0 and matrix[i][j-1] +1 < matrix[i][j]: + matrix[i][j] = matrix[i][j-1] + 1 + + # 2 + for i in range(m-1, -1, -1): + for j in range(n-1, -1, -1): + if matrix[i][j] != 0: + if i < m-1 and matrix[i+1][j] +1 < matrix[i][j]: + matrix[i][j] = matrix[i+1][j] + 1 + if j < n-1 and matrix[i][j+1] +1 < matrix[i][j]: + matrix[i][j] = matrix[i][j+1] + 1 + + return matrix + + + + + diff --git a/ProblemSolving/132pattern/132.py b/ProblemSolving/132pattern/132.py index a9f4788..1a2c374 100644 --- a/ProblemSolving/132pattern/132.py +++ b/ProblemSolving/132pattern/132.py @@ -1,4 +1,3 @@ -# Pending... class Solution(object): def find132pattern(self, nums): """ @@ -20,13 +19,53 @@ def find132pattern(self, nums): j += 1 i += 1 return False + +class Solution: + def find132pattern(self, nums: List[int]) -> bool: + + + # Logic 1: problem statement but contigously (Q wants without being cont and just i= 3: + #print(current) + return True + + for i in range(len(nums)): + + if i+1 >= len(nums): + nxt = [] + else: + nxt = nums[i+1:] - - - - - - + if len(current) == 0: + if nums[i] not in self.start_points: + if backtrack(current + [nums[i]], nxt): + return True + self.start_points.add(nums[i]) + elif len(current) == 1 and current[-1] < nums[i]: + if current[0] + nums[i] not in self.second_points: + if backtrack(current + [nums[i]], nxt): + return True + self.second_points.add(current[0] + nums[i]) + elif len(current) == 2 and current[0] < nums[i] < current[1]: + return True - - + return False + + self.start_points = set() + self.second_points = set() + return backtrack([], nums) diff --git a/ProblemSolving/2KeysKeyboard/2key.py b/ProblemSolving/2KeysKeyboard/2key.py new file mode 100644 index 0000000..948fcfd --- /dev/null +++ b/ProblemSolving/2KeysKeyboard/2key.py @@ -0,0 +1,65 @@ +class Solution(object): + def minSteps(self, n): + """ + :type n: int + :rtype: int + """ + + # Logic: + # * Again, the confusion was at the copy decision to make + # - Already knew solution is something to work around the divisibility + # - example: for 20, we know 2, 4, 5 are divisible by 20 but going with 4 gives the minimum steps + # - Recursively going back from square root or half the number n and iterating for divisibility + being recursive helps... + # * Inreference to the golang solution at https://leetcode.com/problems/2-keys-keyboard/discuss/193726/Simple-Golang-solution-beats-100 + + if n < 2: + return 0 + elif n >= 2 and n <= 5: + return n + else: + for i in range(n//2, 1, -1): + if n%i == 0: + return (n//i) + self.minSteps(i) + return n + + """ + # or + import math + if n == 1: + return 0 + else: + for i in range(int(math.sqrt(n)), 1, -1): + if n%i == 0: + return self.minSteps(i) + self.minSteps(n//i) + return n + """ + + """ + # Literally following the problem and working around that doesnt help + # * The challenge remains on deciding when to perform the copy again + # * The is more of a mathematical solution, to understand the properties of the proble, + # + notepad = "A" + copied = "" + steps = 0 + #total = n-1 + # remember it is exactly `n` number you have to reach... + + while len(notepad) < n: + print notepad, copied, steps + # Copy All Operation + if not copied: + copied = notepad + # Copy operation decision + elif n%len(notepad) == 0: + copied = notepad + # Paste the data + else: + notepad += copied + steps += 1 + + return steps + """ + + + diff --git a/ProblemSolving/CompletenessOfBinaryTree/complete.py b/ProblemSolving/CompletenessOfBinaryTree/complete.py new file mode 100644 index 0000000..3da6f0c --- /dev/null +++ b/ProblemSolving/CompletenessOfBinaryTree/complete.py @@ -0,0 +1,60 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def isCompleteTree(self, root): + """ + :type root: TreeNode + :rtype: bool + """ + + + # Logic: + # * Recursively calculate depth of each leaf node and add them into a list + # * Traverse the list to ensure all the it has precedence left-most + + # List of depth of leaf nodes + self.depth_of_leaf = [] + + # Depth recursive function + def depths(node, depth): + + # Record depth at leaf + if not node: + self.depth_of_leaf.append(depth) + else: + # Traverse for left and right depth + depths(node.left, depth+1) + depths(node.right, depth+1) + + # Trigger + depths(root, 0) + + # Traverse for left most precedence + # * Ensure there is not change on the right once it reduces + # * Ensure there is not change more than once + + left_most = self.depth_of_leaf[0] + print self.depth_of_leaf + low = 0 + + for i in range(len(self.depth_of_leaf)): + if self.depth_of_leaf[i] > left_most: + return False + elif self.depth_of_leaf[i] < left_most: + left_most = self.depth_of_leaf[i] + low += 1 + if low > 1: + return False + else: + return True + + + + + + diff --git a/ProblemSolving/DesignParkingSystem/design.py b/ProblemSolving/DesignParkingSystem/design.py new file mode 100644 index 0000000..9654c01 --- /dev/null +++ b/ProblemSolving/DesignParkingSystem/design.py @@ -0,0 +1,14 @@ +class ParkingSystem: + + def __init__(self, big: int, medium: int, small: int): + self.lots = { + 1: big, + 2: medium, + 3: small, + } + + def addCar(self, carType: int) -> bool: + if self.lots[carType] > 0: + self.lots[carType] -= 1 + return True + return False diff --git a/ProblemSolving/IndexPairsOfAString/index.py b/ProblemSolving/IndexPairsOfAString/index.py new file mode 100644 index 0000000..d9b89cd --- /dev/null +++ b/ProblemSolving/IndexPairsOfAString/index.py @@ -0,0 +1,16 @@ +class Solution(object): + def indexPairs(self, text, words): + """ + :type text: str + :type words: List[str] + :rtype: List[List[int]] + """ + + # Logic 1: O(N) iteration on all the words and corresponding iteration on text everytime - 100 pass 95% faster + result = [] + for word in words: + n = len(word) + for i in range(len(text)): + if text[i:i+n] == word: + result.append([i, i+n-1]) + return sorted(result) diff --git a/ProblemSolving/LRUCache/lru.py b/ProblemSolving/LRUCache/lru.py new file mode 100644 index 0000000..dbf0f99 --- /dev/null +++ b/ProblemSolving/LRUCache/lru.py @@ -0,0 +1,71 @@ +# Logic 2: OrderedDict to the rescue +from collections import OrderedDict +class LRUCache(object): + + def __init__(self, capacity): + """ + :type capacity: int + """ + self.capacity = capacity + self.cache = OrderedDict() + + def get(self, key): + """ + :type key: int + :rtype: int + """ + if key not in self.cache: + return -1 + self.cache.move_to_end(key) + return self.cache[key] + + + def put(self, key, value): + """ + :type key: int + :type value: int + :rtype: None + """ + if key in self.cache: + self.cache.move_to_end(key) + self.cache[key] = value + if len(self.cache) > self.capacity: + self.cache.popitem(last = False) + +# Your LRUCache object will be instantiated and called as such: +# obj = LRUCache(capacity) +# param_1 = obj.get(key) +# obj.put(key,value) +# Logic 1: Naive method +# * learning: The important part of this problem is that we maintain a list of accessed items vs inaccessed items, that way we keep track of things. We also should make sure this happens in perfect time complexity +# * In the below logic, Having a list with all accessed items put to the end of the list and the inaccessed ones on the front does not work so perfectly with time complexity and answers +# * maintaining the relation between the list vs dict becomes crucial too... +""" +class LRUCache(object): + + def __init__(self, capacity): + self.cache = {} + self.capacity = capacity + self.last_used = [] + + def get(self, key): + if key not in self.cache: + return -1 + # Rotate array + self.last_used.append(key) + return self.cache[key] + + + def put(self, key, value): + if key not in self.cache: + if len(self.cache.keys()) == self.capacity: + del self.cache[self.last_used.pop(0)] + #self.last_used.append(key) + self.cache[key] = value + print(self.cache) + +# Your LRUCache object will be instantiated and called as such: +# obj = LRUCache(capacity) +# param_1 = obj.get(key) +# obj.put(key,value) +""" diff --git a/ProblemSolving/LRUCache/lru_full.py b/ProblemSolving/LRUCache/lru_full.py new file mode 100644 index 0000000..2388286 --- /dev/null +++ b/ProblemSolving/LRUCache/lru_full.py @@ -0,0 +1,137 @@ +# Essence: +# * We obviously use a dictionary to perform the operations within O(1) +# * To track the least used element we need some sort of arrangement or array to move items accessed to the last +# - So the first item all the time is the least accessed + + +# Logic1: OrderedDictionary to move stuff around while maintaining a dictionary - 86% faster +""" +from collections import OrderedDict +class LRUCache(object): + + def __init__(self, capacity): + self.capacity = capacity + self.dict = OrderedDict() + + + def get(self, key): + if key not in self.dict: # Key not found in dict + return -1 + self.dict.move_to_end(key) # Move the accessed one to the end + return self.dict[key] # Return value + + + def put(self, key, value): + if key in self.dict: # Key in Dictionary then move accessed part + self.dict.move_to_end(key) + self.dict[key] = value # Add key, value to dict + if len(self.dict) > self.capacity: # Greater than capacity + self.dict.popitem(last = False) # Pop the least accessed item + + +# Your LRUCache object will be instantiated and called as such: +# obj = LRUCache(capacity) +# param_1 = obj.get(key) +# obj.put(key,value) +""" + +# Logic 2: Using a Dictionary and Double Linked List to achieve the same in naive manner - 49% faster + +# Define Double Linked List +# * For ease of access and reference lets maintain dummy nodes for head and tail +class DoubleLinkedList(object): + def __init__(self): + self.next = None + self.prev = None + self.key = None + self.value = None + +class LRUCache(object): + + def __init__(self, capacity): + """ + :type capacity: int + """ + + # Capacity and Size + self.capacity = capacity + self.size = 0 + + # Dictionary + self.dict = {} + + # Double Linked List + self.head = DoubleLinkedList() + self.tail = DoubleLinkedList() + + self.head.next = self.tail + self.tail.prev = self.head + + def add_node(self, node): + + # update current node + node.prev = self.head + node.next = self.head.next + + # update head and next + self.head.next.prev = node + self.head.next = node + + def remove_node(self, node): + prev = node.prev + new = node.next + prev.next = new + new.prev = prev + + def move_node_to_end(self, node): + self.remove_node(node) + self.add_node(node) + + def get(self, key): + """ + :type key: int + :rtype: int + """ + + node = self.dict.get(key, None) + if not node: + return -1 + self.move_node_to_end(node) + return node.value + + def pop_tail(self): + tail = self.tail.prev + self.remove_node(tail) + return tail + + def put(self, key, value): + """ + :type key: int + :type value: int + :rtype: None + """ + + # Get node from the dictionary + node = self.dict.get(key) + + if not node: + node = DoubleLinkedList() # create node + node.key = key + node.value = value + self.dict[key] = node + self.add_node(node) + self.size += 1 + if self.size > self.capacity: + tail = self.pop_tail() + del self.dict[tail.key] + self.size -= 1 + else: + node.value = value + self.move_node_to_end(node) # Update least accessed + + + +# Your LRUCache object will be instantiated and called as such: +# obj = LRUCache(capacity) +# param_1 = obj.get(key) +# obj.put(key,value) diff --git a/ProblemSolving/NestedListWeightedSum/nest.py b/ProblemSolving/NestedListWeightedSum/nest.py new file mode 100644 index 0000000..c333b04 --- /dev/null +++ b/ProblemSolving/NestedListWeightedSum/nest.py @@ -0,0 +1,104 @@ +# """ +# This is the interface that allows for creating nested lists. +# You should not implement it, or speculate about its implementation +# """ +#class NestedInteger(object): +# def __init__(self, value=None): +# """ +# If value is not specified, initializes an empty list. +# Otherwise initializes a single integer equal to value. +# """ +# +# def isInteger(self): +# """ +# @return True if this NestedInteger holds a single integer, rather than a nested list. +# :rtype bool +# """ +# +# def add(self, elem): +# """ +# Set this NestedInteger to hold a nested list and adds a nested integer elem to it. +# :rtype void +# """ +# +# def setInteger(self, value): +# """ +# Set this NestedInteger to hold a single integer equal to value. +# :rtype void +# """ +# +# def getInteger(self): +# """ +# @return the single integer that this NestedInteger holds, if it holds a single integer +# Return None if this NestedInteger holds a nested list +# :rtype int +# """ +# +# def getList(self): +# """ +# @return the nested list that this NestedInteger holds, if it holds a nested list +# Return None if this NestedInteger holds a single integer +# :rtype List[NestedInteger] +# """ + +class Solution(object): + def depthSum(self, nestedList): + """ + :type nestedList: List[NestedInteger] + :rtype: int + """ + + # Logic 1: Iterative and expand the lists by each level until exhaustion + """ + total = 0 + level = 1 + while nestedList: + i = 0 + while i < len(nestedList): + if not nestedList[i].isInteger(): + temp = nestedList[i].getList() + nestedList = nestedList[:i] + temp + nestedList[i+1:] + i += len(temp) + else: + total += level*(nestedList[i].getInteger()) + nestedList.pop(i) + #print(nestedList) + level += 1 + #print(total) + return total + """ + + # Logic 2: Recursive Logic - 86 % faster + def recurse_nested_list(array, level): + while array: + current = array.pop(0) + if current.isInteger(): + self.sum += current.getInteger()*level + else: + recurse_nested_list(current.getList(), level+1) + #print(self.sum, level) + self.sum = 0 + recurse_nested_list(nestedList, 1) + return self.sum + + + """ + # Other logics that dont work... + + # same logic - The comment was misleading claiming not to speculate the interface code. So the below logic assumes naive list of list with integers. + + total = 0 + while nestedList: + i = 0 + while i < len(nestedList): + if isinstance(nestedList[i], (list)): + nestedList = nestedList[:i] + nestedList[i] + nestedList[i+1:] + i += len(nestedList[i]) + else: + total += level*nestedList[i] + nestedList.pop(i) + level += 1 + return total + """ + + diff --git a/ProblemSolving/PartitionList/partition.py b/ProblemSolving/PartitionList/partition.py new file mode 100644 index 0000000..16e824f --- /dev/null +++ b/ProblemSolving/PartitionList/partition.py @@ -0,0 +1,71 @@ +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next +class Solution: + def partition(self, head: Optional[ListNode], x: int) -> Optional[ListNode]: + + # Logic 1: Store values as less and more, perform 2*(O(N)) list iteration + + """ + less = [] # 1,2,2 1->2->2 + more = [] # 4,3,5 4->3->5 + + second = head + result = head + + while head: + if head.val < x: + less.append(head.val) + else: + more.append(head.val) + head = head.next + + print(less, more) + + while second: + if less: + second.val = less.pop(0) + elif more: + second.val = more.pop(0) + second = second.next + + return result + """ + + # Logic 2: Create sublists for less and more with O(N) iteration and merge + + less = None + more = None + lhead = None + mhead = None + + while head: + if head.val < x: + if not less: + lhead = head + less = head + else: + less.next = head + less = less.next + else: + if not more: + more = head + mhead = head + else: + more.next = head + more = more.next + + head = head.next + + #print(lhead.val, mhead.val, more.val, less.val) + if less: + less.next = mhead + if more: + more.next = None + if not lhead: + lhead = mhead + + return lhead + diff --git a/ProblemSolving/PartitionList/partition2.py b/ProblemSolving/PartitionList/partition2.py new file mode 100644 index 0000000..3bd01c3 --- /dev/null +++ b/ProblemSolving/PartitionList/partition2.py @@ -0,0 +1,30 @@ +# ref: simple 2 pointer approach at https://leetcode.com/problems/partition-list/editorial/ +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next +class Solution: + def partition(self, head: Optional[ListNode], x: int) -> Optional[ListNode]: + + before = ListNode(0) + after = ListNode(0) + rec_after = after + rec_before = before + + while head: + + if head.val < x: + before.next = head + before = before.next + else: + after.next = head + after = after.next + + head = head.next + + + after.next = None + before.next = rec_after.next + return rec_before.next + diff --git a/ProblemSolving/addOneRowToBst/add.py b/ProblemSolving/addOneRowToBst/add.py new file mode 100644 index 0000000..79de425 --- /dev/null +++ b/ProblemSolving/addOneRowToBst/add.py @@ -0,0 +1,53 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def addOneRow(self, root, v, d): + """ + :type root: TreeNode + :type v: int + :type d: int + :rtype: TreeNode + """ + + # Logic: 40ms 97% --> get to the correct depth insert based on the parent and current node (create a new node and then insert) + def getToDepthAndInsert(node, current_depth, parent): + + # If the current depth is reached, then create new node + if current_depth == d: + new_node = TreeNode(v) + # * If the corresponding depth is greater than the leaf, then add as leaf + # * Else, insert in between + if not node: + if not parent.left: + parent.left = new_node + elif not parent.right: + parent.right = new_node + else: + if parent.left == node: + parent.left = new_node + new_node.left = node + else: + parent.right = new_node + new_node.right = node + else: + # If depth is not reached, recurse + if node: + getToDepthAndInsert(node.left, current_depth+1, node) + getToDepthAndInsert(node.right, current_depth+1, node) + + # Depth being the root itself + if d == 1: + new_node = TreeNode(v) + new_node.left = root + root = new_node + else: + getToDepthAndInsert(root, 1, None) + + return root + + diff --git a/ProblemSolving/addOneRowToTree/tree.py b/ProblemSolving/addOneRowToTree/tree.py new file mode 100644 index 0000000..18b1ee8 --- /dev/null +++ b/ProblemSolving/addOneRowToTree/tree.py @@ -0,0 +1,42 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right +class Solution: + def addOneRow(self, root: Optional[TreeNode], val: int, depth: int) -> Optional[TreeNode]: + + def insertLevel(node, curLvl): + + if curLvl+1 != depth: + if node.left: + insertLevel(node.left, curLvl+1) + if node.right: + insertLevel(node.right, curLvl+1) + return + + print(curLvl, node.val) + + if node.left: + tmp = node.left + node.left = TreeNode(val) + node.left.left = tmp + else: + node.left = TreeNode(val) + + if node.right: + tmp = node.right + node.right = TreeNode(val) + node.right.right = tmp + else: + node.right = TreeNode(val) + + curLvl = 1 + if curLvl == depth: + new_root = TreeNode(val) + new_root.left = root + return new_root + + insertLevel(root, curLvl) + return root diff --git a/ProblemSolving/addToArrayForm/add.py b/ProblemSolving/addToArrayForm/add.py new file mode 100644 index 0000000..f2fc99d --- /dev/null +++ b/ProblemSolving/addToArrayForm/add.py @@ -0,0 +1,43 @@ +class Solution(object): + def addToArrayForm(self, A, K): + """ + :type A: List[int] + :type K: int + :rtype: List[int] + """ + + # Cracky one line solution - Run @58% and Store @100 faster + return [int(j) for j in str(eval("".join([str(i) for i in A])+"+"+str(K)))] + + """ + # Pending... + # Literal Addition - Iterate O(K) + # * Always positive number + # * Only ADD operation + # * Avoid list of string to integer type conversions... + + # Make K iterable + K = str(K)[::-1] + carry = 0 + n = len(A)-1 + for i in range(len(K)): + if i <= n: + A[n-i] = A[n-i] + int(K[i]) + carry + if A[n-i] > 9: + carry = A[n-i]//10 + A[n-i] = A[n-i]%10 + else: + carry = 0 + else: + A = [int(K[i])] + A + + while n-i >= 0 and carry >= 0: + i += 1 + if n-i == 0: + A = [carry] + A + else: + carry = A[n-i]//10 + A[n-i] = A[n-i]%10 + return A + """ + diff --git a/ProblemSolving/addTwoNumbersLinkedList/add2.py b/ProblemSolving/addTwoNumbersLinkedList/add2.py new file mode 100644 index 0000000..3a65f8e --- /dev/null +++ b/ProblemSolving/addTwoNumbersLinkedList/add2.py @@ -0,0 +1,44 @@ +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next +class Solution: + def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]: + + result = ListNode() + rtnResult = result + carry = 0 + + while l1 and l2: + theSum = l1.val + l2.val + carry + carry = theSum//10 + result.val = theSum%10 + l1 = l1.next + l2 = l2.next + if l1 or l2: + result.next = ListNode() + result = result.next + + while l1: + theSum = l1.val + carry + carry = theSum//10 + result.val = theSum%10 + l1 = l1.next + if l1: + result.next = ListNode() + result = result.next + + while l2: + theSum = l2.val + carry + carry = theSum//10 + result.val = theSum%10 + l2 = l2.next + if l2: + result.next = ListNode() + result = result.next + + if carry: + result.next = ListNode(carry) + + return rtnResult diff --git a/ProblemSolving/allPathsFromSourceToTargetGraph/all.py b/ProblemSolving/allPathsFromSourceToTargetGraph/all.py new file mode 100644 index 0000000..14237a4 --- /dev/null +++ b/ProblemSolving/allPathsFromSourceToTargetGraph/all.py @@ -0,0 +1,61 @@ +class Solution(object): + def allPathsSourceTarget(self, graph): + """ + :type graph: List[List[int]] + :rtype: List[List[int]] + """ + # Given + # * Index is the node + # * graph[Index] is the next nodes of the index node + + # There are 2 method for a graph (like in a tree), + # * DFS - Depth ==> recursive strategy + # * BFS - Breath ==> Iterative strategy + + # Common setting + # Num of nodes (as each i is a node) + n = len(graph) + + # Method 1 - 100 pass 100% faster + + # DFS - Recusive method, a method defined for recursing + + def traverse_graph(path): + + # As we progress with path, the last node in path is the latest node: path[-1] + + # When n-1 or last node is reached, add the path to result + if path[-1] == n-1: + result.append(path) + + # For each next node, add next_node to path and recurse. + for next_node in graph[path[-1]]: + traverse_graph(path+[next_node]) + + # Method 2 - 100 pass, 50% faster + # BFS - Iterative method, a method with a reference list (stack) defined for iteration + + def traverse_graph2(): + + # Reference stack with known first node + stack = [[0]] + + # When stack is empty all nodes are traversed + while stack: + # Current path from stack, current node should be the lastest in the last of path + current_path = stack.pop(0) + current_node = current_path[-1] # Latest Node in the path + + # Once, final node is reached append path + if current_node == n-1: + result.append(current_path) + + # Add next nodes in path and into the stack + if graph[current_node]: + for next_node in graph[current_node]: + stack.append(current_path+[next_node]) + + result = [] + traverse_graph([0]) + #traverse_graph2() + return result diff --git a/ProblemSolving/anagram/anagram2.py b/ProblemSolving/anagram/anagram2.py new file mode 100644 index 0000000..d464f88 --- /dev/null +++ b/ProblemSolving/anagram/anagram2.py @@ -0,0 +1,10 @@ +class Solution(object): + def isAnagram(self, s, t): + """ + :type s: str + :type t: str + :rtype: bool + """ + + import collections + return collections.Counter(s) == collections.Counter(t) diff --git a/ProblemSolving/areaOfTriangleWithCoOrdinates/area.py b/ProblemSolving/areaOfTriangleWithCoOrdinates/area.py new file mode 100644 index 0000000..4eaa393 --- /dev/null +++ b/ProblemSolving/areaOfTriangleWithCoOrdinates/area.py @@ -0,0 +1,10 @@ +# Area of a triangle with co-ordinates +# * Using formula from https://mathinstructor.net/2012/08/how-to-find-area-of-triangle-given-three-vertices/ + +def area(c1, c2, c3): + return abs((c1[0] * (c2[1] - c3[1]) + c2[0] * (c3[1] - c1[1]) + c3[0] * (c1[1] - c2[1]))//2) + +print(area((-3,4), (-2,-2), (3,2))) + + + diff --git a/ProblemSolving/arithmeticSlices/arithmetic.py b/ProblemSolving/arithmeticSlices/arithmetic.py new file mode 100644 index 0000000..471280d --- /dev/null +++ b/ProblemSolving/arithmeticSlices/arithmetic.py @@ -0,0 +1,81 @@ +class Solution(object): + def numberOfArithmeticSlices(self, A): + """ + :type A: List[int] + :rtype: int + """ + + # Logic 3: Nice interpolation --> every nth digit after 3 digits adds n more possib + # * https://leetcode.com/problems/arithmetic-slices/discuss/242396/Python-short-solution-with-explanation + + total_sequences = 0 + current_sequences = 0 + + if len(A) < 3: + return 0 + + for i in range(2, len(A)): + if A[i] - A[i-1] == A[i-1] - A[i-2]: + current_sequences += 1 + total_sequences += current_sequences + else: + current_sequences = 0 + + return total_sequences + + # Logic 2: 2 pointer method + # * https://leetcode.com/problems/arithmetic-slices/discuss/257940/Two-pointers-O(N)-O(1)-Solution-(No-Math-No-DP) + """ + n = len(A) + + if n < 3: + return 0 + + left = 0 + delta = A[1]-A[0] + count = 0 + + for right in range(2, len(A)): + diff = A[right]-A[right-1] + if diff == delta: + length = right-left+1 + if length >= 3: + count += length-2 + else: + delta = diff + left = right - 1 + + return count + """ + + # Logic 1: BruteForce Login: Time Limit Exceeded + + """ + def isArithmetic(array, delta): + n = len(array) + for i in range(1, n): + diff = array[i] - array[i-1] + if diff != delta: + return False + return True + + count = 0 + + if len(A) < 3: + return count + + delta = A[1]-A[0] + + # Itertools dont work as we want consecutive + # import itertools + #for i in range(3, len(A)+1): + # for comb in itertools.combinations(A, r=i): + + for i in range(len(A)): + for j in range(i+1, len(A)+1): + if len(A[i:j]) >= 3: + if isArithmetic(A[i:j], delta): + #print A[i:j] + count += 1 + return count + """ diff --git a/ProblemSolving/armstrongNumber/arms.py b/ProblemSolving/armstrongNumber/arms.py new file mode 100644 index 0000000..fba9dc3 --- /dev/null +++ b/ProblemSolving/armstrongNumber/arms.py @@ -0,0 +1,39 @@ +# Logic 1: [String way] Convert to string and eval/math - 97% faster +# Initial type conversions +num = str(N) +n = len(num) +result = 0 + +# Armstrong calculation +for i in num: + result += int(i)**n + +# Decide result +if result == N: + return True +else: + return False +# Logic 2: [Only Int way] Find the size of the number or num of digit and perform calc - 88% faster +# * use modulo or div + +# Find the size of the number + +n = 0 +num = N +while num: + n += 1 + num = num//10 + +# Armstrong calc - remove last digit and reduce number to the one without the last digit +armstrong = 0 +num = N +while num: + next_digit = num%10 + armstrong += next_digit**n + num = num//10 + print(next_digit, armstrong, num, n) + +if armstrong == N: + return True +else: + return False diff --git a/ProblemSolving/arrangingCoins/technique.py b/ProblemSolving/arrangingCoins/technique.py new file mode 100644 index 0000000..1e77d37 --- /dev/null +++ b/ProblemSolving/arrangingCoins/technique.py @@ -0,0 +1,15 @@ +class Solution: + def arrangeCoins(self, n: int) -> int: + + # Logic 1: Construct formula and solve the equation until <= satisfied + # * the stairs are added with respect to kth step 1, 2, 3 which is basically sum of all steps == n + # * sum of n natural nums --> k(k+1)//2 = n --> k**2 + k = 2n + + N = 2*n + result = 0 + for i in range(1, n+1): + sumOfK = i**2 + i + if sumOfK > N: + return result + result = i + return result diff --git a/ProblemSolving/arrayPartitionI/arr2.py b/ProblemSolving/arrayPartitionI/arr2.py new file mode 100644 index 0000000..71ca4c4 --- /dev/null +++ b/ProblemSolving/arrayPartitionI/arr2.py @@ -0,0 +1,14 @@ + +class Solution(object): + def arrayPairSum(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + + nums.sort() + sumi = 0 + for i in range(0, len(nums), 2): + sumi += nums[i] + return sumi + diff --git a/ProblemSolving/arrayTransformation/array.py b/ProblemSolving/arrayTransformation/array.py new file mode 100644 index 0000000..cf1ccfd --- /dev/null +++ b/ProblemSolving/arrayTransformation/array.py @@ -0,0 +1,21 @@ +class Solution(object): + def transformArray(self, arr): + """ + :type arr: List[int] + :rtype: List[int] + """ + + # Logic: Lets go naive logic of literally solving - 5.80% faster + previous = [0]*len(arr) + new = [1]*len(arr) + while new != previous: + previous = new[:] + new = arr[:] + for i in range(1,len(arr)-1): + if arr[i] > arr[i-1] and arr[i] > arr[i+1]: + new[i] -= 1 + elif arr[i] < arr[i-1] and arr[i] < arr[i+1]: + new[i] += 1 + arr = new + #print(previous, new) + return previous diff --git a/ProblemSolving/assignCookie/assign.py b/ProblemSolving/assignCookie/assign.py new file mode 100644 index 0000000..6bb27b1 --- /dev/null +++ b/ProblemSolving/assignCookie/assign.py @@ -0,0 +1,62 @@ +class Solution(object): + def findContentChildren(self, g, s): + """ + :type g: List[int] + :type s: List[int] + :rtype: int + """ + + # 100 pass - 76ms 42.78% faster + # Using extra variable to count, simpler logic + # To maximize satisfaction, lets particularly sort the arrays + + # Sort the arrays so they are both in increasing order + g.sort() + s.sort() + + # Initial point to start + child, cookie = 0, 0 + + # result + content = 0 + + # Iterate through both the arrays + while child < len(g) and cookie < len(s): + # Found a content child + if s[cookie] >= g[child]: + content += 1 + child += 1 + cookie += 1 + else: + # Iterate cookie until a content cookie is found for respective child + cookie += 1 + + return content + + + """ + # 100 pass - 176 ms 11.55% faster + # Logic of deleting entries from list (Kinda like stacks), trying without using extra variable or result list + # Use children + cookie list as a stack + # * Pop child from chidren when their greed cannot be satisfied + # * Pop cookie from cookies when they are given to children + + g.sort() + s.sort() + + i, j = 0, 0 + while i < len(g): + while j < len(s) and s[j] < g[i]: + j += 1 + if j == len(s): + g.pop(i) + else: + s.pop(j) + i += 1 + return len(g) + """ + + + + + diff --git a/ProblemSolving/asteroidCollision/asteroid.py b/ProblemSolving/asteroidCollision/asteroid.py new file mode 100644 index 0000000..d605533 --- /dev/null +++ b/ProblemSolving/asteroidCollision/asteroid.py @@ -0,0 +1,63 @@ +class Solution(object): + def asteroidCollision(self, asteroids): + """ + :type asteroids: List[int] + :rtype: List[int] + """ + + # Logic 1: Naive O(2N) Iteration over the asteroids --> fails for some testcases. Some TCs remain confusing when the adjacent asteroids can be cancelled and are not for example [-2,-2,-2,1] == [-2,-2] as per code below but real answer is [-2,-2,-2,1] + """ + def collide(asteroids): + i = 0 + while i < len(asteroids): + a1 = asteroids[i] + if i+1 < len(asteroids): + a2 = asteroids[i+1] + else: + break + if a1 > 0 and a2 > 0: + i += 2 + continue + elif a1 < 0 and a2 < 0: + i += 2 + continue + else: + if abs(a1) == abs(a2): + asteroids.pop(i) + asteroids.pop(i) + else: + if abs(a1) > abs(a2): + target = a1 + else: + target = a2 + asteroids.pop(i) + if target > 0: + asteroids[i] = target + else: + asteroids.pop(i) + return asteroids + + a = collide(asteroids) + print(a) + b = collide(a[::-1]) + return b[::-1] + """ + + # Logic 2: Using Stack as mentioned in a number of accepted solutions - 100 pass 68% faster + stack = [] + for i in range(len(asteroids)): + if asteroids[i] > 0: + stack.append(asteroids[i]) + else: + while stack and stack[-1] > 0 and stack[-1] < abs(asteroids[i]): + stack.pop() + if not stack or stack[-1] < 0: + stack.append(asteroids[i]) + elif stack[-1] == -asteroids[i]: + stack.pop() + return stack + + + + + diff --git a/ProblemSolving/availableCapturesForRook/rook_attack.py b/ProblemSolving/availableCapturesForRook/rook_attack.py new file mode 100644 index 0000000..9c330c4 --- /dev/null +++ b/ProblemSolving/availableCapturesForRook/rook_attack.py @@ -0,0 +1,115 @@ +class Solution(object): + def numRookCaptures(self, board): + """ + :type board: List[List[str]] + :rtype: int + """ + + # 100 pass 99% faster + # Revisit 1 -> O(N2) iteration to find rook and pawns, another iteration to attack condition + # Logic: Find vertical, horizontal positions of pawns with respect to the rook and check if the path is empty!\ + + # Variables to record positions of pawns & rook + pawns = [] # pawns position -> [x, y] // # dict logic => row -> [col1, col2, col3....] + rook = [0, 0] # rook position -> [x, y] + others = [] # other pieces + count = 0 + empty = [] + # 8x8 board of Chess - Iterate for positions + for row in range(8): + for column in range(8): + if board[row][column] == "R": # white color rook + rook[0] = row + rook[1] = column + elif board[row][column] == "p": # Black pawn, then potential attack possible + #if row not in pawns: + # pawns[row] = [] + #pawns[row].append(column) + pawns.append([row, column]) + elif board[row][column] != ".": # to check if something else is in between + others.append([row, column]) + elif board[row][column] == ".": # Empty block + empty.append([row, column]) + # Find things in between to satisfy the attack condition + print rook, pawns, others + for position in pawns: + # Row check - Horizontal movement attack + if position[0] == rook[0]: + print "here", position[0], rook[0] + block = 0 + if position[1] > rook[1]: + for i in range(rook[1]+1, position[1]): + if [position[0], i] in pawns or [position[0], i] in others: + block += 1 + if block > 0: + break + if block == 0: + count += 1 + else: + block = 0 + for i in range(position[1]+1, rook[1]): + if [position[0], i] in pawns or [position[0], i] in others: + block += 1 + if block > 0: + break + if block == 0: + count += 1 + elif position[1] == rook[1]: + print "there", position[0], rook[0] + # Column check - Vertical movement attack + if position[0] < rook[0]: + block = 0 + for i in range(position[0]+1, rook[0]): + if [i, position[1]] in pawns or [i, position[1]] in others: + block += 1 + if block > 0: + break + if block == 0: + count += 1 + else: + block = 0 + for i in range(rook[0]+1, position[0]): + if [i, position[1]] in pawns or [i, position[1]] in others: + block += 1 + if block > 0: + break + if block == 0: + count += 1 + print count + return count + + # Logic2: Just traverse horizontal and vertical path of Rook until the first hit + + """ + # Old Logic: Pending... + pawns = 0 + rook_position = -1 + first_pawn_down = 0 + first_pawn_up = 0 + + for i in range(len(board)): + # Rook Condition + board[i] = "".join(board[i]) + if "R" in board[i]: + rook_position = board[i].index("R") + print board[i] + if rook_position+1 < len(board[i]) and board[i][rook_position+1] == "p": + pawns += 1 + if rook_position-1 > len(board[i]) and board[i][rook_position-1] == "p": + pawns += 1 + j = i + while j > 0: + if board[i][rook_position] == "p" and first_pawn_up == 0: + pawns += 1 + first_pawn_up += 1 + break + j -= 1 + if rook_position > -1: + if board[i][rook_position] == "p" and first_pawn_down == 0: + pawns += 1 + first_pawn_down += 1 + + return pawns + """ + + diff --git a/ProblemSolving/averageValueOfEvenNumbersDivisibltByThree/avg.py b/ProblemSolving/averageValueOfEvenNumbersDivisibltByThree/avg.py new file mode 100644 index 0000000..dcb6fbe --- /dev/null +++ b/ProblemSolving/averageValueOfEvenNumbersDivisibltByThree/avg.py @@ -0,0 +1,15 @@ +class Solution: + def averageValue(self, nums: List[int]) -> int: + + total = 0 + count = 0 + + for i in range(len(nums)): + if nums[i]%2 == 0 and nums[i]%3 == 0: + count += 1 + total += nums[i] + + if total == 0 or count == 0: + return 0 + + return total//count diff --git a/ProblemSolving/backspaceStringCompare/back2.py b/ProblemSolving/backspaceStringCompare/back2.py new file mode 100644 index 0000000..cc6aad8 --- /dev/null +++ b/ProblemSolving/backspaceStringCompare/back2.py @@ -0,0 +1,64 @@ +class Solution: + def backspaceCompare(self, s: str, t: str) -> bool: + + # Logic 1: String manipulation --> 59ms faster than 13.8% + """ + def popChar(s): + if len(s) > 1: + s = s[1:] + else: + s = "" + return s + + def finalTypedStr(typedStr): + + finalStr = "" + + while typedStr: + + print(typedStr, finalStr) + if typedStr[0] == "#": + if finalStr: + finalStr = finalStr[:-1] + typedStr = popChar(typedStr) + continue + + finalStr += typedStr[0] + + typedStr = popChar(typedStr) + + return finalStr + + print(finalTypedStr(s), finalTypedStr(t)) + return finalTypedStr(s) == finalTypedStr(t) + """ + + # Logic 2: Stack with single iteration containing 2 pointers -> 46ms faster than 40.5 + + def typeChrInEditor(char, editorStack): + if char == "#": + if editorStack: + editorStack.pop() + else: + editorStack.append(char) + + s1 = s2 = 0 + stack1 = [] + stack2 = [] + + while s1 < len(s) or s2 < len(t): + + if s1 < len(s): + typeChrInEditor(s[s1], stack1) + s1 += 1 + + if s2 < len(t): + typeChrInEditor(t[s2], stack2) + s2 += 1 + + #print(stack1, stack2) + if stack1 == stack2: + return True + + return False + diff --git a/ProblemSolving/backspaceStringCompare/back3.py b/ProblemSolving/backspaceStringCompare/back3.py new file mode 100644 index 0000000..1cf41ca --- /dev/null +++ b/ProblemSolving/backspaceStringCompare/back3.py @@ -0,0 +1,19 @@ +class Solution(object): + def backspaceCompare(self, s, t): + """ + :type s: str + :type t: str + :rtype: bool + """ + + def removeBackspace(txt): + stack = [] + for i in txt: + if i == "#": + if stack: + stack.pop() + else: + stack.append(i) + return "".join(stack) + + return removeBackspace(s) == removeBackspace(t) diff --git a/ProblemSolving/bagOfTokens/bag.py b/ProblemSolving/bagOfTokens/bag.py new file mode 100644 index 0000000..8ffd0c1 --- /dev/null +++ b/ProblemSolving/bagOfTokens/bag.py @@ -0,0 +1,25 @@ +class Solution: + + # Logic 1: Make subproblems independent with sorting and solve greedily (ref: sol) + def bagOfTokensScore(self, tokens: List[int], power: int) -> int: + + tokens.sort() # sorting converts it to greedy removing choice dependency + + score = 0 + result = 0 + + while tokens and (power >= tokens[0] or score > 0): + + while tokens and tokens[0] <= power: # maximize the score with while to be greedy + curr_card = tokens.pop(0) + power -= curr_card + score += 1 + + result = max(result, score) # calc max score as we play + + if tokens and score > 0: # maximize the power by choosing last element to be greedy + curr_card = tokens.pop() + score -= 1 + power += curr_card + + return result diff --git a/ProblemSolving/beforeAndAfterPuzzle/puzzle.py b/ProblemSolving/beforeAndAfterPuzzle/puzzle.py new file mode 100644 index 0000000..fedce10 --- /dev/null +++ b/ProblemSolving/beforeAndAfterPuzzle/puzzle.py @@ -0,0 +1,32 @@ +class Solution(object): + def beforeAndAfterPuzzles(self, phrases): + """ + :type phrases: List[str] + :rtype: List[str] + """ + + # Naive O(N**2) iteration - 100 pass 6% faster + + # we use list instead of set() here to properly sort lexicographically + result = [] + visited = set() + + # O(n**2) iteration + for i in range(len(phrases)): + for j in range(len(phrases)): + if i != j: + p1 = phrases[i].split(" ") + p2 = phrases[j].split(" ") + #print(p1, p2) + if p1[-1] == p2[0]: + if " ".join(p1 + p2[1:]) not in visited: + visited.add(" ".join(p1 + p2[1:])) + result.append(" ".join(p1 + p2[1:])) + elif p1[0] == p2[-1]: + if " ".join(p2 + p1[1:]) not in visited: + visited.add(" ".join(p2 + p1[1:])) + result.append(" ".join(p2 + p1[1:])) + else: + continue + + return sorted(result) diff --git a/ProblemSolving/bestTimeToBuyAndSellStock/maxProfit.py b/ProblemSolving/bestTimeToBuyAndSellStock/maxProfit.py new file mode 100644 index 0000000..c77835f --- /dev/null +++ b/ProblemSolving/bestTimeToBuyAndSellStock/maxProfit.py @@ -0,0 +1,70 @@ +class Solution(object): + def maxProfit(self, prices, fee): + """ + :type prices: List[int] + :type fee: int + :rtype: int + """ + + # Greedy algorithm + + # As we thought, + # * Creating a reference for minimum and maximum values is a trick + # * Be greedy to choose the minimum and execute transaction as soon as we get profit + + # Number of days + n = len(prices) + + # Assume min + minimum = prices[0] + + # Total Money + total = 0 + + for i in range(n): + # If we found a minimum along the way, update it + if prices[i] < minimum: + minimum = prices[i] + # As soon as we get a profit execute transaction + # * Calculate profit as something greater than minimum + fee (Done calculate sell fee here, as atmost 0 is also a profit) + elif prices[i] > minimum + fee: + total += prices[i] - minimum - fee + # Calculate the new minimum now as the executed proces minus the fees (this would be the buy fee) + minimum = prices[i] - fee + #print total + + return total + + """ + # Literal Calculation + + # Number of days + n = len(prices) + mid = n//2 + + # reference array instead of calculating max and min prices as we traverse + #prices_range = sorted(prices) + minimum = prices[0] + + # + total = 0 + bought = False + + # Iterate over the prices range + # * Find the min max as we traverse, calculate the max delta and execute the trade + for i in range(n): + if bought == False and prices[i] <= minimum: + total -= prices[i] + total -= fee + bought = True + if bought == True and prices[i] > minimum+fee: + total += prices[i] + total -= fee + minu + bought = False + + return total + """ + + + diff --git a/ProblemSolving/bestTimeToBuyAndSellStockII/profit.py b/ProblemSolving/bestTimeToBuyAndSellStockII/profit.py new file mode 100644 index 0000000..4bdab27 --- /dev/null +++ b/ProblemSolving/bestTimeToBuyAndSellStockII/profit.py @@ -0,0 +1,26 @@ +class Solution(object): + def maxProfit(self, prices): + """ + :type prices: List[int] + :rtype: int + """ + + # Go Greedy + + # Assume minimum is day1 + + mini = float('inf') + total = 0 + + # Iterate through the day prices + for day in range(len(prices)): + + # Change the minimum and buy that day + if prices[day] < mini: + mini = prices[day] + elif (day+1 < len(prices) and prices[day+1] < prices[day]) or day == len(prices)-1: + #print(prices[day]-mini) + total += prices[day]-mini + mini = float('inf') + #print(mini, prices[day]) + return total diff --git a/ProblemSolving/bestTimeToBuyAndSellStockII/profit2.py b/ProblemSolving/bestTimeToBuyAndSellStockII/profit2.py new file mode 100644 index 0000000..ea5c230 --- /dev/null +++ b/ProblemSolving/bestTimeToBuyAndSellStockII/profit2.py @@ -0,0 +1,39 @@ +class Solution(object): + def maxProfit(self, prices): + """ + :type prices: List[int] + :rtype: int + """ + + mini = float('inf') + profit = 0 + for i in range(len(prices)): + if prices[i] <= mini: + mini = prices[i] + else: + if (i+1 < len(prices) and prices[i+1] < prices[i]) or i == len(prices)-1: + profit += prices[i]-mini + mini = float('inf') + return profit + + """ + # Go Greedy + + # Assume minimum is day1 + + mini = float('inf') + total = 0 + + # Iterate through the day prices + for day in range(len(prices)): + + # Change the minimum and buy that day + if prices[day] < mini: + mini = prices[day] + elif (day+1 < len(prices) and prices[day+1] < prices[day]) or day == len(prices)-1: + #print(prices[day]-mini) + total += prices[day]-mini + mini = float('inf') + #print(mini, prices[day]) + return total + """ diff --git a/ProblemSolving/binaryGap/bin.py b/ProblemSolving/binaryGap/bin.py new file mode 100644 index 0000000..4b338a9 --- /dev/null +++ b/ProblemSolving/binaryGap/bin.py @@ -0,0 +1,57 @@ +class Solution(object): + def binaryGap(self, N): + """ + :type N: int + :rtype: int + """ + + # Brute force method, naive iteration to find consecutive ones + # * One loop for 1st one + # * Second loop for 2nd one + # * We already traverse digits in between, so move forward the index to the second one for the next loop.... + binary = bin(N) + #print binary + + # Control vars + n = len(binary) + maxi = 0 + + # iteration until finding the 1st one + i = 0 + while i < n: + if binary[i] == "1": + # iteration for 2nd one + j = i+1 + while j < n: + # Break as soon as consecutive one is found and adjust index to the consecutive one + if binary[j] == "1": + maxi = max(maxi, j-i) + i = j-1 # Once you break after finding consecutive, while loop iterates i += 1, to handle that negate i before breaking + break + j += 1 + i += 1 + + return maxi + + """ + # Logic: + # * Convert number to a usable form of binary + # * Only the max is required, use 2 pointer method to return on first match --> does not work when consecutive ones need to be worked on. + binary = str(bin(N))[2:] + + left = 0 + right = len(binary)-1 + + while left <= right: + if binary[left] == "1": + break + left += 1 + + while right >= left: + if binary[right] == "1": + break + + right -= 1 + print right, left + return (right - left) + """ diff --git a/ProblemSolving/binaryNumberWithAlternatingBits/bin.py b/ProblemSolving/binaryNumberWithAlternatingBits/bin.py new file mode 100644 index 0000000..b546d77 --- /dev/null +++ b/ProblemSolving/binaryNumberWithAlternatingBits/bin.py @@ -0,0 +1,16 @@ +class Solution(object): + def hasAlternatingBits(self, n): + """ + :type n: int + :rtype: bool + """ + + # Simple O(N) iteration over the binary representation + # 100 pass 79 + n_bin = bin(n)[2:] + for i in range(len(n_bin)-1): + if n_bin[i] != n_bin[i+1]: + pass + else: + return False + return True diff --git a/ProblemSolving/binaryPrefixDivisibleBy5/binary.py b/ProblemSolving/binaryPrefixDivisibleBy5/binary.py new file mode 100644 index 0000000..6d6fa97 --- /dev/null +++ b/ProblemSolving/binaryPrefixDivisibleBy5/binary.py @@ -0,0 +1,37 @@ +class Solution(object): + def prefixesDivBy5(self, A): + """ + :type A: List[int] + :rtype: List[bool] + """ + + # Logic 1: O(N) Iteration + Type casting - 100 pass - 1008 ms 15% faster + """ + result = [] + current = "" + for i in range(len(A)): + current += str(A[i]) + if int(current,2)%5 == 0: + result.append(True) + else: + result.append(False) + return result + """ + + # Logic 2: O(N) Iteration - 100 pass - 55.83 % faster + # * I initially used `current = current*10 + A[i]` to append the integers in integer form resp, which failed at some point as the prefix 0 is lost + # * Multiply by 2 made sense --> Ref: https://leetcode.com/problems/binary-prefix-divisible-by-5/discuss/265601/Detailed-Explanation-using-Modular-Arithmetic-O(n) + result = [] + current = None + for i in range(len(A)): + if current == None: + current = A[i] + else: + current = current*2 + A[i] + #print(current) + if current%5 == 0: + result.append(True) + else: + result.append(False) + return result + diff --git a/ProblemSolving/binarySearch/bin.py b/ProblemSolving/binarySearch/bin.py new file mode 100644 index 0000000..764d742 --- /dev/null +++ b/ProblemSolving/binarySearch/bin.py @@ -0,0 +1,85 @@ +class Solution(object): + def search(self, nums, target): + """ + :type nums: List[int] + :type target: int + :rtype: int + """ + + # Binary search is Half n Half. + # * Always check for half and choose most promising + + # 2 pointer technique - to memorize the indexes as we move through the array without altering the array to perform the search should be apt... + + # Init + left = 0 + right = len(nums)-1 + + # Dividing by 2 and setting pointers as we proceed + while left < right: + mid = (left + right)//2 + print left, mid, right + if nums[mid] == target: + return mid + elif nums[mid] < target: + left = mid + else: + right = mid + + # Smallest array condition (when the array is of length 2) + if (right - left) == 1: + if nums[right] == target: + return right + elif nums[left] == target: + return left + else: + return -1 + + # Equal or single element condition + if left == right and nums[left] == target: + return left + + # no match condition + return -1 + + """ + # Binary search works in the below logic, existence returned + # * Maintaining the index is not done here + while nums: + n = len(nums) + mid = n//2 + if nums[mid] == target: + return True + elif nums[mid] < target: + nums = nums[mid:] + else: + nums = nums[:mid] + return False + """ + + """" + # Altering same logic as above (for existence to crack) + # * Maintaining the index left and right is a challenge + + start_index = 0 + + if nums[start_index] == target: + return 0 + + while len(nums) > 1: + n = len(nums) + mid = n//2 + if nums[mid] == target: + if (start_index + mid) < start_index: + return start_index - mid - 1 + else: + return start_index + mid + elif nums[mid] < target: + nums = nums[mid:] + else: + nums = nums[:mid] + start_index += mid + return -1 + """ + + diff --git a/ProblemSolving/binarySearch/concept.py b/ProblemSolving/binarySearch/concept.py new file mode 100644 index 0000000..a4081cb --- /dev/null +++ b/ProblemSolving/binarySearch/concept.py @@ -0,0 +1,47 @@ +# Binary Search + +# Recursive +def binary_search(array, target, start_index): + + n = len(array) + mid = n//2 + + if n == 0: + return "Not Found!" + + #print start_index, mid, target, array + + if array[mid] == target: + return "Found! at " + str(mid + start_index) + elif array[mid] > target: + if start_index > 0: + return binary_search(array[:mid], target, start_index) + else: + return binary_search(array[:mid], target, 0) + else: + return binary_search(array[mid+1:], target, start_index+mid+1) + +# 2 pointer +def binary_search2(array, target): + + # Initial values + left = 0 + right = len(array) + + # Iterate until left < right + while left < right: + # Mid point + mid = (left + right)//2 + #print left, right, mid, array + if array[mid] == target: + return "Found! at " + str(mid) + elif array[mid] > target: + right = mid + else: + left = mid+1 + return "Not Found!" + +array = [1,2,3,4,5,6,7,8,9] +print binary_search(array, 1, 0), binary_search(array, 9, 0), binary_search(array, 10, 0) +print binary_search2(array, 1), binary_search2(array, 9), binary_search2(array, 10) + diff --git a/ProblemSolving/binarySearch/prac.py b/ProblemSolving/binarySearch/prac.py new file mode 100644 index 0000000..957518a --- /dev/null +++ b/ProblemSolving/binarySearch/prac.py @@ -0,0 +1,19 @@ +# # Practice + +def binarySearch(nums, target): + left, right = 0, len(nums)-1 + while left < right: + mid = left + len(nums[left:right])//2 + print(left, mid, right) + if nums[mid] == target or nums[left] == target or nums[right] == target: + return True + elif nums[mid] > target: + right = mid + elif nums[mid] < target: + left = mid + + return False + +nums = [1,2,3,4,5,6,7,8,9] +for i in range(0, 10): + print(binarySearch(nums, i)) diff --git a/ProblemSolving/binarySearchTreeIterater/bstIterate.py b/ProblemSolving/binarySearchTreeIterater/bstIterate.py new file mode 100644 index 0000000..7264626 --- /dev/null +++ b/ProblemSolving/binarySearchTreeIterater/bstIterate.py @@ -0,0 +1,48 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class BSTIterator(object): + + def __init__(self, root): + """ + :type root: TreeNode + """ + # PreOrder Search BST as soon as you get root + self.result = [] + def preorder(node): + if node: + preorder(node.left) + self.result.append(node.val) + preorder(node.right) + preorder(root) + + + def next(self): + """ + @return the next smallest number + :rtype: int + """ + if self.result: + return self.result.pop(0) + + + def hasNext(self): + """ + @return whether we have a next smallest number + :rtype: bool + """ + if self.result: + return True + else: + return False + + + +# Your BSTIterator object will be instantiated and called as such: +# obj = BSTIterator(root) +# param_1 = obj.next() +# param_2 = obj.hasNext() diff --git a/ProblemSolving/binarySearchTreeToGreaterSumTree/bst.py b/ProblemSolving/binarySearchTreeToGreaterSumTree/bst.py new file mode 100644 index 0000000..926bb14 --- /dev/null +++ b/ProblemSolving/binarySearchTreeToGreaterSumTree/bst.py @@ -0,0 +1,52 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def bstToGst(self, root): + """ + :type root: TreeNode + :rtype: TreeNode + """ + + # Logic 1: 49% faster and 100% space + # * Naive, find all the node values and sum of the bst + # * Obtain these values in sorted form ( in order traversal from above?) + # * Compute and replace the node values + + # Obtain all node values in sorted form + self.node_vals = [] + def in_order_traverse(node): + if node: + if node.left: + in_order_traverse(node.left) + self.node_vals.append(node.val) + if node.right: + in_order_traverse(node.right) + else: + return + + def compute_and_replace(node): + if node: + if node.left: + compute_and_replace(node.left) + # Compute + for i in range(len(self.node_vals)): + if self.node_vals[i] >= node.val: + break + #print(node.val, i) + node.val = sum(self.node_vals[i:]) + if node.right: + compute_and_replace(node.right) + else: + return + + in_order_traverse(root) + #print(self.node_vals, sum(self.node_vals), root.val) + compute_and_replace(root) + return root + + diff --git a/ProblemSolving/binaryTreeLevelOrderTraversalII/bin.py b/ProblemSolving/binaryTreeLevelOrderTraversalII/bin.py new file mode 100644 index 0000000..3ccf43f --- /dev/null +++ b/ProblemSolving/binaryTreeLevelOrderTraversalII/bin.py @@ -0,0 +1,29 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right +class Solution: + def levelOrderBottom(self, root: TreeNode) -> List[List[int]]: + + # Logic 1: Level Order Iterative Way + if not root: + return [] + + stack = [root] # to record nodes visited + result = [] # to store results level by level + n = len(stack) + + while stack: + result = [[]] + result + n = len(stack) + while n: + current = stack.pop(0) + result[0].append(current.val) + if current.left: + stack.append(current.left) + if current.right: + stack.append(current.right) + n -= 1 + return result diff --git a/ProblemSolving/binaryTreeMaximumPathSum/bin.py b/ProblemSolving/binaryTreeMaximumPathSum/bin.py new file mode 100644 index 0000000..3780d74 --- /dev/null +++ b/ProblemSolving/binaryTreeMaximumPathSum/bin.py @@ -0,0 +1,109 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def maxPathSum(self, root): + """ + :type root: TreeNode + :rtype: int + """ + + # Logic 3 + # * Same traverse logic as 2, but calculate all possible values possible + # * Compare + # - current max calculate based on the current path + # - current node value and left + # - current node value and right + # - current both left and right ( for instance when this only a root way path ) + # - current node itself + + # initial max value + self.maxi = -float('inf') + + def traverse(node): + + # Calculate left and right sum + left_sum = traverse(node.left) if node.left else 0 + right_sum = traverse(node.right) if node.right else 0 + + # Calculate max as we defined + self.maxi = max(self.maxi, node.val+left_sum, node.val+right_sum, node.val+left_sum+right_sum, node.val) + + # Return the path value as we traverse, compare with an additional "0", because we dont want a path which reduces the total path value + return node.val + max(left_sum, right_sum, 0) + + traverse(root) + + return self.maxi + + """ + # Logic 2 + # * The challenge is to find any path that also goes without the root? + # * A: To visualize such a logic, assume we always go from left to right to any node, then we use pre-order + # * B1: After we do the preorder arrangement we then calculate the maximum path by another iteration + # * B2: Improvise - We could also do a inbuilt iteration within the preorder loof itself. + + self.nodes_list = [] + self.maxi = -float('inf') + sumi = 0 + + def traverse(node, sumi): + + self.nodes_list.append(node.val) + sumi += node.val + + if sumi > self.maxi: + self.maxi = sumi + + if node.left: + lsum = traverse(node.left, sumi) + else: + lsum = 0 + + if node.right: + rsum = traverse(node.right, lsum) + else: + rsum = 0 + + return lsum + rsum + + traverse(root, sumi) + return self.maxi + """ + + """ + # Logic 1 + # * PreOrder and Calculate + + self.preorder_list = [] + + def preorder_traverse(node): + + self.preorder_list.append(node.val) + if node.left: + preorder_traverse(node.left) + if node.right: + preorder_traverse(node.right) + + preorder_traverse(root) + + n = len(self.preorder_list) + maxi = -float('inf') + sumi = 0 + for i in range(n): + print sumi, maxi + sumi += self.preorder_list[i] + if sumi > maxi: + maxi = sumi + else: + sumi = self.preorder_list[i] + return maxi + """ + + + + diff --git a/ProblemSolving/binaryTreePreOrderTraversal/bin2.py b/ProblemSolving/binaryTreePreOrderTraversal/bin2.py new file mode 100644 index 0000000..b041714 --- /dev/null +++ b/ProblemSolving/binaryTreePreOrderTraversal/bin2.py @@ -0,0 +1,21 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right +class Solution: + def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]: + + stack = [root] + traversal = [] + while stack: + curr = stack.pop(0) + if not curr: + continue + traversal.append(curr.val) + if curr.right: + stack = [curr.right] + stack + if curr.left: + stack = [curr.left] + stack + return traversal diff --git a/ProblemSolving/binaryTreePruning/bstPrune.py b/ProblemSolving/binaryTreePruning/bstPrune.py new file mode 100644 index 0000000..252feb0 --- /dev/null +++ b/ProblemSolving/binaryTreePruning/bstPrune.py @@ -0,0 +1,42 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def pruneTree(self, root): + """ + :type root: TreeNode + :rtype: TreeNode + """ + + def new_tree(node): + + if node.left: + left_children = new_tree(node.left) + else: + left_children = [] + + if node.right: + right_children = new_tree(node.right) + else: + right_children = [] + + if 1 not in left_children: + node.left = None + + if 1 not in right_children: + node.right = None + + children = [node.val if node else None] + left_children + right_children + + #print children + + return children + + new_tree(root) + return root + + diff --git a/ProblemSolving/binaryTreePruning/bstPrune2.py b/ProblemSolving/binaryTreePruning/bstPrune2.py new file mode 100644 index 0000000..afd66d4 --- /dev/null +++ b/ProblemSolving/binaryTreePruning/bstPrune2.py @@ -0,0 +1,34 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right +class Solution: + def pruneTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]: + + def traverse(node): + + oneLeft = oneRight = False + + if node.left: + oneLeft = traverse(node.left) + if node.right: + oneRight = traverse(node.right) + + if oneLeft is False: + node.left = None + if oneRight is False: + node.right = None + + final = oneLeft or oneRight + + if node.val == 1: + final = final or True + + return final + + traverse(root) + if root.val == 0 and not root.left and not root.right: + root = None + return root diff --git a/ProblemSolving/binaryTreeRightSideView/binary.py b/ProblemSolving/binaryTreeRightSideView/binary.py new file mode 100644 index 0000000..397b315 --- /dev/null +++ b/ProblemSolving/binaryTreeRightSideView/binary.py @@ -0,0 +1,33 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def rightSideView(self, root): + """ + :type root: TreeNode + :rtype: List[int] + """ + + # Logic 1: + # * Perform level order traversal and get the last element on that level + def traverse(node, level): + if level not in levels: + levels[level] = [] + levels[level].append(node.val) + if node.left: + traverse(node.left, level+1) + if node.right: + traverse(node.right, level+1) + + result = [] + levels = {} + if not root: + return [] + traverse(root, 0) + for k,v in levels.items(): + result.append(v[-1]) + return result diff --git a/ProblemSolving/binaryTreeWithFactors/bin.py b/ProblemSolving/binaryTreeWithFactors/bin.py new file mode 100644 index 0000000..3cc9d35 --- /dev/null +++ b/ProblemSolving/binaryTreeWithFactors/bin.py @@ -0,0 +1,25 @@ +class Solution: + def numFactoredBinaryTrees(self, arr: List[int]) -> int: + + # Ref: leetcode solution for help + MOD = 10 ** 9 + 7 + + refs = [1]*len(arr) # single index is one tree already + + arr.sort() # arrange so we can iterate for product/modulo computation + + prods = {} + for i in range(len(arr)): + prods[arr[i]] = i # unique so no need to check existence + + for i in range(len(arr)): + for j in range(i): + if arr[i]%arr[j] == 0: # left is arr[j] + other = arr[i]//arr[j] + + if other in prods: + refs[i] += refs[j] * refs[prods[other]] + refs[i] %= MOD + + return sum(refs)%MOD + diff --git a/ProblemSolving/binaryTreeZigZagLevelOrderTraversal/bstZigzag2.py b/ProblemSolving/binaryTreeZigZagLevelOrderTraversal/bstZigzag2.py new file mode 100644 index 0000000..39c7d80 --- /dev/null +++ b/ProblemSolving/binaryTreeZigZagLevelOrderTraversal/bstZigzag2.py @@ -0,0 +1,31 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right +class Solution: + def zigzagLevelOrder(self, root: Optional[TreeNode]) -> List[List[int]]: + + if not root: + return + stack = [root] + zigZag = [] + + while stack: + n = len(stack) + zigZag.append([]) # insert new level + pos = len(zigZag)-1 + while n: + curr = stack.pop(0) + if pos%2 == 0: + zigZag[-1].append(curr.val) + else: + zigZag[-1] = [curr.val] + zigZag[-1] + if curr.left: + stack.append(curr.left) + if curr.right: + stack.append(curr.right) + n -= 1 + + return zigZag diff --git a/ProblemSolving/boatsToSavePeople/boats.py b/ProblemSolving/boatsToSavePeople/boats.py new file mode 100644 index 0000000..b6e0647 --- /dev/null +++ b/ProblemSolving/boatsToSavePeople/boats.py @@ -0,0 +1,48 @@ +ss Solution: + def numRescueBoats(self, people: List[int], limit: int) -> int: + + # Greedy Approach to fill the boat to capacity as they come in + + # Logic 2 - Using Dictionary - 100 pass - only 5 % faster - optimize? + import collections + boats = 0 + p = collections.Counter(people) + for i in range(len(people)): + if p[people[i]] == 0: + continue + current = people[i] + # IF CURRENT PERSON SATISFIES FULL WEIGHT + if current == limit: + p[current] -= 1 + boats += 1 + else: + # IF WEIGHT IS LESSER SELECT BEST OPTIMAL CHOICE FOR THE CURRENT + next_person = limit - current + p[current] -= 1 + while next_person and (next_person not in p or p[next_person] <=0): + next_person -= 1 + if next_person > 0: + p[next_person] -= 1 + #print(next_person, current) + boats += 1 + #print(p, boats) + return boats + + + + # Logic 1: Iteration with some sort - This would not work as we need to find out the exact weight matches to make current optimal choice + """ + boats = 0 + people.sort() + while people: + total_weight = 0 + while total_weight < limit and people and (total_weight + people[0]) <= limit : + total_weight += people.pop(0) + boats += 1 + print(boats, total_weight, people) + return boats + """ + + + + diff --git a/ProblemSolving/bulbSwitch/bulb.py b/ProblemSolving/bulbSwitch/bulb.py new file mode 100644 index 0000000..311ba99 --- /dev/null +++ b/ProblemSolving/bulbSwitch/bulb.py @@ -0,0 +1,83 @@ +# Still pending... +class Solution(object): + def bulbSwitch(self, n): + """ + :type n: int + :rtype: int + """ + + # Logic 4: + # * Taking divisibility test in logic 3 to another level + # * This solution has interesting math property --> Only perfect squares have odd number of divisibility and only odd leads to bulb being on + # https://leetcode.com/problems/bulb-switcher/discuss/327486/Python-one-line-solution + # * Lets do a O(N) iteration instead of a one line solution + result = 0 + for i in range(int(math.sqrt(n))+1): + if float(math.sqrt(i+1)).is_integer(): + result += 1 + return result + + + # Logic 3: Divisibility test logic + """ + def is_divisible(number): + import math + result = 2 # 1 and itself being divisible + if number == 1: + return 1 + for i in range(2, (number//2)+1):#int(math.sqrt(number))+1): + if number%i == 0: + result += 1 + return result + + switches_with_one = 0 + for i in range(n): + div_test = is_divisible(i+1) + #print(i+1, div_test) + if div_test%2 != 0: + switches_with_one += 1 + return switches_with_one + """ + + # Logic 2: Naive bruteforce + """ + # Lets assume 1 in ON and 0 is OFF + # * First steps (1st iteration) also includes constructing the dictionary + # * So, all are ON + + # Initial condition and first round + switches = [1]*n #[0]*n + + # N Rounds with N switches + for i in range(2, n+1): + for j in range(i, n+1, i): + switches[j-1] = switches[j-1]^1 + #print(switches) + return switches.count(1) + """ + + # Logic 1: an attempt before 7 month + """ + import collections + + # Lets assume 1 in ON and 0 is OFF + # * First steps (1st iteration) also includes constructing the dictionary + # * So, all are ON + switches = collections.Counter(range(1,n+1)) + + for i in range(2, n+1): + if i == 2: + for k in range(i, n+1, i): + switches[k] = 0 + else: + for k in range(i, n+1, i): + switches[k] = switches[k]^1 + + return sum(switches.values()) + """ + + + + + + diff --git a/ProblemSolving/bullsAndCows/bull.py b/ProblemSolving/bullsAndCows/bull.py new file mode 100644 index 0000000..bfd0f07 --- /dev/null +++ b/ProblemSolving/bullsAndCows/bull.py @@ -0,0 +1,74 @@ +class Solution(object): + def getHint(self, secret, guess): + """ + :type secret: str + :type guess: str + :rtype: str + """ + + # Logic n: 100 pass + + # Bull Count + A = 0 + # Cow Count + B = 0 + + #One iteration to find out the equal index + for i in range(len(guess)): + if guess[i] == secret[i]: + A += 1 + # OR + #A = sum([i==j for i,j in zip(secret, guess)]) + + # Two all other intersections + #print(collections.Counter(secret), collections.Counter(guess), (collections.Counter(secret) & collections.Counter(guess))) + B = sum((collections.Counter(secret) & collections.Counter(guess)).values())-A + + + # In search of optimization to O(N) + + # Logic 1: Naive Iteration - Fail! + """ + visited = [] + for i in range(len(guess)): + if guess[i] == secret[i]: + if guess[i] in visited: + B -= 1 + A += 1 + elif guess[i] in secret[:i]+secret[i+1:]: + if guess[i] not in visited: + visited.append(guess[i]) + B += 1 + print(visited, A, B) + + i = 0 + secret = list(secret) + guess = list(guess) + while i < len(secret): + if secret and guess and secret[i] == guess[i]: + A += 1 + secret.pop(i) + guess.pop(i) + else: + + i += 1 + """ + """ + C1 = collections.Counter(secret) + C2 = collections.Counter(guess) + print(C1,C2) + """ + + # Logic 2: Use extra space a dictionary -> wont work for duplicates - Fail! + """ + import collections + counts = collections.Counter(secret+guess) + for k,v in counts.items(): + if v == 2 and k in secret and k in guess and secret.index(k) == guess.index(k): + A += 1 + else: + B += 1 + """ + + return str(A)+"A"+str(B)+"B" + diff --git a/ProblemSolving/buyAndSellStock1/buy2.py b/ProblemSolving/buyAndSellStock1/buy2.py new file mode 100644 index 0000000..f3b96db --- /dev/null +++ b/ProblemSolving/buyAndSellStock1/buy2.py @@ -0,0 +1,62 @@ +class Solution(object): + def maxProfit(self, prices): + """ + :type prices: List[int] + :rtype: int + """ + + # Logic 1: At each price, try to find max and subtract - Obviously time limit exceeded + """ + profit = 0 + for p in range(len(prices)): + if prices[p+1:]: + current_profit = max(prices[p+1:]) - prices[p] + if current_profit > profit: + profit = current_profit + return profit + """ + + # Logic 2: Greedy --> Buy when the price decreases from previous day and sell when it increases next day + """ + buy = None + sell = None + for p in range(len(prices)): + if buy == None and (prices[p] < prices[p-1] or prices[p+1] > prices[p]): + buy = p + elif buy < sell and prices[p] < prices[buy]: + buy = p + elif sell == None and buy != None and prices[p] > prices[buy]: + sell = p + elif buy != None and sell != None and sell > buy and prices[p] > prices[sell]: + sell = p + print(buy, sell) + if not buy or not sell: + return 0 + return sell-buy + """ + + # Logic 3: 2 pointer method - does not work + """ + n = len(prices) + buy = 0 + sell = n-1 + profit = 0 + while buy < sell: + profit = max(prices[sell] - prices[buy], profit) + if prices[sell] < prices[buy]: + buy += 1 + elif prices[buy] > prices[sell]: + sell -= 1 + return prices[sell]-prices[buy] + """ + + # Logic 4: O(N) iterate and follow mini and profit + mini = float('inf') + n = len(prices) + profit = 0 + for i in range(n): + if prices[i] < mini: + mini = prices[i] + elif prices[i]-mini > profit: + profit = prices[i]-mini + return profit diff --git a/ProblemSolving/candy/candy.py b/ProblemSolving/candy/candy.py new file mode 100644 index 0000000..efe51f8 --- /dev/null +++ b/ProblemSolving/candy/candy.py @@ -0,0 +1,28 @@ +class Solution: + def candy(self, ratings: List[int]) -> int: + + # Logic 1: O(N) iteration + n = len(ratings) + + if n == 0: + return 0 + if n == 1: + return 1 + + candies = [1]*n + + for i in range(1, len(ratings)): + if ratings[i-1] < ratings[i]: + candies[i] = candies[i-1]+1 + + min_cost = candies[n-1] + for i in range(n-2, -1, -1): + if ratings[i] > ratings[i+1]: + v = candies[i+1]+1 + if v > candies[i]: + candies[i] = v + min_cost += candies[i] + + #print(candies) + + return min_cost diff --git a/ProblemSolving/captalizeTheTitle/cap.py b/ProblemSolving/captalizeTheTitle/cap.py new file mode 100644 index 0000000..7c78b3f --- /dev/null +++ b/ProblemSolving/captalizeTheTitle/cap.py @@ -0,0 +1,12 @@ +""" +https://leetcode.com/contest/biweekly-contest-69/problems/capitalize-the-title/ +""" +class Solution: + def capitalizeTitle(self, title: str) -> str: + words = title.split(" ") + for w in range(len(words)): + if len(words[w]) <= 2: + words[w] = words[w].lower() + else: + words[w] = words[w][0].upper() + words[w][1:].lower() + return " ".join(words) diff --git a/ProblemSolving/carPooling/car.py b/ProblemSolving/carPooling/car.py new file mode 100644 index 0000000..035c496 --- /dev/null +++ b/ProblemSolving/carPooling/car.py @@ -0,0 +1,107 @@ +class Solution(object): + def carPooling(self, trips, capacity): + """ + :type trips: List[List[int]] + :type capacity: int + :rtype: bool + + + # Lesson: + # The right mood and mindset would allow you to solve anything easily! + # * Take rest and off sometime and get your mood for the problem + # * one shot solve of a problem attempted earlier with a new logic + + # Logic: 100 pass: A slower logic but passes all scenarios. + # * Plot all the route and calculate capacity at each point, return false if it exceeds + """ + #trips = [[2,1,5],[3,3,7]] + #capacity = 4 + route = [] + for trip in trips: + if len(route) < trip[2]: + route.extend([0]*(trip[2]-len(route))) + #print(route, trip[2]) + for road in range(trip[1], trip[2]): + route[road-1] += trip[0] + #print(route[road-1], capacity) + if route[road-1] > capacity: + return False + return True + + + """ + # No 100 pass - an attempt to finish later + # Logic 1: Fails (works only for iterative increase) Literally following through all the trips and calculating if capacity exceeds + # * This logic works assuming the ranges (start->end) only overlap for the next trip and not further + # * If there exist a trip farther in the list overlapping subset of the entire or initial part of the array then this fails + + # num of passengers: destination address + + start = [] + end = [] + passengers = [] + + for trip in trips: + print end, passengers, capacity, trip + if end and trip[1] >= end[-1]: + end.pop() + start.pop() + capacity += passengers.pop() + elif end and trip[2] <= end[-1] and trip[1] > start[-1]: + break + elif start and trip[1] < start[-1]: + return False + passengers.append(trip[0]) + end.append(trip[2]) + start.append(trip[1]) + capacity -= trip[0] + if capacity < 0: + return False + return True + """ + + """ + No 100 pass - an attempt to finish later!! + # Logic 2: Overlapping subsets + # * We need to solve this global for any overlapping range across the entire array + + # Method 1 + + # sort by the start interval + trips = sorted(trips, key=lambda x: x[1]) + + + end = [] + seats = [] + for trip in trips: + + # Overlapping subsets + + # Case1: When a subset falls within the previous subset + # Case2: When a subset overlaps and exceeds the previous subset + + #if end and trip[2] <= end[-1]: + # capacity -= trip[1] + #elif end and trip[1] < end[-1] and trip[2] > end[-1]: + # if seats[-1] + trip[0] > capacity: + # return False + # capacity += seats.pop() + # end.pop() + + + if trip[1] < end[-1]: + capacity -= trip[0] + else: + capacity += + + # For every trip add to the list and calculate capacity ( non overlapping ) + end.append(trip[2]) + seats.append(trip[1]) + + # Fail if capacity is exceeded + if capacity < 0: + return False + + # True otherwise + return True + """ diff --git a/ProblemSolving/characterReplacement/char.py b/ProblemSolving/characterReplacement/char.py new file mode 100644 index 0000000..44bbccc --- /dev/null +++ b/ProblemSolving/characterReplacement/char.py @@ -0,0 +1,68 @@ +class Solution(object): + def characterReplacement(self, s, k): + """ + :type s: str + :type k: int + :rtype: int + """ + + # Logic 1: Pending work.... No magic, just follow the steps in the problem literally. + + + n = len(s) + select = None + result = 0 + i = 0 + while i < n: + print i, select, result + if select == None: + select = i + tempk = k + tempi = None + else: + if s[i] != s[select]: + if tempk <= 0 or i == n-1: + if len(s[select:i]) > result: + result = len(s[select:i]) + if i == n-1: + result += 1 + select = None + if tempi > 0: + i = tempi-1 + else: + if tempi == None: + tempi = i + tempk -= 1 + i += 1 + return result + + + # Logic 2: 100 pass + # * Reference: https://leetcode.com/problems/longest-repeating-character-replacement/discuss/91272/consise-python-sliding-window + # * Using formal sliding window technique from the above thread + + # Array/List logic + # Initialize a alphabet space to use + counts = [0]*26 + + start = max_count = max_length = 0 + + # Iterate end to move the window + for end in range(len(s)): + index = ord(s[end])-ord('A') + # Increase count for the character + counts[index] += 1 + # Set max_count as we proceed + max_count = max(max_count, counts[index]) + # Move window + while end - start + 1 - max_count > k: + counts[ord(s[start])-ord('A')] -= 1 + start += 1 + max_length = max(max_length, end-start+1) + return max_length + + # Dictionary logic: Replace array/list with dictionary for the above logic + + + + diff --git a/ProblemSolving/checkIfANumberIsMajorityElementInASortedArray/check.py b/ProblemSolving/checkIfANumberIsMajorityElementInASortedArray/check.py new file mode 100644 index 0000000..4d54560 --- /dev/null +++ b/ProblemSolving/checkIfANumberIsMajorityElementInASortedArray/check.py @@ -0,0 +1,56 @@ +class Solution: + # Logic 1: Using Dictionary or Counter - 100 pass - 85% + """ + def isMajorityElement(self, nums: List[int], target: int) -> bool: + import collections + counts = collections.Counter(nums) + if counts[target] > len(nums)//2: + return True + return False + """ + # Logic 2: Using BST and Iteration - No dictionary - 85% faster + def isMajorityElement(self, nums: List[int], target: int) -> bool: + def binary_search(nums, target): + l = 0 + r = len(nums)-1 + while l < r: + # BST + mid = l + (r-l)//2 + if target < nums[mid]: + r = mid + elif target > nums[mid]: + l = mid + # Return if found + if target == nums[l]: + return l + elif target == nums[r]: + return r + elif target == nums[mid]: + return mid + else: + return -1 + + return -1 + + index = binary_search(nums, target) + if index == -1: + return False + counts = 1 + left = index-1 + right = index+1 + while left >= 0 and nums[left] == target: + counts += 1 + left -= 1 + if counts > len(nums)//2: + return True + while right < len(nums) and nums[right] == target: + counts += 1 + right += 1 + if counts > len(nums)//2: + return True + return False + + + + + diff --git a/ProblemSolving/checkIfAStringContainsAllBinaryCodesOfSizeK/check.py b/ProblemSolving/checkIfAStringContainsAllBinaryCodesOfSizeK/check.py new file mode 100644 index 0000000..a42af84 --- /dev/null +++ b/ProblemSolving/checkIfAStringContainsAllBinaryCodesOfSizeK/check.py @@ -0,0 +1,29 @@ +class Solution(object): + def hasAllCodes(self, s, k): + """ + :type s: str + :type k: int + :rtype: bool + """ + + # Logic 1: compute total combinations of k binary codes, check if number of visited substrings match the total computed before (assuming substring is contiguous) + + total_sizek_codes = 2**k + + substrings = {} + + for i in range(len(s)): + end = i+k + if end > len(s): + continue + subs = s[i:end] + if subs not in substrings: + substrings[subs] = 0 + substrings[subs] += 1 + + #print(substrings) + + if len(substrings) == total_sizek_codes: + return True + + return False diff --git a/ProblemSolving/checkIfAWordOccursAsAPrefixOfAnyWordInSentence/check.py b/ProblemSolving/checkIfAWordOccursAsAPrefixOfAnyWordInSentence/check.py new file mode 100644 index 0000000..9cd8fda --- /dev/null +++ b/ProblemSolving/checkIfAWordOccursAsAPrefixOfAnyWordInSentence/check.py @@ -0,0 +1,17 @@ +class Solution(object): + def isPrefixOfWord(self, sentence, searchWord): + """ + :type sentence: str + :type searchWord: str + :rtype: int + """ + + # Logic 1: split sentence and compare searchWord length prefix for every word - 75% faster + words = sentence.split(" ") + m = len(searchWord) + + for i in range(len(words)): + if searchWord == words[i][:m]: + return i+1 + return -1 + diff --git a/ProblemSolving/checkIfAnArrayIsConsecutive/check.py b/ProblemSolving/checkIfAnArrayIsConsecutive/check.py new file mode 100644 index 0000000..112f636 --- /dev/null +++ b/ProblemSolving/checkIfAnArrayIsConsecutive/check.py @@ -0,0 +1,33 @@ +class Solution(object): + def isConsecutive(self, nums): + """ + :type nums: List[int] + :rtype: bool + """ + + # Logic 1: sort and check diff --> NlogN * N --> 27% faster + """ + nums.sort() + for i in range(len(nums)-1): + if nums[i+1]-nums[i] == 1: + continue + return False + return True + """ + + # Logic 2: 2*O(N) iteration with O(N) space --> 31% faster + num = {} + mini = float('inf') + maxi = -float('inf') + for i in nums: + if i in num: + return False + num[i] = 1 + if i < mini: + mini = i + if i > maxi: + maxi = i + for i in range(mini, maxi): + if i not in num: + return False + return True diff --git a/ProblemSolving/checkIfArrayIsSortedAndRotated/check.py b/ProblemSolving/checkIfArrayIsSortedAndRotated/check.py new file mode 100644 index 0000000..6917fab --- /dev/null +++ b/ProblemSolving/checkIfArrayIsSortedAndRotated/check.py @@ -0,0 +1,26 @@ +class Solution: + def check(self, nums: List[int]) -> bool: + + def findDivergedAtPos(nums: List[int]) -> (bool, int): + diverge = -2 + for i in range(1, len(nums)): + if nums[i] >= nums[i-1]: + continue + if diverge != -2: + return True, diverge + diverge = i + if diverge > -2: + return True, diverge + return False, 0 + + diverged, pos = findDivergedAtPos(nums) + if diverged and pos == -2: + return False + + sort_nums = nums[pos:] + nums[:pos] + diverged, pos = findDivergedAtPos(sort_nums) + print(diverged, pos, sort_nums) + if pos == 0 and not diverged: + return True + + return False diff --git a/ProblemSolving/checkIfItIsAStraightLine/check.py b/ProblemSolving/checkIfItIsAStraightLine/check.py new file mode 100644 index 0000000..a1fb685 --- /dev/null +++ b/ProblemSolving/checkIfItIsAStraightLine/check.py @@ -0,0 +1,36 @@ +class Solution(object): + def checkStraightLine(self, coordinates): + """ + :type coordinates: List[List[int]] + :rtype: bool + """ + + # Logic 1: If a line is going to be straight. All the DIFF/DISTANCE between every points should be equal - DIST does not work use SLOPE + + # Distance between 2 points + def distance(p1, p2): + import math + return math.sqrt((p2[0]-p1[0])**2 + (p2[1]-p1[1])**2) + + # Logic 2: Upgrading the same logic with SLOPE formula - 100 pass 50%faster + # Ref: https://www.urbanpro.com/gre/how-to-determine-if-points-are-collinear + + def slope(p1, p2): + # Using exception handler when x is 0 or undefined slope is encountered + try: + return (p2[1]-p1[1])//(p2[0]-p1[0]) + except: + return 0 + + # Iterate each pair of points + dist = None + coordinates.sort() + for p in range(1, len(coordinates)): + d = slope(coordinates[p], coordinates[p-1]) + #print(d, coordinates[p]) + if not dist: + dist = d + else: + if d != dist: + return False + return True diff --git a/ProblemSolving/checkIfNAndItsDoubleExists/check.py b/ProblemSolving/checkIfNAndItsDoubleExists/check.py new file mode 100644 index 0000000..7b31de3 --- /dev/null +++ b/ProblemSolving/checkIfNAndItsDoubleExists/check.py @@ -0,0 +1,15 @@ +class Solution(object): + def checkIfExist(self, arr): + """ + :type arr: List[int] + :rtype: bool + """ + + # Logic 1: Naive Iteration + for i in range(len(arr)): + if 2*arr[i] in set(arr[:i]+arr[i+1:]): + return True + return False + + # Logic 2: Use Dictionary / Set to check existence and then check for all doubles + diff --git a/ProblemSolving/checkStringAllAsAppearBeforeBs/check.py b/ProblemSolving/checkStringAllAsAppearBeforeBs/check.py new file mode 100644 index 0000000..41cb90d --- /dev/null +++ b/ProblemSolving/checkStringAllAsAppearBeforeBs/check.py @@ -0,0 +1,27 @@ +class Solution(object): + def checkString(self, s): + """ + :type s: str + :rtype: bool + """ + + # Logic 1: O(N) iteration with a flag variable - 95% faster + end_b = False + + for i in range(len(s)-1, -1, -1): + + if s[i] == "a": + end_b = True + if s[i] == "b" and end_b: + return False + + return True + + # Logic 2: O(N) iteration to find wrong order + """ + for i in range(len(s)-1): + if s[i]+s[i+1] == "ba": + return False + return True + """ + diff --git a/ProblemSolving/clearDigits/clear.py b/ProblemSolving/clearDigits/clear.py new file mode 100644 index 0000000..219ff36 --- /dev/null +++ b/ProblemSolving/clearDigits/clear.py @@ -0,0 +1,10 @@ +class Solution: + def clearDigits(self, s: str) -> str: + + result = "" + for i in s: + if i.isdigit() and result: + result = result[:-1] + else: + result += i + return result diff --git a/ProblemSolving/cloneNaryTree/clone.py b/ProblemSolving/cloneNaryTree/clone.py new file mode 100644 index 0000000..f62e558 --- /dev/null +++ b/ProblemSolving/cloneNaryTree/clone.py @@ -0,0 +1,29 @@ +""" +# Definition for a Node. +class Node: + def __init__(self, val=None, children=None): + self.val = val + self.children = children if children is not None else [] +""" + +class Solution: + def cloneTree(self, root: 'Node') -> 'Node': + + def clone(tree1, tree2=None): + + if not tree1: + return + + if tree2 == None: + tree2 = Node(tree1.val) + + for child in tree1.children: + new_child = Node(child.val) + clone(child, new_child) + tree2.children.append(new_child) + + return tree2 + + tree2 = clone(root) + return tree2 + diff --git a/ProblemSolving/closestBinarySearchTreeValue/close.py b/ProblemSolving/closestBinarySearchTreeValue/close.py new file mode 100644 index 0000000..c613661 --- /dev/null +++ b/ProblemSolving/closestBinarySearchTreeValue/close.py @@ -0,0 +1,32 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def closestValue(self, root, target): + """ + :type root: TreeNode + :type target: float + :rtype: int + """ + + # Logic 1: Use globals to track minimum and then recurse - 100 pass - 46% faster + def traverse(node): + if not node: + return + if self.mini == None or abs(target-node.val) < self.mini: + self.mini = abs(target-node.val) + self.closest = node.val + #print(self.mini) + if node.left: + traverse(node.left) + if node.right: + traverse(node.right) + + self.mini = None + self.closest = root.val + traverse(root) + return self.closest diff --git a/ProblemSolving/clumsyFactorial/clumsy.py b/ProblemSolving/clumsyFactorial/clumsy.py new file mode 100644 index 0000000..913c98c --- /dev/null +++ b/ProblemSolving/clumsyFactorial/clumsy.py @@ -0,0 +1,29 @@ +class Solution(object): + def clumsy(self, N): + """ + :type N: int + :rtype: int + """ + + # Logic 1: Using Eval() function to evaluate expression - 100 pass 25% faster + + # Operations + operation = ["*", "/", "+", "-"] + + # Initial expression + expression = str(N) + + # Control variables + op = 0 + i = N-1 + + # Loop to construct expression + while i > 0: + if op > 3: + op = 0 + expression += operation[op] + str(i) + op += 1 + i -= 1 + + # Return evaluated expression + return eval(expression) diff --git a/ProblemSolving/coinChange/coin.py b/ProblemSolving/coinChange/coin.py new file mode 100644 index 0000000..93876aa --- /dev/null +++ b/ProblemSolving/coinChange/coin.py @@ -0,0 +1,81 @@ +class Solution: + def coinChange(self, coins: List[int], amount: int) -> int: + + # Exploration: + # * Based on the problem of MINIMIZING number of coins, we go greedy to choose the highest coin value each time + # * Drawback on this would be, there might be one option which is not optimal which might succeed that wont be found if greedy approach is taken + # * Recurse as we have to iterate every time for each value and reuse the code + + # Logic 1 --> Brute Force --> Obvious time limit exceeded + """ + def coinChangeForValue(coins: List[int], amount: int, num_of_coins: int, selected: List[int]) -> int: + if amount > 0: + for change in coins: + if change <= amount: + coinChangeForValue(coins, amount-change, num_of_coins+1, selected+[change]) + else: + #print(amount, num_of_coins, selected) + if amount == 0: + #print(coins, amount, num_of_coins, selected) + if num_of_coins < self.optimal_choice: + self.optimal_choice = num_of_coins + return + + self.optimal_choice = float('inf') + coins = sorted(coins, reverse=True) + coinChangeForValue(coins, amount, 0, []) + if self.optimal_choice == float('inf'): + return -1 + else: + return self.optimal_choice + """ + + # Logic 2 --> Memoize the above - in progress + """ + def coinChangeForValue(coins: List[int], amount: int, num_of_coins: int) -> int: + print(amount, num_of_coins, self.memo) + if amount in self.memo: + coins = num_of_coins + self.memo[amount] + if coins < self.optimal: + self.optimal = coins + elif amount > 0: + for change in coins: + if change <= amount: + current_target = amount-change + num_of_coins += 1 + if current_target not in self.memo: + self.memo[current_target] = num_of_coins + coinChangeForValue(coins, current_target, num_of_coins) + else: + if amount == 0: + if num_of_coins < self.optimal: + self.optimal = num_if_coins + + self.memo = {} + self.optimal = float('inf') + coins = sorted(coins, reverse=True) + coinChangeForValue(coins, amount, 0) + if self.optimal == float('inf'): + return -1 + return self.optimal + """ + + # Logic 3: Bottom Up Approach + # * Calculate for all optimal subproblems + + # Create space for subproblems + dp = [float('inf')]*(amount + 1) # Initialize + + # Initial 0 value + dp[0] = 0 + + # Iterate coins + for change in coins: + # For each coin, iterate value until amount + for value in range(change, amount+1): + # Track min value + dp[value] = min(dp[value], dp[value-change]+1) + + #print(dp) + return dp[-1] if dp[-1] != float('inf') else -1 + diff --git a/ProblemSolving/combinationSum/sum.py b/ProblemSolving/combinationSum/sum.py index 738125e..a88c19d 100644 --- a/ProblemSolving/combinationSum/sum.py +++ b/ProblemSolving/combinationSum/sum.py @@ -1,3 +1,56 @@ +class Solution(object): + def combinationSum(self, candidates, target): + """ + :type candidates: List[int] + :type target: int + :rtype: List[List[int]] + """ + + + # Logic: This iterates through all combination, works 100% but 35ms fast only. + + # Itertools for using product, combinations or permutations + import itertools + + # Result array to hold all the valid combinations + result = [] + + # As repeated elements can be unlimited, we start the iteration with minimum element in the array that adds up to the target + mini = min(candidates) + n = target//mini + + # Using combinations with replacement --> to have all the combination of length r with repeated elements, and check if sum adds up to the target + for i in range(n, 0, -1): + for comb in itertools.combinations_with_replacement(candidates, r=i): + if sum(comb) == target: + result.append(comb) + return result + + + """ + # Another Logic with Recursive strategy + # Reference: https://leetcode.com/problems/combination-sum/discuss/232167/python-simple-backtracking + + result = [] + + def recursive_combinations(temp, index): + + if sum(temp) > target: + return + elif sum(temp) == target: + temp = sorted(temp) + if temp not in result: + result.append(temp) + return + + for i in range(index, len(candidates)): + recursive_combinations(temp+[candidates[i]], index) + + recursive_combinations([], 0) + return result + """ + +""" ### Pending... class Solution(object): @@ -57,7 +110,7 @@ def combinationSum(self, candidates, target): return result - +""" diff --git a/ProblemSolving/combinationSum/sum2.py b/ProblemSolving/combinationSum/sum2.py new file mode 100644 index 0000000..ea85f29 --- /dev/null +++ b/ProblemSolving/combinationSum/sum2.py @@ -0,0 +1,38 @@ +class Solution(object): + def combinationSum(self, candidates, target): + """ + :type candidates: List[int] + :type target: int + :rtype: List[List[int]] + """ + + """ + # Bruteforce + import itertools + result = set() + maxi = target//min(candidates) + #print(maxi) + for i in range(1, maxi+1): + for comb in itertools.product(candidates, repeat=i): + if sum(comb) == target: + comb = tuple(sorted(comb)) + result.add(comb) + return list(result) + """ + + def backtrack(result, temp, candidates, remain, start): + if remain < 0: + return + elif remain == 0: + result.append(temp) + return + else: + for i in range(start, len(candidates)): + backtrack(result, temp+[candidates[i]], candidates, remain-candidates[i], i) + + + candidates = sorted(candidates) + result = [] + backtrack(result, [], candidates, target, 0) + return result + diff --git a/ProblemSolving/combinations/combination.md b/ProblemSolving/combinations/combination.md new file mode 100644 index 0000000..f516ab4 --- /dev/null +++ b/ProblemSolving/combinations/combination.md @@ -0,0 +1,80 @@ + +1) A bit hacky solution using inbuilt function `itertools` +``` +class Solution(object): + def combine(self, n, k): + """ + :type n: int + :type k: int + :rtype: List[List[int]] + """ + + # Logic: Use Python Itertools - 120ms 99% faster. + # * K numbers ==> repeat=2 + # * 1..N is the limit ==> range(1,n) + + import itertools + result = [] + + for comb in itertools.combinations(range(1,n+1), r=k): + result.append(comb) + + return result +``` + +2) Same logic above implemented as a single line solution +``` +return [comb for comb in itertools.combinations(range(1,n+1), r=k)] +``` + +3) Recursive with comments on why? +``` +class Solution(object): + def combine(self, n, k): + """ + :type n: int + :type k: int + :rtype: List[List[int]] + """ + """ + # This is the sole idea of a brute force solution: (particularly when k=2) + + # This would be the general brute force logic for k=2 ==> 2 for loops... + # * K input will contain k for loops --> use recursive function to for loop k times... + + # Brute force solution - worst case sceanrio + result = [] + for i in range(1, n+1): + for j in range(1, n+1): + if i != j: + if sorted([i,j]) not in result: + result.append([i,j]) + return result + """ + + # 100 pass 756ms + # Implementing the same brute force solution (reference to the logic above..) + result = [] + + # A loop to carry forward the array constructed and next index to operate + def k_times_for_loops(temp_array, index): + + # debug + #print temp_array + + # Recursive function: First create a decision when to exit... + # what should be the result, return once you get the result + if len(temp_array) >= k: + # Avoid duplicates and same element arrays + if sorted(temp_array) not in result and len(set(temp_array)) == k: + result.append(temp_array) + return + + # Recurse with for loop k times, add the current index to list and operate on next index + for i in range(index, n+1): + k_times_for_loops(temp_array+[i], i+1) + + # Function trigger + k_times_for_loops([], 1) + return result +``` diff --git a/ProblemSolving/combinations/combination.py b/ProblemSolving/combinations/combination.py new file mode 100644 index 0000000..1203ecc --- /dev/null +++ b/ProblemSolving/combinations/combination.py @@ -0,0 +1,70 @@ +class Solution(object): + def combine(self, n, k): + """ + :type n: int + :type k: int + :rtype: List[List[int]] + """ + + """ + # Logic: Use Python Itertools - 120ms 99% faster. + # * K numbers ==> repeat=2 + # * 1..N is the limit ==> range(1,n) + + # Single line solution would be: `return [comb for comb in itertools.combinations(range(1,n+1), r=k)]` + + import itertools + result = [] + + for comb in itertools.combinations(range(1,n+1), r=k): + result.append(comb) + + return result + """ + + + """ + # This is the sole idea of a brute force solution: (particularly when k=2) + + # This would be the general brute force logic for k=2 ==> 2 for loops... + # * K input will contain k for loops --> use recursive function to for loop k times... + + # Brute force solution - worst case sceanrio + result = [] + for i in range(1, n+1): + for j in range(1, n+1): + if i != j: + if sorted([i,j]) not in result: + result.append([i,j]) + return result + """ + + # 100 pass 756ms + # Implementing the same brute force solution (reference to the logic above..) + result = [] + + # A loop to carry forward the array constructed and next index to operate + def k_times_for_loops(temp_array, index): + + # debug + #print temp_array + + # Recursive function: First create a decision when to exit... + # what should be the result, return once you get the result + if len(temp_array) >= k: + # Avoid duplicates and same element arrays + if sorted(temp_array) not in result and len(set(temp_array)) == k: + result.append(temp_array) + return + + # Recurse with for loop k times, add the current index to list and operate on next index + for i in range(index, n+1): + k_times_for_loops(temp_array+[i], i+1) + + # Function trigger + k_times_for_loops([], 1) + return result + + + + diff --git a/ProblemSolving/compareStringsByFrequency/compare.py b/ProblemSolving/compareStringsByFrequency/compare.py new file mode 100644 index 0000000..55ec29d --- /dev/null +++ b/ProblemSolving/compareStringsByFrequency/compare.py @@ -0,0 +1,34 @@ +class Solution(object): + def numSmallerByFrequency(self, queries, words): + """ + :type queries: List[str] + :type words: List[str] + :rtype: List[int] + """ + + def strength_of_string(word): + word = sorted(word) + temp = word[0] + strength = 1 + for char in word[1:]: + if char == temp: + strength += 1 + else: + break + return strength + + queries_strength = [] + for w in queries: + queries_strength.append(strength_of_string(w)) + + result = [0 for i in range(len(queries_strength))] + for w in words: + words_strength = strength_of_string(w) + i = 0 + while i < len(queries_strength): + if words_strength > queries_strength[i]: + result[i] += 1 + i += 1 + return result + + diff --git a/ProblemSolving/complementOfBase10Integer/comp.py b/ProblemSolving/complementOfBase10Integer/comp.py new file mode 100644 index 0000000..5a8dc60 --- /dev/null +++ b/ProblemSolving/complementOfBase10Integer/comp.py @@ -0,0 +1,16 @@ +class Solution(object): + def bitwiseComplement(self, N): + """ + :type N: int + :rtype: int + """ + + # Logic1: With String Replacement (Hacky String Trick) + # --> 28ms (100%) faster and 100% less memory + binary = bin(N)[2:] + binary = binary.replace("0", "Z") + binary = binary.replace("1", "0") + binary = binary.replace("Z", "1") + return int(binary, 2) + + # Logic2: Update pending... diff --git a/ProblemSolving/confusingNumber/conf.py b/ProblemSolving/confusingNumber/conf.py new file mode 100644 index 0000000..1075c9c --- /dev/null +++ b/ProblemSolving/confusingNumber/conf.py @@ -0,0 +1,49 @@ +# Logic 1: Integer based with no type conversion - 96.56% faster +# * create a new number and check, also eliminate if denylist exists + +class Solution: + def confusingNumber(self, N: int) -> bool: + old = N + new = 0 + confusing = { + 0: 0, + 1: 1, + 9: 6, + 6: 9, + 8: 8 + } + while N: + current = N%10 + if current in set([2,3,4,5,7]): + return False + else: + new = new*10 + confusing[current] + N = N//10 + print(old, new) + if old != new: + return True + else: + return False + + +# Try without creating the new number --> Fail pending... +""" +class Solution: + def confusingNumber(self, N: int) -> bool: + same_chances = set([0,1,8]) + count = 0 + digits = 0 + while N: + current = N%10 + if current in set([2,3,4,5,7]): + return False + elif current in same_chances: + count += 1 + digits += 1 + N = N//10 + if count == digits: + return False + return True +""" + + diff --git a/ProblemSolving/constructBinarySearchTreeFromPreOrderTraversal/cons.py b/ProblemSolving/constructBinarySearchTreeFromPreOrderTraversal/cons.py new file mode 100644 index 0000000..c9ddc02 --- /dev/null +++ b/ProblemSolving/constructBinarySearchTreeFromPreOrderTraversal/cons.py @@ -0,0 +1,75 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def bstFromPreorder(self, preorder): + """ + :type preorder: List[int] + :rtype: TreeNode + """ + + # Logic 1: 100% pass 100% time + + # Create a root prior + root = TreeNode(preorder.pop(0)) + # Track all the parents as we visit + parents = [root] + # Iterate all the nodes in preorder + while preorder: + # Current value from preorder and its node representation + current = preorder.pop(0) + current_node = TreeNode(current) + # If current is lesser, add to the left of the node + if current < parents[-1].val: + parents[-1].left = current_node + else: + # When the current is greater then remove all the nodes lesser than this node + while parents and parents[-1].val < current: + last_node = parents.pop() + # The last nodes right would be this + last_node.right = current_node + # Append the node to parents list + parents.append(current_node) + return root + + + + + """ + # Iterative method + root = preorder.pop(0) + parent = current_node = None + while preorder: + if current_node: + parent = current_node + current_node = TreeNode(preorder.pop(0)) + if current_node.val < root.val: + root.left = current_node + root = current_node + elif parent and current_node.val > parent.val: + root = parent + else: + root.right = current_node + root = current_node + + + def construct_tree(root_node, parent): + + if preorder: + current_node = TreeNode(preorder.pop(0)) + if current_node.val < root_node: + root_node.left = current_node + elif parent and root_node.val > parent.val: + return + else: + return + + root = preorder.pop(0) + construct_tree(root, preorder) + + return root + """ diff --git a/ProblemSolving/constructBinaryTreeFromPreOrderAndPostOrder/construct.py b/ProblemSolving/constructBinaryTreeFromPreOrderAndPostOrder/construct.py new file mode 100644 index 0000000..4d5a702 --- /dev/null +++ b/ProblemSolving/constructBinaryTreeFromPreOrderAndPostOrder/construct.py @@ -0,0 +1,108 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def constructFromPrePost(self, pre, post): + """ + :type pre: List[int] + :type post: List[int] + :rtype: TreeNode + """ + + # Gathering some known properties and findings: + # PreOrder + # * has root at the beginning [Root, Left, Right] + # * Ends with the right most node of the tree + # PostOrder + # * has root at the end [Left, Right, Root] + # * Starts with the left most node of the tree + + # Root + root = TreeNode(pre.pop(0)) + head = post.pop(-1) + + # To help us traverse through the tree + stack = [root] + + + # The learnings until now, appending to the list above: + # * Pre ==> Root, L, R ==> If we find a root, then the subsequent nodes are left and right + # * Post ==> L, R, Root ==> By ensuring we hit a root we can be confident that the all nodes of that subtree have been exercised + # * This seems to be an elegant approach of the same understanding. Using as reference... + + pnode = 0 + + for node in pre: + + current_node = TreeNode(node) + + # Ensure, if the root is reached in post order to confirm the subtree has been exercised + while stack[-1].val == post[pnode]: + stack.pop() + pnode += 1 + + # If there is no left, add left + if not stack[-1].left: + stack[-1].left = current_node + elif not stack[-1].right: + stack[-1].right= current_node + + # Each node can be a root in pre, append to stack to traverse + stack.append(current_node) + + return root + + """ + # We should leverage some logic to iteratively perform the node addition rather than following the steps literally + # * This works by literally following the logic, more better of the same implementation above... + + # pre and post ==> Both are equal number of nodes as guaranteed the answer exists + while pre and post: + + # First, reach the left mode node + left_most_node = post.pop(0) + while pre[0] != left_most_node: + root.left = TreeNode(pre.pop(0)) + root = root.left + stack.append(root) + # Add the left most node + root.left = TreeNode(pre.pop(0)) + + # Second, traverse back up to the root adding the right nodes + # * where to stop ==> The left subtree ends when upper most left child is reached... + while stack and post[0] != stack[0].val: + parent = stack.pop(-1) + if post[0] == parent.val: + post.pop(0) + elif post[0] == parent.left.val: + post.pop(0) + else: + parent.right = post.pop(0) + + # Upper most left node + if stack: + post.pop(0) + # reset root + root = head + # Left subtree is done! + + # Right subtree + root.right = post.pop(-1) + """ + + + + + + + + + + + + + diff --git a/ProblemSolving/containerWithMostWater/con2.py b/ProblemSolving/containerWithMostWater/con2.py new file mode 100644 index 0000000..843f9d7 --- /dev/null +++ b/ProblemSolving/containerWithMostWater/con2.py @@ -0,0 +1,35 @@ +class Solution: + def maxArea(self, height: List[int]) -> int: + + # Logic 1: Bruteforce with O(N)**2 --> works but time limit exceeded + """ + maxi = 0 + for i in range(len(height)): + for j in range(i+1, len(height)): + h = min(height[i], height[j]) + l = j-i + a = h*l + if a > maxi: + maxi = a + + return maxi + """ + + # Logic 2: 2 pointer method - all pass + left = 0 + right = len(height)-1 + maxi = 0 + + while left < right: + h = min(height[left], height[right]) + l = right-left + a = h*l + if a > maxi: + maxi = a + if height[left] > height[right]: + right -= 1 + else: + left += 1 + #print(height[left], height[right], a) + + return maxi diff --git a/ProblemSolving/containsDuplicates/dup2.py b/ProblemSolving/containsDuplicates/dup2.py new file mode 100644 index 0000000..b80cbac --- /dev/null +++ b/ProblemSolving/containsDuplicates/dup2.py @@ -0,0 +1,13 @@ +class Solution(object): + def containsDuplicate(self, nums): + """ + :type nums: List[int] + :rtype: bool + """ + import collections + freq = list(set(collections.Counter(nums).values())) + if not freq or (len(freq) == 1 and freq[0] == 1): + return False + else: + return True + diff --git a/ProblemSolving/contiguousArray/count.py b/ProblemSolving/contiguousArray/count.py new file mode 100644 index 0000000..0396f27 --- /dev/null +++ b/ProblemSolving/contiguousArray/count.py @@ -0,0 +1,34 @@ +class Solution(object): + def findMaxLength(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + + # Logic 2: With Dict to track counting - 86% faster + prefix_count = {0:-1} + maxi, count = 0, 0 + for i,v in enumerate(nums): # Step1: iterate by index and value + count += (-1 if v == 0 else 1) # Make count 1 for 1 and -1 for 0 + if count in prefix_count: + maxi = max(maxi, i-prefix_count[count]) + else: + prefix_count[count] = i # Store immediate index after cont array + return maxi + + # Logic 1: O(N) Loop Iteration + # * This does not work when position or contiguous rule occur, otherwise for any arrangement might work + """ + zero = 0 + one = 0 + maxi = 0 + for i in range(len(nums)): + if nums[i] == 0: + zero += 1 + else: + one += 1 + maxi = max(maxi, min(one,zero)) + print(one, zero, maxi) + return maxi*2 + """ + diff --git a/ProblemSolving/convertSortedArrayToBinarySearchTree/convert.py b/ProblemSolving/convertSortedArrayToBinarySearchTree/convert.py new file mode 100644 index 0000000..295a369 --- /dev/null +++ b/ProblemSolving/convertSortedArrayToBinarySearchTree/convert.py @@ -0,0 +1,22 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def sortedArrayToBST(self, nums): + """ + :type nums: List[int] + :rtype: TreeNode + """ + + if not nums: + return + mid = len(nums)//2 + root = TreeNode(nums[mid]) + root.left = self.sortedArrayToBST(nums[:mid]) + root.right = self.sortedArrayToBST(nums[mid+1:]) + return root + diff --git a/ProblemSolving/convertSortedArrayToBinarySearchTree/convert2.py b/ProblemSolving/convertSortedArrayToBinarySearchTree/convert2.py new file mode 100644 index 0000000..1d462c6 --- /dev/null +++ b/ProblemSolving/convertSortedArrayToBinarySearchTree/convert2.py @@ -0,0 +1,26 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right +class Solution: + def sortedArrayToBST(self, nums: List[int]) -> Optional[TreeNode]: + + def divide(arr): + + if not arr: + return + + mid = len(arr)//2 + left = mid-1 + right = mid+1 + + root = TreeNode(arr[mid]) + + root.left = divide(arr[:mid]) + root.right = divide(arr[mid+1:]) + + return root + + return divide(nums) diff --git a/ProblemSolving/copyListWithRandomPointer/copy.py b/ProblemSolving/copyListWithRandomPointer/copy.py new file mode 100644 index 0000000..6d344f7 --- /dev/null +++ b/ProblemSolving/copyListWithRandomPointer/copy.py @@ -0,0 +1,46 @@ +""" +# Definition for a Node. +class Node: + def __init__(self, x: int, next: 'Node' = None, random: 'Node' = None): + self.val = int(x) + self.next = next + self.random = random +""" + +class Solution: + def copyRandomList(self, head: 'Optional[Node]') -> 'Optional[Node]': + + if not head: + return + + # relate existing node to new nodes for deep copy + node_to_new_nodes = {} + traverse = head + while traverse: + # current + new_node = Node(traverse.val) + node_to_new_nodes[traverse] = new_node + # next + if traverse.next and traverse.next not in node_to_new_nodes: + nxt_node = Node(traverse.next.val) + node_to_new_nodes[traverse.next] = nxt_node + # random + if traverse.random and traverse.random not in node_to_new_nodes: + rnd_node = Node(traverse.random.val) + node_to_new_nodes[traverse.random] = rnd_node + + traverse = traverse.next + + traverse = head + copy = node_to_new_nodes[traverse] + result = copy + while traverse: + if traverse.next: + copy.next = node_to_new_nodes[traverse.next] + if traverse.random: + copy.random = node_to_new_nodes[traverse.random] + copy = copy.next + traverse = traverse.next + + return result + diff --git a/ProblemSolving/corporateFlightBookings/flights.py b/ProblemSolving/corporateFlightBookings/flights.py new file mode 100644 index 0000000..268c035 --- /dev/null +++ b/ProblemSolving/corporateFlightBookings/flights.py @@ -0,0 +1,36 @@ +class Solution(object): + def corpFlightBookings(self, bookings, n): + """ + :type bookings: List[List[int]] + :type n: int + :rtype: List[int] + """ + + # Logic 2: Do not go over the range og flight bookings, Instead + # * Increment seats at the start of the range say i + # * Decrement these seats at after j as we need to reduce them (j+1) + # Idea from https://leetcode.com/problems/corporate-flight-bookings/discuss/328856/JavaC%2B%2BPython-Straight-Forward-Solution + + # Hold all the flight bookings + flights = [0]*(n+1) + # Iterate booking + for booking in bookings: + # At the range start, Increment num of seats + flights[booking[0]-1] += booking[2] + # Remove thos seats at j+1 + flights[booking[1]] -= booking[2] + # Correct the range with one iteration + # * Add previous to the current booking + for i in range(1, n): + flights[i] += flights[i-1] + return flights[:-1] + + + # Logic 1: Naive method of Iteration - 99 pass ( time limit exceeded on the scale test case) + """ + flights = [0]*(n+1) + for booking in bookings: + for flight in range(booking[0], booking[1]+1): + flights[flight] += booking[2] + return flights[1:] + """ diff --git a/ProblemSolving/countAndSay/count.py b/ProblemSolving/countAndSay/count.py index ca094c5..6184fd6 100644 --- a/ProblemSolving/countAndSay/count.py +++ b/ProblemSolving/countAndSay/count.py @@ -116,4 +116,26 @@ def countAndSay(self, n): return result """ """ - + +""" +# Logic 2: Memoize and Perform the Iteration until length -->100 pass 73% faster +class Solution: + def countAndSay(self, n: int) -> str: + if n == 0: + return "" + memo = ["1"] + for c in range(1, n+1): + target = memo[-1] + word = "" + i = 0 + while i < len(target): + ch = target[i] + j = 1 + i += 1 + while i < len(target) and target[i] == ch: + i += 1 + j += 1 + word += str(j) + ch + memo.append(word) + return memo[-2] +""" diff --git a/ProblemSolving/countAndSay/count2.py b/ProblemSolving/countAndSay/count2.py new file mode 100644 index 0000000..d5575ba --- /dev/null +++ b/ProblemSolving/countAndSay/count2.py @@ -0,0 +1,31 @@ +class Solution: + def countAndSay(self, n: int) -> str: + + def say(nStr): + + ns = list(nStr) + stack = [] + saying = "" + + while ns: + #print(ns) + curr = ns.pop(0) + if stack and stack[-1] == curr: + stack.append(curr) + else: + if stack: + saying += str(len(stack))+stack[-1] + stack = [curr] + + if stack: + saying += str(len(stack))+stack[-1] + + return saying + + self.memo = {1:"1"} + for i in range(2, n+1): + result = say(self.memo[i-1]) + self.memo[i] = result + + #print(self.memo) + return self.memo[n] diff --git a/ProblemSolving/countLargestGroup/count.go b/ProblemSolving/countLargestGroup/count.go new file mode 100644 index 0000000..1709272 --- /dev/null +++ b/ProblemSolving/countLargestGroup/count.go @@ -0,0 +1,32 @@ +// Logic 1: Naive way of using map and iteration with Sum of digits helper function - 100 pass - 60% faster +func sumOfDigits(n int) int { + total := 0 + for n > 0 { + total += n%10 + n = n/10 + } + return total +} + +func countLargestGroup(n int) int { + // Track max group size + max_group_size := 0 + // Map Sum to Digits + dict := make(map[int][]int) + // Iterate n + for i:=1; i<=n; i++ { + sumOfDigit := sumOfDigits(i) + dict[sumOfDigit] = append(dict[sumOfDigit], i) + if len(dict[sumOfDigit]) > max_group_size { + max_group_size = len(dict[sumOfDigit]) + } + } + result := 0 + for _, value := range dict { + if len(value) == max_group_size { + result += 1 + } + } + //fmt.Println(dict, max_group_size) + return result +} diff --git a/ProblemSolving/countNumberOfConsistentStrings/count.py b/ProblemSolving/countNumberOfConsistentStrings/count.py new file mode 100644 index 0000000..1b0a2c2 --- /dev/null +++ b/ProblemSolving/countNumberOfConsistentStrings/count.py @@ -0,0 +1,14 @@ +class Solution: + def countConsistentStrings(self, allowed: str, words: List[str]) -> int: + import collections + consistent = 0 + allowd = collections.Counter(allowed) + for w in words: + consist = True + for c in w: + if c not in allowd: + consist = False + break + if consist: + consistent += 1 + return consistent diff --git a/ProblemSolving/countNumberOfTeams/count.py b/ProblemSolving/countNumberOfTeams/count.py new file mode 100644 index 0000000..41fa1ee --- /dev/null +++ b/ProblemSolving/countNumberOfTeams/count.py @@ -0,0 +1,38 @@ +class Solution(object): + def numTeams(self, rating): + """ + :type rating: List[int] + :rtype: int + """ + + + # Logic 1: BackTrack Logic to exit when condition is not satisfied - 100 pass 5% faster + + # Recursive backtrack + def backtrack(current_team, remaining): + # Exit criteria for team of size 3 + if len(current_team) == 3: + self.teams.append(current_team) + else: + # Create team + for i in range(len(remaining)): + # We cant decide when team size if only 1 so just add + if len(current_team) == 1: + backtrack(current_team + [remaining[i]], remaining[i+1:]) + else: + # Find if the logic is decreasing or increasing rating + validate = current_team[-2] > current_team[-1] + # Add next member to team based on increasing or decreasing criteria + if validate and remaining[i] < current_team[-1]: + backtrack(current_team + [remaining[i]], remaining[i+1:]) + elif not validate and remaining[i] > current_team[-1]: + backtrack(current_team + [remaining[i]], remaining[i+1:]) + return + + self.teams = [] + # Usecase for every new member added to the team as the first person + for i in range(len(rating)): + backtrack([rating[i]], rating[i+1:]) + #print(self.teams) + return len(self.teams) + diff --git a/ProblemSolving/countNumbersSmallerThanCurrentNumber/count.py b/ProblemSolving/countNumbersSmallerThanCurrentNumber/count.py new file mode 100644 index 0000000..4b4de7d --- /dev/null +++ b/ProblemSolving/countNumbersSmallerThanCurrentNumber/count.py @@ -0,0 +1,12 @@ +class Solution(object): + def smallerNumbersThanCurrent(self, nums): + """ + :type nums: List[int] + :rtype: List[int] + """ + + # Logic 1: Numbers smaller than current number - 100 pass 64% faster + sortNum = sorted(nums) + for i in range(len(nums)): + nums[i] = sortNum.index(nums[i]) + return nums diff --git a/ProblemSolving/countOddNumbersInAnIntervalRange/count.py b/ProblemSolving/countOddNumbersInAnIntervalRange/count.py new file mode 100644 index 0000000..1ff89ac --- /dev/null +++ b/ProblemSolving/countOddNumbersInAnIntervalRange/count.py @@ -0,0 +1,13 @@ +class Solution: + def countOdds(self, low: int, high: int) -> int: + # Logic 1: Math way - 100 pass 94% + odds = 0 + if (low%2 != 0): # if low is odd + odds += 1 + if (high%2 != 0): # is high is odd + odds += 1 + if odds == 0 or odds < 2: # anyone or none are odd we do diff//2 + odds += (high - low)//2 + elif odds == 2: # both low,high are odds then we take diff-1//2 + odds += (high - low - 1)//2 + return odds diff --git a/ProblemSolving/countOfMatchesInTournament/count.py b/ProblemSolving/countOfMatchesInTournament/count.py new file mode 100644 index 0000000..8de7d50 --- /dev/null +++ b/ProblemSolving/countOfMatchesInTournament/count.py @@ -0,0 +1,29 @@ +""" +# Logic 1: Naive iteration backwards from n with even/odd logic --> 82% faster +class Solution: + def numberOfMatches(self, n: int) -> int: + match = 0 + advance = 0 + while n+advance != 1: + print(n, match, advance) + n += advance + advance = 0 + if n%2 != 0: + advance += 1 + n -= 1 + n -= n//2 + match += n + return match +""" +# Logic 2: use modulo and division to make the loop simpler --> 95 % faster +class Solution: + def numberOfMatches(self, n: int) -> int: + matches = 0 + advance = 0 + while n+advance != 1: + #print(n, matches, advance) + n += advance + advance = n%2 + n = n//2 + matches += n + return matches diff --git a/ProblemSolving/countPrimes/count2.py b/ProblemSolving/countPrimes/count2.py new file mode 100644 index 0000000..d499b15 --- /dev/null +++ b/ProblemSolving/countPrimes/count2.py @@ -0,0 +1,41 @@ +class Solution(object): + def countPrimes(self, n): + """ + :type n: int + :rtype: int + """ + + # Logic 2: + memo = [0]*n + count = 0 + if n > 2: + count += 1 + for i in range(3, n, 2): + if memo[i] == 0: + count += 1 + j = 3 + while i*j < n: + memo[i*j] = 1 + j += 1 + return count + + # Logic 1: + """ + def is_prime(a): + import math + for i in range(3, int(math.sqrt(a))+1, 2): + if a%i == 0: + return False + return True + + count = 0 + if n <= 2: + return 0 + elif n < 3: + return 1 + count = 1 + for i in range(3, n, 2): + if is_prime(i): + count += 1 + return count + """ diff --git a/ProblemSolving/countSubstringsWithOnlyOneDistinctLetter/count.py b/ProblemSolving/countSubstringsWithOnlyOneDistinctLetter/count.py new file mode 100644 index 0000000..d0ec431 --- /dev/null +++ b/ProblemSolving/countSubstringsWithOnlyOneDistinctLetter/count.py @@ -0,0 +1,18 @@ +# Logic 1: Find the number of substring with ( sum of N ) for each disinct substrings - 100 pass - 7% pass +class Solution: + def sumOfN(self, n): + return (n*(n+1))//2 + + def countLetters(self, S: str) -> int: + distinct = 0 + substring = [] + for i in range(len(S)): + if len(set(substring+[S[i]])) > 1: + n = len(substring) + distinct += self.sumOfN(n) + substring = [] + substring.append(S[i]) + if substring: + n = len(substring) + distinct += self.sumOfN(n) + return distinct diff --git a/ProblemSolving/countVowelStrings/count.py b/ProblemSolving/countVowelStrings/count.py new file mode 100644 index 0000000..d8811d1 --- /dev/null +++ b/ProblemSolving/countVowelStrings/count.py @@ -0,0 +1,39 @@ +class Solution: + def countVowelStrings(self, n: int) -> int: + + # Logic 1: Backtrack recursively to construct string --> 9506 ms, faster than 5.08% of Python3 --> 100 pass + self.vowels = ["a", "e", "i", "o", "u"] + self.strings = [] + self.nums = 0 + + def backtrack(current, remaining): + #print(current) + + if remaining == 0: + self.strings.append(current) + self.nums += 1 + return + + for v in self.vowels: + if current and v < current[-1]: + continue + backtrack(current + v, remaining-1) + return + + backtrack("", n) + #print(self.strings) + + return self.nums + + # Logic 2: Mathematical combination formula [k+n-1]!//(k-1)!n! + """ + # general combination: 2 --> _ _ --> [a,e,i,o,u] --> 5*5 --> 25 + # lexi combination: 2 --> + # a = 1 x 5 + # e = 1 x 4 + # i = 1 x 3 + # o = 1 x 2 + # u = 1 x 1 + # ==> 15 + return (n+4)*(n+3)*(n+2)*(n+1)//24 + """ diff --git a/ProblemSolving/countingBits/count.py b/ProblemSolving/countingBits/count.py new file mode 100644 index 0000000..52245f1 --- /dev/null +++ b/ProblemSolving/countingBits/count.py @@ -0,0 +1,67 @@ +class Solution(object): + def countBits(self, num): + """ + :type num: int + :rtype: List[int] + """ + + # All logic below are 100 pass (variation in timing) + + # Modified logic 2 with better intelligence - 48% + # Ref: https://leetcode.com/problems/counting-bits/discuss/248745/c%2B%2B-100-52ms + + result = [0] + remainder = 1 + for i in range(1, num+1): + # This checkpoints for all 2*remainder which is 2, 4, 8 + if i == 2*remainder: + remainder = 2*remainder + result.append(result[i-remainder]+1) + return result + + # Logic3 - 55% faster - another logic more mathematical + # Reference: https://leetcode.com/problems/counting-bits/discuss/246572/My-python-solution + result = [0]*(num+1) + for i in range(1,num+1): + result[i] = result[i//2] + i%2 + return result + + + """ + # Logic 2: Fails for 10, 11, 12, 13 + # * Use the design of binary numbers to make it faster + # * For every even number visited, there is no num of ones change - 2 (010) + # * For every odd number visited, there is a num of ones change - 3 (011) + # * Also, at each digit increase from 2, 4, 8 the number of digits in a binary are constant until that number 2 (010, 011), 4 (100, 101, 110, 111), 8 (1000, 1001, 1010, 1011, 1100, 1101, 1110, 1111) + result = [0, 1] + remainder = 0 + for i in range(2, num+1): + if i%2 != 0: + result.append(result[-1]+1) + else: + if remainder == 0: + remainder = i + result.append(1) + else: + result.append(result[-1]) + print i, result, remainder + remainder -= 1 + return result + """ + + # Logic 1: 100 pass but Only 5% faster + # * use collections to count + # * O(N) iteration and binary number calculation for each number visited in a loop... + """ + import collections + result = [] + for i in range(num+1): + counts = collections.Counter(bin(i)[2:]) + if "1" in counts: + result.append(counts["1"]) + else: + result.append(0) + return result + """ + + diff --git a/ProblemSolving/countingElements/count.py b/ProblemSolving/countingElements/count.py new file mode 100644 index 0000000..2d6c1f4 --- /dev/null +++ b/ProblemSolving/countingElements/count.py @@ -0,0 +1,16 @@ +class Solution(object): + def countElements(self, arr): + """ + :type arr: List[int] + :rtype: int + """ + + import collections + freq = collections.Counter(arr) + counts = 0 + for k in freq.keys(): # Iterate over all elements + if k+1 in freq: # If i+1 exists in array + max_diff = freq[k] + counts += max_diff # Increment count + freq[k] -= max_diff # Update freq + return counts diff --git a/ProblemSolving/courseSchedule/course.py b/ProblemSolving/courseSchedule/course.py new file mode 100644 index 0000000..281a103 --- /dev/null +++ b/ProblemSolving/courseSchedule/course.py @@ -0,0 +1,84 @@ +class Solution(object): + def canFinish(self, numCourses, prerequisites): + """ + :type numCourses: int + :type prerequisites: List[List[int]] + :rtype: bool + """ + + # Initialize a graph and visited array + graph = [[] for x in xrange(numCourses)] + visited_vertices = [0]*numCourses + + # Create a graph + for pair in prerequisites: + curr_course = pair[0] + pre_req = pair[1] + graph[curr_course].append(pre_req) + visited_vertices[pre_req] += 1 + + # Get all the root nodes or nodes with are starting/end point + possible_start_end_nodes = [] + for node in range(numCourses): + if visited_vertices[node] == 0: + possible_start_end_nodes.append(node) + + # Iterate all possible start and end nodes + for node in possible_start_end_nodes: + for pre_req in graph[node]: + visited_vertices[pre_req] -= 1 + if visited_vertices[pre_req] == 0: + possible_start_end_nodes.append(pre_req) + print(possible_start_end_nodes, graph, visited_vertices) + return len(possible_start_end_nodes) == numCourses + + """ + # Initialize a graph and visited array + graph = [[] for x in xrange(numCourses)] + visited_vertices = [0]*numCourses + + + # Recursively progress through the graph visiting all the nodes once + def traverse_graph(node, path): + # Recursively iterate the pre_req + visited_vertices[node] = 1 + if node not in path: + for pre_req in graph[node]: + if visited_vertices[pre_req] == 0: + traverse_graph(pre_req, path) + visited_vertices[pre_req] = 1 + path.append(node) + + + if prerequisites == []: + return True + + # Create a graph + for pair in prerequisites: + curr_course = pair[0] + pre_req = pair[1] + #print(graph, curr_course, pre_req) + graph[curr_course].append(pre_req) + visited_vertices[pre_req] += 1 + + + result = [] + max_path = 0 + for course in range(len(graph)): + route = [] + traverse_graph(course, route) + print(route, visited_vertices, course, result) + if len(route) > max_path: + max_path = len(route) + result = [route] + elif len(route) == max_path: + if route[::-1] in result: + return False + result.append(route) + if result: + return True + return False + """ + + + diff --git a/ProblemSolving/courseSchedule/course2.py b/ProblemSolving/courseSchedule/course2.py new file mode 100644 index 0000000..c9bcf41 --- /dev/null +++ b/ProblemSolving/courseSchedule/course2.py @@ -0,0 +1,51 @@ +# Topo Sort +class Solution: + def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool: + + graph = {} + ingress = {} + for i in range(len(prerequisites)): + end = prerequisites[i][0] + start = prerequisites[i][1] + + if start not in graph: + graph[start] = [] + graph[start].append(end) + + if end not in graph: + graph[end] = [] + + if start not in ingress: + ingress[start] = 0 + if end not in ingress: + ingress[end] = 0 + ingress[end] += 1 + + process_queue = [] + for i, val in ingress.items(): + if val == 0: + process_queue.append((i, val)) + + order = [] + while process_queue: + curri, currv = process_queue[0] + if len(process_queue) > 1: + process_queue = process_queue[1:] + else: + process_queue = [] + + if currv == 0: + order.append(curri) + + for nxt in graph[curri]: + ingress[nxt] -= 1 + if ingress[nxt] == 0: + process_queue.append((nxt, 0)) + + if len(order) > len(graph): + return False + + if len(order) == len(graph): + return True + + return False diff --git a/ProblemSolving/courseScheduleII/course.py b/ProblemSolving/courseScheduleII/course.py new file mode 100644 index 0000000..ba94c99 --- /dev/null +++ b/ProblemSolving/courseScheduleII/course.py @@ -0,0 +1,54 @@ +class Solution(object): + def findOrder(self, numCourses, prerequisites): + """ + :type numCourses: int + :type prerequisites: List[List[int]] + :rtype: List[int] + """ + + # Iterative method + + # Null prereq + if not prerequisites: + return range(numCourses) + + # 1. Initialize a graph with schema graph[prereq], graph[dependency] + graph = {} + + # 2. Build dictionary:graph of relationships + for prereq in prerequisites: + course = prereq[1] + req = prereq[0] + # Update prereq + if course not in graph: + graph[course] = {"dependent":[], "dependency": 0} + graph[course]["dependent"].append(req) + # Update dependency + if req not in graph: + graph[req] = {"dependent":[], "dependency":0} + graph[req]["dependency"] += 1 + + # 3. Get all the non depedent nodes + dependency_satisfied_nodes = [] + for node in range(numCourses): + if node not in graph: + graph[node] = {"dependent":[], "dependency":0} + dependency_satisfied_nodes.append(node) + elif graph[node]["dependency"] == 0: + dependency_satisfied_nodes.append(node) + + print graph, dependency_satisfied_nodes + + # 4. Iterate to satisfy and add all nodes + for node in dependency_satisfied_nodes: + for req in graph[node]["dependent"]: + graph[req]["dependency"] -= 1 + if graph[req]["dependency"] == 0: + dependency_satisfied_nodes.append(req) + + print(dependency_satisfied_nodes) + if len(dependency_satisfied_nodes) == numCourses: + return dependency_satisfied_nodes + else: + return [] + diff --git a/ProblemSolving/cousinsInBinaryTree/cousins.py b/ProblemSolving/cousinsInBinaryTree/cousins.py new file mode 100644 index 0000000..1ed6cc4 --- /dev/null +++ b/ProblemSolving/cousinsInBinaryTree/cousins.py @@ -0,0 +1,47 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def isCousins(self, root, x, y): + """ + :type root: TreeNode + :type x: int + :type y: int + :rtype: bool + """ + + # Iterative method - 100 pass 100% faster + + # * Level order search -> Find if they are cousins + stack = [root] + result = [] + + while stack: + n = len(stack) + result.append([]) + while n > 0: + current_node = stack.pop(0) + result[-1].append(current_node.val) + left = right = 0 + if current_node.left: + left = current_node.left.val + stack.append(current_node.left) + if current_node.right: + right = current_node.right.val + stack.append(current_node.right) + if left > 0 and right > 0: + if (left == x and right == y) or (left == y and right == x): + return False + n -= 1 + + for level in result: + if x in level and y in level: + return True + return False + + + diff --git a/ProblemSolving/crawlerLogFolder/crawler.py b/ProblemSolving/crawlerLogFolder/crawler.py new file mode 100644 index 0000000..65ccc01 --- /dev/null +++ b/ProblemSolving/crawlerLogFolder/crawler.py @@ -0,0 +1,28 @@ +class Solution: + def minOperations(self, logs: List[str]) -> int: + + level = 0 # at main level + dir_hierarchy = ["main"] # starting from current directory + + while logs: + + current_op = logs.pop(0) + + if current_op == "../": + if level > 0: + level -= 1 + if len(dir_hierarchy) > 1: + dir_hierarchy.pop() + + elif current_op == "./": + continue # remain in the folder means no change in levels + + else: # increase level wrt child dir --> no need to check for existence based on info in Q + + current_op = current_op.strip("/") + level += 1 + dir_hierarchy.append(current_op) + + print(level, dir_hierarchy) + + return level diff --git a/ProblemSolving/createTargetArrayInGivenOrder/create.py b/ProblemSolving/createTargetArrayInGivenOrder/create.py new file mode 100644 index 0000000..36b1cfb --- /dev/null +++ b/ProblemSolving/createTargetArrayInGivenOrder/create.py @@ -0,0 +1,16 @@ +# Logic 1: 100 pass 80% faster +# * Initialize dummy array elements +# * Add elements to index +# * shift when the index is already filled +class Solution: + def createTargetArray(self, nums: List[int], index: List[int]) -> List[int]: + i = 0 + n = len(nums) + result = [None]*n + while i < n: + if result[index[i]] == None: + result[index[i]] = nums[i] + else: + result = result[:index[i]] + [nums[i]] + result[index[i]:] + i += 1 + return result[:n] diff --git a/ProblemSolving/customSortString/sort2.py b/ProblemSolving/customSortString/sort2.py new file mode 100644 index 0000000..8a4ea0e --- /dev/null +++ b/ProblemSolving/customSortString/sort2.py @@ -0,0 +1,9 @@ +class Solution(object): + def customSortString(self, S, T): + """ + :type S: str + :type T: str + :rtype: str + """ + + return "".join(sorted(T, key=lambda x: list(S).index(x) if x in S else float('inf'))) diff --git a/ProblemSolving/dayOfTheWeek/day.py b/ProblemSolving/dayOfTheWeek/day.py new file mode 100644 index 0000000..1e050fd --- /dev/null +++ b/ProblemSolving/dayOfTheWeek/day.py @@ -0,0 +1,13 @@ +class Solution(object): + def dayOfTheWeek(self, day, month, year): + """ + :type day: int + :type month: int + :type year: int + :rtype: str + """ + + import datetime + week = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"] + date_obj = datetime.date(year, month, day) + return week[date_obj.weekday()] diff --git a/ProblemSolving/dayOfTheYear/day.py b/ProblemSolving/dayOfTheYear/day.py new file mode 100644 index 0000000..c0a4867 --- /dev/null +++ b/ProblemSolving/dayOfTheYear/day.py @@ -0,0 +1,24 @@ +class Solution(object): + def dayOfYear(self, date): + """ + :type date: str + :rtype: int + """ + + # Logic 1: Literally following the problem description - 100 pass 75% faster + + # Split date into corresponding year, month, day + year, month, day = date.split("-") + + # Days of the month + days_in_a_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] + + # Leap year check + if int(year)%400 == 0 or (int(year)%4 == 0 and int(year)%100 != 0): + days_in_a_month[1] = 29 + + # No of days just within a year is calculating month (month days until that resp month) and days + num = sum(days_in_a_month[:int(month)-1])+int(day) + return num + + diff --git a/ProblemSolving/decodeString/decode.py b/ProblemSolving/decodeString/decode.py new file mode 100644 index 0000000..b47d4a4 --- /dev/null +++ b/ProblemSolving/decodeString/decode.py @@ -0,0 +1,34 @@ +class Solution(object): + def decodeString(self, s): + """ + :type s: str + :rtype: str + """ + + # Logic - 100 pass 100% + # * Stack to store and iterate + # ** We will operate only when "]" appear in the string + + stack = [] + + # Iterate across the string + for i in range(len(s)): + # Operate only on ] + if s[i] == "]": + # fetch the sub string within [] + substring = "" + while stack[-1] != "[": + substring = stack.pop() + substring + stack.pop() # removes "[" + # fetch the integer times + num_of_time = "" + while stack and stack[-1].isdigit(): # stack[-1] != "]" + num_of_time = stack.pop() + num_of_time + # Append the decoded string back into stack (to support nested format) + stack.append(int(num_of_time)*substring) + else: + # Add everything except "]" into array + stack.append(s[i]) + # Return stack + return "".join(stack) + diff --git a/ProblemSolving/decodeWays/decode.py b/ProblemSolving/decodeWays/decode.py new file mode 100644 index 0000000..1271617 --- /dev/null +++ b/ProblemSolving/decodeWays/decode.py @@ -0,0 +1,57 @@ +class Solution(object): + def numDecodings(self, s): + """ + :type s: str + :rtype: int + """ + + # Without literally solving - try using math and some memo - 78% faster + # Ref: https://leetcode.com/problems/decode-ways/discuss/372420/Python-O(n)-time-O(1)-space-Detail-explanation-Turtle-Code + if not s or s[0] == "0": + return 0 + l1, l2, curr = 1, 1, 0 + for i in range(1, len(s)): + if s[i] != "0": + curr = l1 + if "10" <= s[i-1:i+1] < "27": + curr += l2 + l1, l2, curr = curr, l1, 0 + return l1 + + # BackTrack - 99 pass - Time Limit Exceeded + """ + def backtrack(decoded, remaining, selected): + if not remaining: + #print(decoded) + if str(decoded) not in selected: + selected.add(str(decoded)) + return selected + for i in range(1,3): + nxt = "".join(remaining[:i]) + if nxt and nxt[0] != "0" and (0 < int(nxt) < 27): + backtrack(decoded + [nxt], remaining[i:], selected) + return selected + + return len(backtrack([], list(s), set())) + """ + + # GIST + """ + # * Lesson: it looks like recursive should work here. Below naive does not work + s = list(s) + result = [""] + for i in range(len(s)): + one_letter = 96+int(s[i]) + if one_letter >= 97: + if result: + result[0] += chr(one_letter) + else: + if result: + result.pop(0) + if i+1 < len(s): + two_letter = int(s[i]+s[i+1]) + if two_letter < 27 and len(str(two_letter)) == 2: + result.append(chr(two_letter)) + return len(result) + """ + diff --git a/ProblemSolving/decryptStringFromAlphabetToIntegerMapping/decrypt.py b/ProblemSolving/decryptStringFromAlphabetToIntegerMapping/decrypt.py new file mode 100644 index 0000000..caeb546 --- /dev/null +++ b/ProblemSolving/decryptStringFromAlphabetToIntegerMapping/decrypt.py @@ -0,0 +1,17 @@ +class Solution: + def freqAlphabets(self, s: str) -> str: + # Logic 1: O(N) --> one reverse pass to covert to char with ascii value + # * We need to to find if the integer falls in which half + # * Easy way to achieve this would be to iterate string chars in reverse to know single digit vs double digit alphabets to expect + + decode = "" + i = len(s)-1 + asciiStart = 96 + while i >= 0: + if s[i] == "#": + decode = chr(int(s[i-2:i])+asciiStart) + decode # add to front as we reverse iterate + i -= 3 + else: + decode = chr(int(s[i])+asciiStart) + decode + i -= 1 + return decode diff --git a/ProblemSolving/deepCopyListWithRandomPointer/deep.py b/ProblemSolving/deepCopyListWithRandomPointer/deep.py new file mode 100644 index 0000000..6b12701 --- /dev/null +++ b/ProblemSolving/deepCopyListWithRandomPointer/deep.py @@ -0,0 +1,44 @@ +""" +# Definition for a Node. +class Node: + def __init__(self, x, next=None, random=None): + self.val = int(x) + self.next = next + self.random = random +""" +class Solution(object): + def copyRandomList(self, head): + """ + :type head: Node + :rtype: Node + """ + + # Logic 1: 69.36% faster + + # Variable declaration + copy = None + nodes = {} + prev = None + result = None + ref = head + + # O(1) iteration for current node and next + while head: + nodes[head] = Node(head.val, None, None) + if not result: + result = nodes[head] + if prev: + nodes[prev].next = nodes[head] + prev = head + head = head.next + + # Another O(1) iteration to decide the random + while ref: + if ref.random: + nodes[ref].random = nodes[ref.random] + else: + nodes[ref].random = None + ref = ref.next + return result + + diff --git a/ProblemSolving/deepestLeavesSum/deep.py b/ProblemSolving/deepestLeavesSum/deep.py new file mode 100644 index 0000000..8224265 --- /dev/null +++ b/ProblemSolving/deepestLeavesSum/deep.py @@ -0,0 +1,42 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right +class Solution(object): + def deepestLeavesSum(self, root): + """ + :type root: TreeNode + :rtype: int + """ + + # Logic 1: 88% faster - 100 pass + # * Record all the leaves in the tree with their heights in a dictionary + # * Track the maximum and return their sum + + def heightForLeaves(node, height): + # null check + if not node: + return + # traverse tree + if node.left: + heightForLeaves(node.left, height+1) + if node.right: + heightForLeaves(node.right, height+1) + # Check for leaf + if not node.left and not node.right: + if height not in self.leaf_heights: + self.leaf_heights[height] = [] + self.leaf_heights[height].append(node.val) + if height > self.max_height: + self.max_height = height + + self.leaf_heights = {} # height: [leaves] + self.max_height = 0 # track maximum + heightForLeaves(root, 0) + return sum(self.leaf_heights[self.max_height]) + + # Logic 2: + # * BFS + # * Return the farthest level sum diff --git a/ProblemSolving/defangIpAddress/defang.py b/ProblemSolving/defangIpAddress/defang.py new file mode 100644 index 0000000..5cd1c2d --- /dev/null +++ b/ProblemSolving/defangIpAddress/defang.py @@ -0,0 +1,22 @@ +class Solution(object): + def defangIPaddr(self, address): + """ + :type address: str + :rtype: str + """ + + # Easy inbuilt solution -- 100 pass 100% + ## return address.replace(".","[.]") + + # Another easy method -- 100 pass 100% + return "[.]".join(address.split(".")) + + # Manual replacements -- 100 pass 100% + """ + address = list(address) + for c in range(len(address)): + if address[c] == ".": + address[c] = "[.]" + return "".join(address) + """ + diff --git a/ProblemSolving/deleteColumnsToMakeSorted/delete.py b/ProblemSolving/deleteColumnsToMakeSorted/delete.py new file mode 100644 index 0000000..2476c93 --- /dev/null +++ b/ProblemSolving/deleteColumnsToMakeSorted/delete.py @@ -0,0 +1,23 @@ +class Solution(object): + def minDeletionSize(self, A): + """ + :type A: List[str] + :rtype: int + """ + + # Logic 1: 93 % faster + # * Problem here is we have to + # - Iterate the array A + # - Iterate the index + # * Logic with 2 for loops or one with dictionary to store all index elements would help but will be long logic + # * Thinking to iterate all the strings within one loop + # - Used unpack (*) of list to unpack the list to strings + # - Zip to iterate all the arguments by index together in one for loop + count = 0 + + for i in zip(*A): + if list(i) != sorted(i): + count += 1 + + return count + diff --git a/ProblemSolving/deleteLeavesWithGivenValue/delete.py b/ProblemSolving/deleteLeavesWithGivenValue/delete.py new file mode 100644 index 0000000..194c460 --- /dev/null +++ b/ProblemSolving/deleteLeavesWithGivenValue/delete.py @@ -0,0 +1,38 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def removeLeafNodes(self, root, target): + """ + :type root: TreeNode + :type target: int + :rtype: TreeNode + """ + + # Logic 1: traverse and delete all leaf nodes with target - 100 pass - 28ms 100% faster + def traverse(node, parent, side): + + # Traverse to reach the leaf node ( left and right ) + # ( Imagine traversing forward until a leaf is reached ) + if node.left: + traverse(node.left, node, "left") + if node.right: + traverse(node.right, node, "right") + + # After traversing on left and right sides, if the node becomes a leaf then do this + # ( Imagine traversing backwards to each parents until the root ) + if not node.left and not node.right: + if node.val == target: + if side == "center" and not parent: # Handle root node case ( no parent ) + node = None + elif side == "left": # tracking the sides is used to delete resp node + parent.left = None + elif side == "right": # tracking the sides is used to delete resp node + parent.right = None + return node + + return traverse(root, None, "center") diff --git a/ProblemSolving/deleteNnodesAfterMnodesOfLinkedList/del.py b/ProblemSolving/deleteNnodesAfterMnodesOfLinkedList/del.py new file mode 100644 index 0000000..4235b98 --- /dev/null +++ b/ProblemSolving/deleteNnodesAfterMnodesOfLinkedList/del.py @@ -0,0 +1,29 @@ +# Logic 1: follow the prob steps, at every start node, skip some and delete others, jump to a new start and then start the loop again - 100 pass - 78% faster + +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next +class Solution: + def deleteNodes(self, head: ListNode, m: int, n: int) -> ListNode: + + # Store head ref to return + result = head + # Iterate until end + while head: + # Refresh n, m at every start node + noDel = m-1 + delete = n + # no delete m + while head and noDel: + head = head.next + noDel -= 1 + # delete n + while head and head.next and delete: + head.next = head.next.next + delete -= 1 + # move to a new start + if head: + head = head.next + return result diff --git a/ProblemSolving/deleteNodeInALinkedList/delete.py b/ProblemSolving/deleteNodeInALinkedList/delete.py new file mode 100644 index 0000000..4a7ef5b --- /dev/null +++ b/ProblemSolving/deleteNodeInALinkedList/delete.py @@ -0,0 +1,20 @@ +# Definition for singly-linked list. +# class ListNode(object): +# def __init__(self, x): +# self.val = x +# self.next = None + +class Solution(object): + def deleteNode(self, node): + """ + :type node: ListNode + :rtype: void Do not return anything, modify node in-place instead. + """ + + nxt = node + while nxt: + if nxt.next: + nxt.val = nxt.next.val + if not nxt.next.next: + nxt.next = None + nxt = nxt.next diff --git a/ProblemSolving/deleteNodesAndReturnForest/delete.py b/ProblemSolving/deleteNodesAndReturnForest/delete.py new file mode 100644 index 0000000..7663613 --- /dev/null +++ b/ProblemSolving/deleteNodesAndReturnForest/delete.py @@ -0,0 +1,129 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def delNodes(self, root, to_delete): + """ + :type root: TreeNode + :type to_delete: List[int] + :rtype: List[TreeNode] + """ + + # Logic1: + # Recurse and + # * Alter node to null if they are present in to_delete + # * Each tree values on a list + # * If None, add the node value only if they have children + # * Returns list of trees with node values list ( question asks for roots of the trees so alter logic) + self.result = [] + + def traverse(node, parent_value): + if node.val in to_delete: + node.val = None + + has_children = False + + if node.left or node.right: + has_children = True + + if parent_value: + if node.val or (node.val == None and has_children): + self.result[-1].append(node.val) + else: + #if self.result: + # self.result[-1].append([node.val]) + #else: + self.result.append([node.val]) + + if node.left: + traverse(node.left, node.val) + + if node.right: + traverse(node.right, node.val) + + # Logic: Modify above logic to only include root nodes in the result list + # 100 pass + def logic2(node, parent_value): + + if node.val in to_delete: + node.val = None + + has_children = False + + if node.left or node.right: + has_children = True + + if not parent_value and node.val: + self.result.append(node) + + if node.left: + logic2(node.left, node.val) + + if node.right: + logic2(node.right, node.val) + + if has_children and node.val == None: + if node.left: + node.left = None + if node.right: + node.right = None + elif has_children: + if node.left and node.left.val == None: + node.left = None + if node.right and node.right.val == None: + node.right = None + + logic2(root, None) + return self.result +""" + # Logic: One time tree traversal with operations + + # Result list to hold the root nodes of the trees + self.result = [] + + # Helper method to recursively traverse all nodes (navigate the tree) + def traverse(node, parent_value): + + # While we visit nodes in to_delete, alter their values to None + # ( This lookup might take O(N), could be made faster) + if node.val in to_delete: + node.val = None + + # Check for children + # - nodes who are parent and None should be included in the previous tree + # - nodes who are parent and None should be removed from the relationship of its children + has_children = False + if node.left or node.right: + has_children = True + + # Parent value if NULL include as separate tree + if not parent_value and node.val: + self.result.append(node) + + # Traverse left and right children + if node.left: + traverse(node.left, node.val) + + if node.right: + traverse(node.right, node.val) + + # Remove relationship of the None valued parent + if has_children and node.val == None: + if node.left: + node.left = None + if node.right: + node.right = None + elif has_children: + # Check for tail leaf nodes ( output should not include leaf nodes that are None) + if node.left and node.left.val == None: + node.left = None + if node.right and node.right.val == None: + node.right = None + + traverse(root, None) + return self.result +""" diff --git a/ProblemSolving/designAStackWithIncrementOperation/design.py b/ProblemSolving/designAStackWithIncrementOperation/design.py new file mode 100644 index 0000000..4914e53 --- /dev/null +++ b/ProblemSolving/designAStackWithIncrementOperation/design.py @@ -0,0 +1,48 @@ +# Logic 1: Naive logic with iterations --> 20% faster +class CustomStack(object): + + def __init__(self, maxSize): + """ + :type maxSize: int + """ + + self.stack = [] + self.max = maxSize + + def push(self, x): + """ + :type x: int + :rtype: None + """ + if self.max == len(self.stack): + return + self.stack = [x] + self.stack + + + def pop(self): + """ + :rtype: int + """ + if self.stack: + return self.stack.pop(0) + return -1 + + + def increment(self, k, val): + """ + :type k: int + :type val: int + :rtype: None + """ + n = len(self.stack)-1 + i = 0 + while k and i <= n: + self.stack[n-i] += val + k -= 1 + i += 1 + +# Your CustomStack object will be instantiated and called as such: +# obj = CustomStack(maxSize) +# obj.push(x) +# param_2 = obj.pop() +# obj.increment(k,val) diff --git a/ProblemSolving/designBoundedBlockingQueue/design.py b/ProblemSolving/designBoundedBlockingQueue/design.py new file mode 100644 index 0000000..cb1d853 --- /dev/null +++ b/ProblemSolving/designBoundedBlockingQueue/design.py @@ -0,0 +1,33 @@ +# Logic 1: Naive logic with WHILE loop blocking for threads --> 5% Faster +class BoundedBlockingQueue(object): + def __init__(self, capacity): + """ + :type capacity: int + """ + self.queue = [] + self.max = capacity + + + def enqueue(self, element): + """ + :type element: int + :rtype: void + """ + while len(self.queue) == self.max: + pass + self.queue = [element] + self.queue + + def dequeue(self): + """ + :rtype: int + """ + while len(self.queue) == 0: + pass + return self.queue.pop() + + def size(self): + """ + :rtype: int + """ + return len(self.queue) + diff --git a/ProblemSolving/designCircularQueue/circle_queue.py b/ProblemSolving/designCircularQueue/circle_queue.py new file mode 100644 index 0000000..8d50b3a --- /dev/null +++ b/ProblemSolving/designCircularQueue/circle_queue.py @@ -0,0 +1,91 @@ +class MyCircularQueue(object): + + def __init__(self, k): + """ + Initialize your data structure here. Set the size of the queue to be k. + :type k: int + """ + + # Let us take a queue to be a list + # Construct queue + self.queue = [] # we dont want to initialize 0 for i in range(k) + self.size = k + + + def enQueue(self, value): + """ + Insert an element into the circular queue. Return true if the operation is successful. + :type value: int + :rtype: bool + """ + if not self.isFull(): + self.queue.append(value) + return True + else: + return False + + + def deQueue(self): + """ + Delete an element from the circular queue. Return true if the operation is successful. + :rtype: bool + """ + if self.isEmpty(): + return False + else: + self.queue.pop(0) + return True + + + def Front(self): + """ + Get the front item from the queue. + :rtype: int + """ + if not self.queue: + return -1 + else: + return self.queue[0] + + + def Rear(self): + """ + Get the last item from the queue. + :rtype: int + """ + if not self.queue: + return -1 + else: + return self.queue[-1] + + + def isEmpty(self): + """ + Checks whether the circular queue is empty or not. + :rtype: bool + """ + if self.queue != []: + return False + else: + return True + + def isFull(self): + """ + Checks whether the circular queue is full or not. + :rtype: bool + """ + if len(self.queue) == self.size: + return True + else: + return False + + + +# Your MyCircularQueue object will be instantiated and called as such: +# obj = MyCircularQueue(k) +# param_1 = obj.enQueue(value) +# param_2 = obj.deQueue() +# param_3 = obj.Front() +# param_4 = obj.Rear() +# param_5 = obj.isEmpty() +# param_6 = obj.isFull() diff --git a/ProblemSolving/designHashMap/map.py b/ProblemSolving/designHashMap/map.py new file mode 100644 index 0000000..9da75e2 --- /dev/null +++ b/ProblemSolving/designHashMap/map.py @@ -0,0 +1,52 @@ +class MyHashMap: + + # Logic 1: using lists for key and values with reusing uniq indexes to relate key/value pairs --> 5% faster + def __init__(self): + """ + Initialize your data structure here. + """ + + # using lists to implement hashmap + self.keys = [] + self.values = [] + + + def put(self, key: int, value: int) -> None: + """ + value will always be non-negative. + """ + for k in range(len(self.keys)): + if self.keys[k] == key: + self.values[k] = value + return + self.keys.append(key) + self.values.append(value) + + + def get(self, key: int) -> int: + """ + Returns the value to which the specified key is mapped, or -1 if this map contains no mapping for the key + """ + for k in range(len(self.keys)): + if self.keys[k] == key: + return self.values[k] + return -1 + + + def remove(self, key: int) -> None: + """ + Removes the mapping of the specified value key if this map contains a mapping for the key + """ + for k in range(len(self.keys)): + if self.keys[k] == key: + self.keys = self.keys[:k] + self.keys[k+1:] + self.values = self.values[:k] + self.values[k+1:] + return + return + + +# Your MyHashMap object will be instantiated and called as such: +# obj = MyHashMap() +# obj.put(key,value) +# param_2 = obj.get(key) +# obj.remove(key) diff --git a/ProblemSolving/designHashset/design.py b/ProblemSolving/designHashset/design.py new file mode 100644 index 0000000..3f75c43 --- /dev/null +++ b/ProblemSolving/designHashset/design.py @@ -0,0 +1,53 @@ +class MyHashSet(object): + + def __init__(self): + """ + Initialize your data structure here. + """ + + # Write more with BST Tree of internals of a dictionary + + # Logic 1: With Dictionary + # HashSet principles from references + # * Summary + # - Set contains only unique values + # - Internally its a dictionary with element as key and dummy value or present as value + # - Returns null when key is unique and added, else the value if already present + # * https://javahungry.blogspot.com/2013/08/how-sets-are-implemented-internally-in.html + self.ds = {} + + def add(self, key): + """ + :type key: int + :rtype: None + """ + if key in self.ds: + return + self.ds[key] = "present" + + + def remove(self, key): + """ + :type key: int + :rtype: None + """ + if key in self.ds: + del self.ds[key] + + def contains(self, key): + """ + Returns true if this set contains the specified element + :type key: int + :rtype: bool + """ + if key in self.ds: + return True + else: + return False + + +# Your MyHashSet object will be instantiated and called as such: +# obj = MyHashSet() +# obj.add(key) +# obj.remove(key) +# param_3 = obj.contains(key) diff --git a/ProblemSolving/designUnderGroundSystem/train_times.py b/ProblemSolving/designUnderGroundSystem/train_times.py new file mode 100644 index 0000000..3f020e2 --- /dev/null +++ b/ProblemSolving/designUnderGroundSystem/train_times.py @@ -0,0 +1,43 @@ +class UndergroundSystem: + + def __init__(self): + + self.trip_times = {} + self.customer_onboarded = {} + + def checkIn(self, id: int, stationName: str, t: int) -> None: + + if id not in self.customer_onboarded: + self.customer_onboarded[id] = [] + + self.customer_onboarded[id] = [stationName, t] + + def checkOut(self, id: int, stationName: str, t: int) -> None: + + startPoint, startTime = self.customer_onboarded[id] + totalDuration = t - startTime + key = startPoint + "->" + stationName + + if key not in self.trip_times: + self.trip_times[key] = [0, 0] + + self.trip_times[key][0] += totalDuration + self.trip_times[key][1] += 1 + + + def getAverageTime(self, startStation: str, endStation: str) -> float: + + key = startStation + "->" + endStation + + # there is always a trip so we dont need to check key existence, it shld always be true + if key not in self.trip_times: + return False + + return self.trip_times[key][0]/self.trip_times[key][1] + + +# Your UndergroundSystem object will be instantiated and called as such: +# obj = UndergroundSystem() +# obj.checkIn(id,stationName,t) +# obj.checkOut(id,stationName,t) +# param_3 = obj.getAverageTime(startStation,endStation) diff --git a/ProblemSolving/destinationCity/dest.py b/ProblemSolving/destinationCity/dest.py new file mode 100644 index 0000000..1fcb1bf --- /dev/null +++ b/ProblemSolving/destinationCity/dest.py @@ -0,0 +1,26 @@ +class Solution(object): + def destCity(self, pathss): + """ + :type paths: List[List[str]] + :rtype: str + """ + + # Logic 1: Built graph using dic and iterate for null dsts --> 100 pass 88% faster + + # Source --> Destination Map + paths = {} + + # Build graph + for (src, dst) in pathss: + if src not in paths: + paths[src] = [] + if dst not in paths: + paths[dst] = [] + paths[src].append(dst) + + # find the src with no dsts + for src in paths.keys(): + if paths[src] == []: + return src + + return None diff --git a/ProblemSolving/detectCapital/detect2.py b/ProblemSolving/detectCapital/detect2.py new file mode 100644 index 0000000..7907f16 --- /dev/null +++ b/ProblemSolving/detectCapital/detect2.py @@ -0,0 +1,27 @@ +class Solution: + def detectCapitalUse(self, word: str) -> bool: + + def isCaptial(charac): + if 65 <= ord(charac) <= 90: + return True + return False + + if len(word) == 0: + return False + + lastIsCapital = isCaptial(word[0]) + + index = 1 + for char in word[1:]: + if isCaptial(char): + if not lastIsCapital: + return False + lastIsCapital = True + else: + if lastIsCapital and index != 1: + return False + lastIsCapital = False + index += 1 + + # Implied: if not captialExists or captialExists + return True diff --git a/ProblemSolving/determineIfTwoStringsAreClose/determine.py b/ProblemSolving/determineIfTwoStringsAreClose/determine.py new file mode 100644 index 0000000..61cdabe --- /dev/null +++ b/ProblemSolving/determineIfTwoStringsAreClose/determine.py @@ -0,0 +1,22 @@ +class Solution: + def closeStrings(self, word1: str, word2: str) -> bool: + + import collections + + if len(word1) != len(word2): + return False + + # character count matching + count1 = collections.Counter(word1) + count2 = collections.Counter(word2) + + if count1 == count2: + return True + + chars1 = set(count1.keys()) + for c in count2.keys(): + if c not in chars1: + return False + + if sorted(count1.values()) == sorted(count2.values()): + return True diff --git a/ProblemSolving/diameterOfBinaryTree/diameter2.py b/ProblemSolving/diameterOfBinaryTree/diameter2.py new file mode 100644 index 0000000..0610cf1 --- /dev/null +++ b/ProblemSolving/diameterOfBinaryTree/diameter2.py @@ -0,0 +1,32 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right +class Solution: + def diameterOfBinaryTree(self, root: Optional[TreeNode]) -> int: + + def traverse(node): + + # traverse to compute + left_path = 0 + right_path = 0 + if node.left: + left_path = 1 + traverse(node.left) + if node.right: + right_path = 1 + traverse(node.right) + + # bottom up path calculation + + # for passing through current node calulation + max_path = (left_path + right_path) + if max_path > self.max_path: + self.max_path = max_path + + # for upper level max path calulation + return max(left_path, right_path) + + self.max_path = 0 + traverse(root) + return self.max_path diff --git a/ProblemSolving/diameterOfNaryTree/diameter.py b/ProblemSolving/diameterOfNaryTree/diameter.py new file mode 100644 index 0000000..e590086 --- /dev/null +++ b/ProblemSolving/diameterOfNaryTree/diameter.py @@ -0,0 +1,54 @@ +""" +# Definition for a Node. +class Node: + def __init__(self, val=None, children=None): + self.val = val + self.children = children if children is not None else [] +""" + +class Solution: + def diameter(self, root: 'Node') -> int: + """ + :type root: 'Node' + :rtype: int + """ + + # Logic 1: 40ms 100% faster + # * At every node, we store the longest height of its children + # * We can add up between children to obtain the max length through this subtree root node or return the max length of its children including itself + + # global diameter + self.diameter = 0 + + def find_diameter(node): + + # Null Check + if not node: + return + + # [Recursion] Obtain height of all children by traversing + heights = [] + for n in node.children: + heights.append(find_diameter(n)) + + # At current subtree root node... + heights.sort() + + # Max height of a child if children exists else 0 + current_max = heights[-1] if heights else 0 + + # Check if max diameter passes through this node ( Ex 1: 5-3-[1]-2 ) + if len(heights) > 1 and heights[-1] + heights[-2] > self.diameter: + self.diameter = heights[-1] + heights[-2] + + # Check if max height of child is the diameter ( Ex: [1]-2-3 ) + if current_max > self.diameter: + self.diameter = current_max + + # Return the max height of child including the current subtree root node ( adding itself ) for recursion to continue... + return 1 + current_max + + find_diameter(root) + return self.diameter + + diff --git a/ProblemSolving/distanceBetweenBusStops/distance.py b/ProblemSolving/distanceBetweenBusStops/distance.py new file mode 100644 index 0000000..3784641 --- /dev/null +++ b/ProblemSolving/distanceBetweenBusStops/distance.py @@ -0,0 +1,22 @@ +class Solution(object): + def distanceBetweenBusStops(self, distance, start, destination): + """ + :type distance: List[int] + :type start: int + :type destination: int + :rtype: int + """ + + + n = len(distance) + s = min(start, destination) + d = max(start, destination) + distance += distance + + clockwise = sum(distance[s:d]) + anticlockwise = sum(distance[d:n+s]) + + print(distance[s:d], distance[d:n+s]) + return min(clockwise, anticlockwise) + + diff --git a/ProblemSolving/distributeCandies/dist.py b/ProblemSolving/distributeCandies/dist.py index bcdd43c..87d4467 100644 --- a/ProblemSolving/distributeCandies/dist.py +++ b/ProblemSolving/distributeCandies/dist.py @@ -19,4 +19,30 @@ def distributeCandies(self, candies): else: return len(count.keys()) - +""" +class Solution(object): + def distributeCandies(self, candies): + """ + :type candies: List[int] + :rtype: int + """ + + import collections + bgs = len(candies)//2 + candy = collections.Counter(candies) + #print(candy) + + # When kind of candies are as much as of the girls ( half the students ) + if len(candy.keys()) == bgs: + return bgs + + # When there is indifference, then we calculate common candies for the boys, and then for the girls + for k, v in candy.items(): + while bgs > 0 and candy[k] > 1: + candy[k] -= 1 + bgs -= 1 + if candy[k] == 0: + del candy[k] + #print(candy) + return len(candy.keys())-bgs +""" diff --git a/ProblemSolving/distributeCandiesToPeople/distribute.py b/ProblemSolving/distributeCandiesToPeople/distribute.py new file mode 100644 index 0000000..feaa5b1 --- /dev/null +++ b/ProblemSolving/distributeCandiesToPeople/distribute.py @@ -0,0 +1,30 @@ +class Solution(object): + def distributeCandies(self, candies, num_people): + """ + :type candies: int + :type num_people: int + :rtype: List[int] + """ + + # Logic 1: 100 pass - 30% faster and 100% memory - Simple iteration to distribute candies + # * Got into a confusion where I though n increases for every iteration ( read the problem carefully ) + output = [0]*num_people + i = 0 + iteration = 0 + n = candies + + while i < len(output) and candies: + amount = len(output)*iteration + i + 1 + #print candies, amount + if amount <= candies: + output[i] += amount + candies -= amount + else: + output[i] += candies + candies = 0 + #print output, candies + if i == len(output)-1: + i = -1 + iteration += 1 + i += 1 + return output diff --git a/ProblemSolving/distributeCoinsInBinaryTree/dist.py b/ProblemSolving/distributeCoinsInBinaryTree/dist.py new file mode 100644 index 0000000..490fcd8 --- /dev/null +++ b/ProblemSolving/distributeCoinsInBinaryTree/dist.py @@ -0,0 +1,44 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def distributeCoins(self, root): + """ + :type root: TreeNode + :rtype: int + """ + + # Reference from lee215 at https://leetcode.com/problems/distribute-coins-in-binary-tree/discuss/221930/JavaC%2B%2BPython-Recursive-Solution + + # DFS method to find the distance to the root from both the left and right subtree + + # Global result + self.result = 0 + + # DFS recursive method + def dfs(node): + + # Null node check + if not node: + return 0 + + # Left and Right values + left = dfs(node.left) + right = dfs(node.right) + + # Add left and right values as we progress to the parent to the result + self.result += abs(left) + abs(right) + + # For each node, return everything except 1 for itself + return node.val + left + right - 1 + + # recursive call + dfs(root) + + return self.result + + diff --git a/ProblemSolving/divisorGame/div.py b/ProblemSolving/divisorGame/div.py new file mode 100644 index 0000000..b9c19a2 --- /dev/null +++ b/ProblemSolving/divisorGame/div.py @@ -0,0 +1,26 @@ +class Solution(object): + def divisorGame(self, N): + """ + :type N: int + :rtype: bool + """ + + def play_game(number): + + # Find Divisor + for i in range(1, (number//2)+1): + if number%i == 0: + # Return the difference + return number-i + return None + + count = 0 + while N != None: + N = play_game(N) + count += 1 + print count, N + + if count%2 != 0: + return False + else: + return True diff --git a/ProblemSolving/duplicateZeros/duplicate.py b/ProblemSolving/duplicateZeros/duplicate.py new file mode 100644 index 0000000..788338c --- /dev/null +++ b/ProblemSolving/duplicateZeros/duplicate.py @@ -0,0 +1,106 @@ +class Solution(object): + def duplicateZeros(self, arr): + """ + :type arr: List[int] + :rtype: None Do not return anything, modify arr in-place instead. + """ + + # Logic1: Lousy method: 100 pass 5% faster + # * At every 0 hit, shift all the elements and add zero + """ + n = len(arr) + i = 0 + while i < n: + if arr[i] == 0: + j = n-1 + while j > i+1: + arr[j] = arr[j-1] + j -= 1 + if i+1 < n: + arr[i+1] = 0 + i += 2 + else: + i += 1 + """ + + # Logic2: Similar to 2 pointer method - 100 pass 97 % faster + # * We could count the zeros (shift) that will fit the array + # * Use the remaining array to make the changes + + n = len(arr) + + # Count the Number of shifts - I altered this to store appropriate positions + shift_indices = [] # Indices where shift should happen + shift = 0 # Count the shift required as we iterate + shift_index = 0 # The index that would be the end of array in the future shifted array + for i in range(n): + shift += 1 # Shift for every element + if shift == n: # If shift cover the array return the shift index + shift_index = i + break + elif arr[i] == 0: # Extra shift for 0s + shift_indices.append(i) + shift += 1 + if shift == n: # If shift cover the array return the shift index ( after extra shift) + shift_index = i + break + # print shift, shift_index, arr, shift_indices + + # The real index in the array + real_index = n-1 + # The next shift index + if shift_indices: + next_shift = shift_indices.pop() + else: + next_shift = None + # Shifting... by one iteration + while shift_index >= 0 and real_index >= 0: + arr[real_index] = arr[shift_index] # Shift for all the elements + if shift_index == next_shift: # Add extra 0s in place for next shift element + arr[real_index-1] = 0 + real_index -= 1 # Extra iteration for extra 0 + # Update the next shift + if shift_indices: + next_shift = shift_indices.pop() + else: + next_shift = None + # Iterate and reduce indices + shift_index -= 1 + real_index -= 1 + + """ + # Uncleaned attempt + n = len(arr) + shift_indices = [] + shift = 0 + shift_index = 0 + for i in range(n): + shift += 1 + if shift == n: + shift_index = i + break + elif arr[i] == 0: + shift_indices.append(i) + shift += 1 + if shift == n: + shift_index = i + break + print shift, shift_index, arr, shift_indices + real_index = n-1 + if shift_indices: + next_shift = shift_indices.pop() + else: + next_shift = None + while shift_index >= 0 and real_index >= 0: + arr[real_index] = arr[shift_index] + if shift_index == next_shift: + arr[real_index-1] = 0 + real_index -= 1 + if shift_indices: + next_shift = shift_indices.pop() + else: + next_shift = None + shift_index -= 1 + real_index -= 1 + """ + diff --git a/ProblemSolving/elementAppearingMoreThan25InASortedArray/element.py b/ProblemSolving/elementAppearingMoreThan25InASortedArray/element.py new file mode 100644 index 0000000..165ba59 --- /dev/null +++ b/ProblemSolving/elementAppearingMoreThan25InASortedArray/element.py @@ -0,0 +1,31 @@ +class Solution(object): + def findSpecialInteger(self, arr): + """ + :type arr: List[int] + :rtype: int + """ + + # Logic 1: Naive Iteration O(N) - exit on first match of more than 25% - 100 pass 97% faster + """ + n = len(arr) + visited = None + count = 0 + for i in range(n): + if visited != None and arr[i] == visited: + count += 1 + else: + visited = arr[i] + count = 1 + if count > n//4: + return visited + return -1 + """ + + # Logic 2: Dictionary count method + import collections + counts = collections.Counter(arr) + n25 = len(arr)//4 + for k, v in counts.items(): + if v > n25: + return k + return -1 diff --git a/ProblemSolving/eliminationGame/eliminate.py b/ProblemSolving/eliminationGame/eliminate.py new file mode 100644 index 0000000..ebcb224 --- /dev/null +++ b/ProblemSolving/eliminationGame/eliminate.py @@ -0,0 +1,41 @@ +class Solution(object): + def lastRemaining(self, n): + """ + :type n: int + :rtype: int + """ + + # Interpret the Same condition in another way + # - Instead of deleting, we add only the respective digits... + nums = range(1,n+1) + while len(nums) > 1: + n = len(nums) + i = 1 + temp = [] + while i <= n-1: + temp.append(nums[i]) + i += 2 + nums = temp[::-1] + return nums[0] + + + """ + # Literal solve - pseudocode + + nums = range(1,n+1) + + while len(nums) > 1: + n = len(nums) + i = 0 + while i <= n-1: + nums.pop(i) + i += 2 + i = len(nums)-1 + while i >= 0: + nums.pop(i) + i -= 2 + return nums[0] + """ + + + diff --git a/ProblemSolving/encodeAndDecodeTinyURL/tinyURL.py b/ProblemSolving/encodeAndDecodeTinyURL/tinyURL.py new file mode 100644 index 0000000..2f52028 --- /dev/null +++ b/ProblemSolving/encodeAndDecodeTinyURL/tinyURL.py @@ -0,0 +1,36 @@ +import base64 + +class Codec: + + # Logic 1: use a dict to store (might cause o(N) space) using char count, or any random id or tail url + # Logic 2: use base64 algo + + def encode(self, longUrl: str) -> str: + """Encodes a URL to a shortened URL. + """ + + noSlashes = longUrl.split("/") + + domain = "/".join(noSlashes[:3]) + encodedPath = base64.b64encode(("/".join(noSlashes[3:]).encode())) + + #print(noSlashes, domain, encodedPath) + #print(domain+ "/" + encodedPath.decode('utf-8')) + + return domain+ "/" + encodedPath.decode('utf-8') + + + def decode(self, shortUrl: str) -> str: + """Decodes a shortened URL to its original URL. + """ + noSlashes = shortUrl.split("/") + + domain = "/".join(noSlashes[:3]) + decodedPath = base64.b64decode(("/".join(noSlashes[3:]).encode())) + + return domain+ "/" + decodedPath.decode('utf-8') + + +# Your Codec object will be instantiated and called as such: +# codec = Codec() +# codec.decode(codec.encode(url)) diff --git a/ProblemSolving/encodeNumber/encode.py b/ProblemSolving/encodeNumber/encode.py new file mode 100644 index 0000000..9b57a00 --- /dev/null +++ b/ProblemSolving/encodeNumber/encode.py @@ -0,0 +1,6 @@ +# Logic 1: Binary of N+1 and remove left most 1 - 100 pass 77.5% faster +class Solution: + def encode(self, num: int) -> str: + num += 1 + b = bin(num)[2:] + return "1".join(b.split("1")[1:]) diff --git a/ProblemSolving/evenDigits/even.py b/ProblemSolving/evenDigits/even.py new file mode 100644 index 0000000..c232a91 --- /dev/null +++ b/ProblemSolving/evenDigits/even.py @@ -0,0 +1,26 @@ +# Naive add/sub with 2 pointers + +def isEven(num): + for i in list(str(num).strip()): + if int(i)%2 != 0: + return False + return True + +def uniqCalc(N): + left = right = 0 + + while not isEven(N-left) and not isEven(N+right): + #print N+left, N+right, isEven(N+left), isEven(N+right) + left += 1 + right += 1 + + if isEven(N-left): + return left + else: + return right + +testcases = input() +for i in range(testcases): + num = input() + print "Case #"+str(i+1)+": "+str(uniqCalc(num)) + diff --git a/ProblemSolving/evenDigits/new.py b/ProblemSolving/evenDigits/new.py new file mode 100644 index 0000000..9349904 --- /dev/null +++ b/ProblemSolving/evenDigits/new.py @@ -0,0 +1,28 @@ +# Naive add/sub with 2 pointers + +def isEven0(num): + if num%2 == 0: + for i in list(str(num).strip()): + if int(i)%2 != 0: + return False + return True + else: + return False + +def uniqCalc(N): + step = 0 + + if N%2 != 0: + step += 1 + + while not isEven0(N-step) and not isEven0(N+step): + #print N+left, N+right, isEven(N+left), isEven(N+right) + step += 2 + + return step + +testcases = input() +for i in range(testcases): + num = input() + print "Case #"+str(i+1)+": "+str(uniqCalc(num)) + diff --git a/ProblemSolving/evenOddArrangement/even.py b/ProblemSolving/evenOddArrangement/even.py new file mode 100644 index 0000000..3d6324c --- /dev/null +++ b/ProblemSolving/evenOddArrangement/even.py @@ -0,0 +1,18 @@ +# Even to the front of the array and Odd behind the array - with no extra space, operate in the given array +def evenOddArrange(arr): + odd_index = None + for i in range(len(arr)): + if arr[i]%2 == 0: + if odd_index != None: + arr[odd_index], arr[i] = arr[i], arr[odd_index] + odd_index += 1 + else: + if odd_index == None: + odd_index = i + return arr + +def main(): + array = [1,2,3,4,5,6,7,8,9] + print evenOddArrange(array) + +main() diff --git a/ProblemSolving/fibonacci/fibo.go b/ProblemSolving/fibonacci/fibo.go new file mode 100644 index 0000000..aaea6dd --- /dev/null +++ b/ProblemSolving/fibonacci/fibo.go @@ -0,0 +1,31 @@ +// Iterative Fibonacci - 0ms +func fib(N int) int { + if N == 0 { + return 0 + } + if N == 1 { + return 1 + } + f0 := 0 + f1 := 1 + f2 := 0 + for i := 1; i= 2: + for i in range(2, N+1): + fnext = f0 + f1 + f0 = f1 + f1 = fnext + if N == 0: + return f0 + elif N == 1: + return f1 + else: + return fnext + """ + + # List Method - 100 pass + """ + fiboN = [0,1] + i = 2 + while i < N+1: + fiboN.append(fiboN[i-1]+fiboN[i-2]) + i += 1 + return fiboN[N] + """ + + # Recursion Only Method - Slow - 100 pass + """ + def fiboRecurse(N): + if N == 0: + return 0 + elif N == 1: + return 1 + else: + return fiboRecurse(N-1)+fiboRecurse(N-2) + return fiboRecurse(N) + """ + + # Memoization + Recursion - Faster 100 pass + memo = [0, 1] + def fiboRecurseMemo(N): + if N < len(memo): + return memo[N] + else: + memo.append(fiboRecurseMemo(N-1)+fiboRecurseMemo(N-2)) + return memo[-1] + return fiboRecurseMemo(N) + + + + + diff --git a/ProblemSolving/finalPricesWithASpecialDiscountInAShop/final.py b/ProblemSolving/finalPricesWithASpecialDiscountInAShop/final.py new file mode 100644 index 0000000..45ff7dc --- /dev/null +++ b/ProblemSolving/finalPricesWithASpecialDiscountInAShop/final.py @@ -0,0 +1,30 @@ +class Solution: + def finalPrices(self, prices: List[int]) -> List[int]: + # Logic 1: Obvious almost NM**2 of running until last index at each index considered - 100 pass 53% faster + """ + for i in range(len(prices)): + mini = prices[i+1:] + for j in range(len(mini)): + if mini[j] <= prices[i]: + prices[i] -= mini[j] + break + return prices + """ + # Logic 2: Having a convergence stage of making relationship before iterating + # * Keep a record of the sorted array + # * index to element relation in a dictionary + # * Convergence can again take almost equal complexity + + # Logic 3: Using inbuilt min function at every index --> the first min index is asked so this effort is not worth + + # Logic 4: O(N) Using a separate stack or array to feed all the greater ones so when we hit the first min <= element we can apply the condition + # * Ref: https://leetcode.com/problems/final-prices-with-a-special-discount-in-a-shop/discuss/685390/JavaC%2B%2BPython-Stack-One-Pass + stack = [] # Separate stack to store element that still need to be computed for discount + for i in range(len(prices)): + #print(stack) + while stack and prices[stack[-1]] >= prices[i]: # current element is first min index >= the stack element + prices[stack.pop()] -= prices[i] # Apply discount + stack.append(i) # Add to stack to compute this later in iteration + return prices + + diff --git a/ProblemSolving/findAllNumbersDisappearedInAnArray/arr.py b/ProblemSolving/findAllNumbersDisappearedInAnArray/arr.py index 4b34d40..3ee0c35 100644 --- a/ProblemSolving/findAllNumbersDisappearedInAnArray/arr.py +++ b/ProblemSolving/findAllNumbersDisappearedInAnArray/arr.py @@ -59,3 +59,27 @@ def findDisappearedNumbers(self, nums): i += 1 return nums """ + + + """ + # retry after a long time - 100 pass + class Solution(object): + def findDisappearedNumbers(self, nums): + """ + :type nums: List[int] + :rtype: List[int] + """ + + nums.sort() + result = set() + for i in range(len(nums)): + if nums[i]-nums[i-1] > 1: + for j in range(nums[i-1]+1, nums[i]): + result.add(j) + #print(nums) + if nums and nums[-1] < len(nums): + result.update(set(range(nums[-1]+1, len(nums)+1))) + if nums and nums[0] > 1: + result.update(set(range(1, nums[0]))) + return result + """ diff --git a/ProblemSolving/findAllTheLonelyNodes/lonely.py b/ProblemSolving/findAllTheLonelyNodes/lonely.py new file mode 100644 index 0000000..49be300 --- /dev/null +++ b/ProblemSolving/findAllTheLonelyNodes/lonely.py @@ -0,0 +1,31 @@ +# Logic 1: Traverse tree + find parent with one node: 50% faster + +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right +class Solution: + def getLonelyNodes(self, root: TreeNode) -> List[int]: + + + def traverseTree(node): + if not node: + return + children = [] + if node.left: + children.append(node.left.val) + traverseTree(node.left) + if node.right: + children.append(node.right.val) + traverseTree(node.right) + if len(children) == 1: + self.lonely.append(children[0]) + + + self.lonely = [] + traverseTree(root) + return self.lonely + + diff --git a/ProblemSolving/findAnagramMappings/find.py b/ProblemSolving/findAnagramMappings/find.py new file mode 100644 index 0000000..6bea7b6 --- /dev/null +++ b/ProblemSolving/findAnagramMappings/find.py @@ -0,0 +1,20 @@ +class Solution(object): + def anagramMappings(self, A, B): + """ + :type A: List[int] + :type B: List[int] + :rtype: List[int] + """ + + # Logic 1: Using dictionary to store indexes in B - 2*O(N) --> 37.87% faster 100 pass + # 1. iterate over B to create a map - account for duplicates with a list + # 2. iterate over A to generate results + mapB = {} # element: [indexes] + for i in range(len(B)): + if B[i] not in mapB: + mapB[B[i]] = [] + mapB[B[i]].append(i) + result = [] + for element in A: + result.append(mapB[element].pop()) + return result diff --git a/ProblemSolving/findAndReplaceInString/find.py b/ProblemSolving/findAndReplaceInString/find.py new file mode 100644 index 0000000..c625d70 --- /dev/null +++ b/ProblemSolving/findAndReplaceInString/find.py @@ -0,0 +1,47 @@ +# Pending.. +class Solution(object): + def findReplaceString(self, S, indexes, sources, targets): + """ + :type S: str + :type indexes: List[int] + :type sources: List[str] + :type targets: List[str] + :rtype: str + """ + + # Logic 2 + # * Create a relation between different elements in the problem + # * Solve accordingly + + # Logic X: A Python Approach using a bunch of inbuilt functions + result = S + for i in range(len(indexes)): + current = sources[i] + index = indexes[i] + n = len(current) + if S[index:index+n] == current: + result = result.replace(current, targets[i], 1) + return result + + # Logic + # * Literally follow instructions --> find and replace + # * No overlap is a good thing and is given! + + # this problem has a bunch of disintegrated list which need to be related. Below logic will pass when the index list is sorted and corresponding entries are present in the targets list. + # Having the indexes sorted would require each related list to arrange accordingly. Rethink a different approach + """ + length_delta = 0 + # Start with index + for i in range(len(indexes)): + # Get the Source + current = sources[i] + index = indexes[i]+length_delta + n = len(current) + # Check the Source is S + if S[index:index+n] == current: + # Replace is match + S= S[:index] + targets[i] + S[index+n:] + length_delta += len(targets[i])-1 + print S + return S + """ diff --git a/ProblemSolving/findAndReplacePattern/find2.py b/ProblemSolving/findAndReplacePattern/find2.py new file mode 100644 index 0000000..23d68ca --- /dev/null +++ b/ProblemSolving/findAndReplacePattern/find2.py @@ -0,0 +1,34 @@ +class Solution: + def findAndReplacePattern(self, words: List[str], pattern: str) -> List[str]: + + patt = {} + for p in range(len(pattern)): + if pattern[p] not in patt: + patt[pattern[p]] = [] + patt[pattern[p]].append(p) + + def matchPattern(src): + if len(src) != len(pattern): + return False + visited = set() + visited_char = set() + for i in range(len(src)): + if i in visited: + continue + visited.add(i) + if src[i] in visited_char: + return False + for p in patt[pattern[i]]: + if src[p] != src[i]: + return False + visited.add(p) + visited_char.add(src[i]) + return True + + result = [] + for word in words: + if matchPattern(word): + result.append(word) + return result + + diff --git a/ProblemSolving/findCommonCharacters/find.py b/ProblemSolving/findCommonCharacters/find.py new file mode 100644 index 0000000..f721fad --- /dev/null +++ b/ProblemSolving/findCommonCharacters/find.py @@ -0,0 +1,29 @@ +class Solution(object): + def commonChars(self, A): + """ + :type A: List[str] + :rtype: List[str] + """ + + # Logic: + # 1. Using set ==> we might loose the duplicate common elements + # 2. Using counter() ==> intersection depends on the prefix counter + # 3. bruteforce or naive method + + result = list(A[0]) + + for word in A[1:]: + i = 0 + word = list(word) + while i < len(result): + if result[i] not in word: + del result[i] + else: + del word[word.index(result[i])] + i += 1 + return result + + + + + diff --git a/ProblemSolving/findContentChildren/find.py b/ProblemSolving/findContentChildren/find.py new file mode 100644 index 0000000..ab61460 --- /dev/null +++ b/ProblemSolving/findContentChildren/find.py @@ -0,0 +1,14 @@ +class Solution: + def findContentChildren(self, g: List[int], s: List[int]) -> int: + + g.sort(reverse=True) + s.sort(reverse=True) + + count = 0 + for i in range(len(g)): + if not s: + return count + if g[i] <= s[0]: + s.pop(0) + count += 1 + return count diff --git a/ProblemSolving/findCorrespondingNodeInABinaryTreeInACloneOfThatTree/find.py b/ProblemSolving/findCorrespondingNodeInABinaryTreeInACloneOfThatTree/find.py new file mode 100644 index 0000000..7117d0c --- /dev/null +++ b/ProblemSolving/findCorrespondingNodeInABinaryTreeInACloneOfThatTree/find.py @@ -0,0 +1,70 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def getTargetCopy(self, original: TreeNode, cloned: TreeNode, target: TreeNode) -> TreeNode: + + + # Logic 1: traverse cloned to find the same node with same children + def traverse(node): + + if not node: + return + + if node.val == target.val: + left = False + right = False + if node.left and target.left and node.left.val == target.left.val: + left = True + if node.right and target.right and node.right.val == target.right.val: + right = True + if not node.left and not target.left: + left = True + if not node.right and not target.right: + right = True + if left and right: + self.node = node + + # traversal + if node.left: + traverse(node.left) + if node.right: + traverse(node.right) + + return + + # Logic 2: traverse both the trees in parallel to find the exact node + def dualTraverse(tree1, tree2): + + if tree1 and tree1 == target: + return tree2 + + if not tree1: + return None + + l = None + r = None + if tree1.left: + l = dualTraverse(tree1.left, tree2.left) + if tree1.right: + r = dualTraverse(tree1.right, tree2.right) + + if l: + return l + elif r: + return r + else: + return None + + # logic 1 call + + #self.node = None + #traverse(cloned) + #return self.node + + # logic 2 call + return dualTraverse(original, cloned) diff --git a/ProblemSolving/findDifferenceOfTwoArrays/find.py b/ProblemSolving/findDifferenceOfTwoArrays/find.py new file mode 100644 index 0000000..148c10a --- /dev/null +++ b/ProblemSolving/findDifferenceOfTwoArrays/find.py @@ -0,0 +1,30 @@ +class Solution(object): + def findDifference(self, nums1, nums2): + """ + :type nums1: List[int] + :type nums2: List[int] + :rtype: List[List[int]] + """ + + result = [[],[]] + + count_nums1 = {} + for i in nums1: + if i not in count_nums1: + count_nums1[i] = 0 + count_nums1[i] = 1 + + count_nums2 = {} + for i in nums2: + if i in count_nums1: + count_nums1[i] -= 1 + continue + if i not in count_nums2: + result[1].append(i) + count_nums2[i] = 1 + + for k,v in count_nums1.items(): + if v > 0: + result[0].append(k) + + return result diff --git a/ProblemSolving/findDuplicateSubtree/find.py b/ProblemSolving/findDuplicateSubtree/find.py new file mode 100644 index 0000000..a445e29 --- /dev/null +++ b/ProblemSolving/findDuplicateSubtree/find.py @@ -0,0 +1,49 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def findDuplicateSubtrees(self, root): + """ + :type root: TreeNode + :rtype: List[TreeNode] + """ + + # maintain record of visited subtree + all_subtrees = {} + # Root node results + result = [] + + def traverse(node): + + # Null node condition + if not node: + return "null" + + # Create subtree + subtree_at_current_node = str(node.val) + subtree_at_current_node += traverse(node.left) + subtree_at_current_node += traverse(node.right) + + # Condition to handle already visited nodes + if subtree_at_current_node in all_subtrees: + if all_subtrees[subtree_at_current_node] == 1: + result.append(node) + else: + all_subtrees[subtree_at_current_node] = 0 + # Increment visited nodes + all_subtrees[subtree_at_current_node] += 1 + + # Return subtree to build for every node + return subtree_at_current_node + + # Null node check + if not root: + return [] + + traverse(root) + + return result diff --git a/ProblemSolving/findFirstAndLastPositionOfElementInASortedArray/find.py b/ProblemSolving/findFirstAndLastPositionOfElementInASortedArray/find.py new file mode 100644 index 0000000..ae32df0 --- /dev/null +++ b/ProblemSolving/findFirstAndLastPositionOfElementInASortedArray/find.py @@ -0,0 +1,38 @@ +class Solution: + def searchRange(self, nums: List[int], target: int) -> List[int]: + + # Logic: log n + already sorted demanding binary search (ref lt sol) + def binarySearchBounds(nums, target, bound="lower"): + + n = len(nums) + l = 0 + r = n-1 + + while l <= r: + mid = l+(r-l)//2 + + if nums[mid] == target: + if bound == "lower": + if mid == l or nums[mid-1] < target: # r-l == 1 then l=mid or less integer due to being sorted + return mid + r = mid-1 + elif bound == "upper": + if mid == r or nums[mid+1] > target: # r-l == 1 then r=mid or greater integer due to being sorted + return mid + l = mid+1 + else: + return -1 + + elif nums[mid] < target: + l = mid+1 + else: + r = mid-1 + + return -1 + + lb = binarySearchBounds(nums, target) + if lb == -1: + return [-1,-1] + hb = binarySearchBounds(nums, target, "upper") + + return [lb, hb] diff --git a/ProblemSolving/findLuckyIntegerInAnArray/find.py b/ProblemSolving/findLuckyIntegerInAnArray/find.py new file mode 100644 index 0000000..282ee14 --- /dev/null +++ b/ProblemSolving/findLuckyIntegerInAnArray/find.py @@ -0,0 +1,11 @@ +class Solution: + def findLucky(self, arr: List[int]) -> int: + + # Logic 1: Dictionary + max tracking - 100 pass 84% faster + import collections + count = collections.Counter(arr) + result = -1 + for k, v in count.items(): + if v == k and k > result: + result = k + return result diff --git a/ProblemSolving/findMissingAndRepeatedValues/find.py b/ProblemSolving/findMissingAndRepeatedValues/find.py new file mode 100644 index 0000000..0b08098 --- /dev/null +++ b/ProblemSolving/findMissingAndRepeatedValues/find.py @@ -0,0 +1,26 @@ +class Solution: + def findMissingAndRepeatedValues(self, grid: List[List[int]]) -> List[int]: + + rc = len(grid) + + if rc == 0: + return [] + + cc = len(grid[0]) + + elements = [0]*((rc*cc)+1) + + for i in range(rc): + for j in range(cc): + elements[grid[i][j]] += 1 + + twice = [] + noexist = [] + for i in range(1, (rc*cc)+1): + v = elements[i] + if v == 2: + twice.append(i) + if v == 0: + noexist.append(i) + + return twice + noexist diff --git a/ProblemSolving/findModeInBinarySearchTree/find.py b/ProblemSolving/findModeInBinarySearchTree/find.py new file mode 100644 index 0000000..c01b4fa --- /dev/null +++ b/ProblemSolving/findModeInBinarySearchTree/find.py @@ -0,0 +1,46 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def findMode(self, root): + """ + :type root: TreeNode + :rtype: List[int] + """ + + # Using extra space logic + # * a dictionary with all the values + self.freq = {} + + def traverse(node): + # Null node handle + if not node: + return + + if node.val not in self.freq: + self.freq[node.val] = 1 + else: + self.freq[node.val] += 1 + + if node.left: + traverse(node.left) + if node.right: + traverse(node.right) + + if not root: + return [] + + traverse(root) + + result = [] + mode = max(self.freq.values()) + for value, count in self.freq.items(): + if count == mode: + result.append(value) + return result + + diff --git a/ProblemSolving/findNodeInClonedBinaryTree/find.py b/ProblemSolving/findNodeInClonedBinaryTree/find.py new file mode 100644 index 0000000..6d4dc25 --- /dev/null +++ b/ProblemSolving/findNodeInClonedBinaryTree/find.py @@ -0,0 +1,48 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def getTargetCopy(self, original, cloned, target): + """ + :type original: TreeNode + :type cloned: TreeNode + :type target: TreeNode + :rtype: TreeNode + """ + + # Brainstorm: + # * Both the trees are copies so their structure remains the same, iterate or traverse together? + # * I think they mean deep copy (not shallow copy) here and we need to find the reference of the exact node even when there are repeated values + # * By nature bst has distinct keys --> Can the logic also support when repeated values occur? + # - Means we need to check if the parents and childrens are the same or subtree at that node is same + + # Logic 1: Traverse 2 trees - 100 pass 17.6% + def traverseBothTree(original, cloned, target, result): + print(self.result) + # Check node not null + if not original: + return None + + # Exit criteria + if original.val == cloned.val == target.val: + self.result = cloned + + # Traverse the tree together + if original.left and not self.result: + self.getTargetCopy(original.left, cloned.left, target) + + if original.right and not self.result: + self.getTargetCopy(original.right, cloned.right, target) + + self.result = None + traverseBothTree(original, cloned, target, self.result) + print(self.result) + return self.result + + # Logic 2: Repeated values would be allowed? + + diff --git a/ProblemSolving/findNumbersWithEvenDigits/find.py b/ProblemSolving/findNumbersWithEvenDigits/find.py new file mode 100644 index 0000000..8f99804 --- /dev/null +++ b/ProblemSolving/findNumbersWithEvenDigits/find.py @@ -0,0 +1,27 @@ +class Solution(object): + def findNumbers(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + + # Logic 1: String conversion and length ( a bit like bruteforce ) - 97% faster + """ + result = 0 + for num in nums: + if len(str(num))%2 == 0: + result += 1 + return result + """ + + # Logic 2: ( No string conversion) Retain as Integer and perform the same - 60% faster + # * Remove the units digits one by one until the number expires + result = 0 + for num in nums: + digits = 0 + while num: + num = num//10 + digits += 1 + if digits%2 == 0: + result += 1 + return result diff --git a/ProblemSolving/findPivotIndex/find2.py b/ProblemSolving/findPivotIndex/find2.py new file mode 100644 index 0000000..c7ed9b7 --- /dev/null +++ b/ProblemSolving/findPivotIndex/find2.py @@ -0,0 +1,22 @@ +class Solution: + def pivotIndex(self, nums: List[int]) -> int: + + if len(nums) == 0: + return -1 + if len(nums) == 1: + return 0 + + sum_of_array = 0 + for i in nums: + sum_of_array += i + + lsum = 0 + rsum = sum_of_array + + for i in range(len(nums)): + rsum -= nums[i] + if lsum == rsum: + return i + lsum += nums[i] + + return -1 diff --git a/ProblemSolving/findPlayersWithZeroOrOneLosses/plays.py b/ProblemSolving/findPlayersWithZeroOrOneLosses/plays.py new file mode 100644 index 0000000..6a1f572 --- /dev/null +++ b/ProblemSolving/findPlayersWithZeroOrOneLosses/plays.py @@ -0,0 +1,32 @@ +class Solution: + def findWinners(self, matches: List[List[int]]) -> List[List[int]]: + + goat = [] + onemiss = [] + + matchesPerPlayer = {} + resultsPerPlayer = {} + + for match in matches: + winner = match[0] + loser = match[1] + + for player in [winner, loser]: + if player not in matchesPerPlayer: + matchesPerPlayer[player] = 0 + if player not in resultsPerPlayer: + resultsPerPlayer[player] = 0 + + matchesPerPlayer[player] += 1 + + resultsPerPlayer[winner] += 1 + resultsPerPlayer[loser] -= 1 + + for p in sorted(matchesPerPlayer.keys()): + #print(p, matchesPerPlayer[p], resultsPerPlayer[p]) + if matchesPerPlayer[p] == resultsPerPlayer[p]: + goat.append(p) + if (matchesPerPlayer[p] - resultsPerPlayer[p]) == 2: + onemiss.append(p) + + return [goat, onemiss] diff --git a/ProblemSolving/findPositiveIntegerSolutionForAGivenEquation/find.py b/ProblemSolving/findPositiveIntegerSolutionForAGivenEquation/find.py new file mode 100644 index 0000000..7970776 --- /dev/null +++ b/ProblemSolving/findPositiveIntegerSolutionForAGivenEquation/find.py @@ -0,0 +1,33 @@ +""" + This is the custom function interface. + You should not implement it, or speculate about its implementation + class CustomFunction: + # Returns f(x, y) for any given positive integers x and y. + # Note that f(x, y) is increasing with respect to both x and y. + # i.e. f(x, y) < f(x + 1, y), f(x, y) < f(x, y + 1) + def f(self, x, y): + +""" +class Solution(object): + def findSolution(self, customfunction, z): + """ + :type num: int + :type z: int + :rtype: List[List[int]] + """ + + i = 1 + j = 1 + result = [] + while customfunction.f(i,j) <= z: + while customfunction.f(i,j) <= z: + if customfunction.f(i,j) == z: + result.append([i, j]) + j += 1 + j = 1 + i += 1 + return result + + + + diff --git a/ProblemSolving/findSmallestCommonElementInAllRows/find.py b/ProblemSolving/findSmallestCommonElementInAllRows/find.py new file mode 100644 index 0000000..d63985c --- /dev/null +++ b/ProblemSolving/findSmallestCommonElementInAllRows/find.py @@ -0,0 +1,21 @@ +class Solution(object): + def smallestCommonElement(self, mat): + """ + :type mat: List[List[int]] + :rtype: int + """ + + # Logic 1: Naive iteration of rows + converting each row into dictionary + finding the frequency of items - 100 pass 6% faster + import collections + common = collections.Counter(mat[0]) + for r in range(1, len(mat)): + rn = collections.Counter(mat[r]) + common = common + rn + for k,v in common.items(): + if v < r+1: + del common[k] + if common: + return min(common.keys()) + else: + return -1 + diff --git a/ProblemSolving/findTheDistanceValueBetweenTwoArrays/find.py b/ProblemSolving/findTheDistanceValueBetweenTwoArrays/find.py new file mode 100644 index 0000000..f295e08 --- /dev/null +++ b/ProblemSolving/findTheDistanceValueBetweenTwoArrays/find.py @@ -0,0 +1,27 @@ +class Solution: + def findTheDistanceValue(self, arr1: List[int], arr2: List[int], d: int) -> int: + # Naive method of iterations - 100 pass - 40% faster + result = 0 + for e1 in arr1: # iterate 1st arr + for e2 in range(len(arr2)): # iterate 2nd arr + if abs(e1-arr2[e2]) <= d: # check condition and exit on first match + break + if e2 == len(arr2)-1: # If it reached the last then update result + result += 1 + return result + +""" + # Naive method of iterations - 100 pass - 50% faster + result = 0 + no_match = False # This is used to check the state of last index element in arr2 + for e1 in arr1: # iterate 1st arr + for e2 in range(len(arr2)): # iterate 2nd arr + if abs(e1-arr2[e2]) <= d: # check condition and exit on first match + no_match = False + break + no_match = True + if e2 == len(arr2)-1 and no_match: # If it reached the last then update result + result += 1 + return result +""" + diff --git a/ProblemSolving/findTheHighestAltitude/find.py b/ProblemSolving/findTheHighestAltitude/find.py new file mode 100644 index 0000000..5968dcc --- /dev/null +++ b/ProblemSolving/findTheHighestAltitude/find.py @@ -0,0 +1,9 @@ +class Solution: + def largestAltitude(self, gain: List[int]) -> int: + max_alt = 0 + current_alt = 0 + for i in gain: + current_alt += i + if current_alt > max_alt: + max_alt = current_alt + return max_alt diff --git a/ProblemSolving/findThePunishmentNumberOfAnInteger/punish_num.py b/ProblemSolving/findThePunishmentNumberOfAnInteger/punish_num.py new file mode 100644 index 0000000..520a0be --- /dev/null +++ b/ProblemSolving/findThePunishmentNumberOfAnInteger/punish_num.py @@ -0,0 +1,36 @@ +class Solution: + def punishmentNumber(self, n: int) -> int: + + def findPunishNum(square, integer, result): + #print(square, integer, result) + tens = 0 + test = square + while test >= 10: + test = test//10 + tens += 1 + + if square+result == integer: + return True + + if tens == 0: + if integer == square: # single digit multiplier case + return True + if square+result == integer: + return True + + for m in range(1, tens+1): + m = 10**m + if findPunishNum(square//m, integer, result + square%m): + return True + + return False + + ans = 0 + for i in range(1, n+1): + sq = i*i + if findPunishNum(sq, i, 0): + print(i) + ans += sq + #print(findPunishNum(25, 5, 0)) + + return ans diff --git a/ProblemSolving/findTheTeamSize/find.py b/ProblemSolving/findTheTeamSize/find.py new file mode 100644 index 0000000..7cdeba3 --- /dev/null +++ b/ProblemSolving/findTheTeamSize/find.py @@ -0,0 +1,3 @@ +# Write your MySQL query statement below + +select e.employee_id, (select COUNT(team_id) from Employee where team_id=e.team_id) as team_size from Employee e; diff --git a/ProblemSolving/findTheTownJudge/find.py b/ProblemSolving/findTheTownJudge/find.py new file mode 100644 index 0000000..ac5b174 --- /dev/null +++ b/ProblemSolving/findTheTownJudge/find.py @@ -0,0 +1,49 @@ +class Solution(object): + def findJudge(self, N, trust): + """ + :type N: int + :type trust: List[List[int]] + :rtype: int + """ + + # Logic 2 - (Just Add/Sub) 100 pass 100 percent + # Dictionary to count all the trust + # * Combining the 2 rule we conclude + # - being trusted, Count add 1 + # - Trusting someoone, Count subtract 1 + # * The one remaining with value equal to N-1 wins + trusted_by_n = [0]*(N+1) + + # Iterate through trust to add/sub the trust scale + for t in trust: + trusted_by_n[t[0]] -= 1 + trusted_by_n[t[1]] += 1 + + # Null Trust list check + if trust == [] and N==1: + return N + + # One with value of trust equal to N-1 is the Judge + if max(trusted_by_n) == N-1: + return trusted_by_n.index(max(trusted_by_n)) + else: + return -1 + + # Logic 1 + # A dictionary to satisfy both the condition + # For a town judge, + # * number of trusters of a person should be N-1 + # * no trust for the one person + """ + trust_dictionary = {} + + for t in trust: + if t[1] not in trust_dictionary: + trust_dictionary[t[1]] = [] + trust_dictionary[t[1]].append(t[0]) + """ + + + + + diff --git a/ProblemSolving/findTheTownJudge/find2.py b/ProblemSolving/findTheTownJudge/find2.py new file mode 100644 index 0000000..15b301e --- /dev/null +++ b/ProblemSolving/findTheTownJudge/find2.py @@ -0,0 +1,24 @@ +class Solution: + def findJudge(self, n: int, trust: List[List[int]]) -> int: + + trustGraph = {} + + for t in range(len(trust)): + + a = trust[t][0] + b = trust[t][1] + + if a not in trustGraph: + trustGraph[a] = set() + if b not in trustGraph: + trustGraph[b] = set() + + trustGraph[a].add(b) + + possibleJudges = [] + for k,v in trustGraph.items(): + if len(v) == 0: + possibleJudges.append(k) + + if len(trust) == 0 and n == 1: + return 1 diff --git a/ProblemSolving/findUniqueBinaryString/find.py b/ProblemSolving/findUniqueBinaryString/find.py new file mode 100644 index 0000000..a525ac3 --- /dev/null +++ b/ProblemSolving/findUniqueBinaryString/find.py @@ -0,0 +1,31 @@ +class Solution: + def findDifferentBinaryString(self, nums: List[str]) -> str: + + numset = set() + + for i in range(len(nums)): + n = len(nums[i]) + numset.add(nums[i]) + + comp = ["1"*n, "0"*n] + for i in range(len(nums)): + target = ''.join(str(int(b1) ^ int(b2)) for b1, b2 in zip(nums[i], comp[0])) + if target not in numset: + return target + target = ''.join(str(int(b1) ^ int(b2)) for b1, b2 in zip(nums[i], comp[0])) + if target not in numset: + return target + + stack = ["0", "1"] + while stack: + curr = stack.pop(0) + if len(curr) == n and curr not in numset: + return curr + if len(curr) > n: + continue + for i in ["0", "1"]: + stack.append(curr+i) + + return "" + + diff --git a/ProblemSolving/findWordsThatCanBeFormedByCharacters/findWordsThatCanBeFormedyCharacters/find.py b/ProblemSolving/findWordsThatCanBeFormedByCharacters/findWordsThatCanBeFormedyCharacters/find.py new file mode 100644 index 0000000..e1afeff --- /dev/null +++ b/ProblemSolving/findWordsThatCanBeFormedByCharacters/findWordsThatCanBeFormedyCharacters/find.py @@ -0,0 +1,27 @@ +class Solution(object): + def countCharacters(self, words, chars): + """ + :type words: List[str] + :type chars: str + :rtype: int + """ + + # Logic 1: Using (Counter) Dictionary datastructure - 10% faster - 100 pass + + import collections + result = 0 + dict_char = collections.Counter(chars) + for word in words: + dict_word = collections.Counter(word) + ## If you use subtract method it adds the non existing chars which complicates so use '-' + #dict_word.subtract(dict_char) + #print(dict_word - dict_char) + #if sorted(dict_word.values(), reverse=True)[0] <= 0: + not_good_word = dict_word - dict_char + if not not_good_word: + result += len(word) + return result + + + # Logic 2: Naive iteration Using for loop for chars, for words and for char in word + diff --git a/ProblemSolving/findWordsThatCanBeFormedByCharacters/findWordsThatCanBeFormedyCharacters/find2.py b/ProblemSolving/findWordsThatCanBeFormedByCharacters/findWordsThatCanBeFormedyCharacters/find2.py new file mode 100644 index 0000000..f5e4e3c --- /dev/null +++ b/ProblemSolving/findWordsThatCanBeFormedByCharacters/findWordsThatCanBeFormedyCharacters/find2.py @@ -0,0 +1,18 @@ +class Solution(object): + def countCharacters(self, words, chars): + """ + :type words: List[str] + :type chars: str + :rtype: int + """ + + # Logic: Dictionary to store all characters count + import collections + c_count = collections.Counter(chars) + lengths = 0 + for word in words: + w_count = collections.Counter(word) + diff = w_count - c_count + if not diff: + lengths += len(word) + return lengths diff --git a/ProblemSolving/findWordsThatCanBeFormedByCharacters/findWordsThatCanBeFormedyCharacters/find3.py b/ProblemSolving/findWordsThatCanBeFormedByCharacters/findWordsThatCanBeFormedyCharacters/find3.py new file mode 100644 index 0000000..871b00b --- /dev/null +++ b/ProblemSolving/findWordsThatCanBeFormedByCharacters/findWordsThatCanBeFormedyCharacters/find3.py @@ -0,0 +1,28 @@ +class Solution: + def countCharacters(self, words: List[str], chars: str) -> int: + + def isGoodWord(word): + temp = {} + for i in word: + if i not in self.characs: + return False + if i not in temp: + temp[i] = 0 + temp[i] += 1 + if temp[i] > self.characs[i]: + return False + return True + + + self.characs = {} + for i in chars: + if i not in self.characs: + self.characs[i] = 0 + self.characs[i] += 1 + + ans = 0 + for i in words: + if isGoodWord(i): + ans += len(i) + return ans + diff --git a/ProblemSolving/firstBadVersion/bad2.py b/ProblemSolving/firstBadVersion/bad2.py new file mode 100644 index 0000000..c81fbdd --- /dev/null +++ b/ProblemSolving/firstBadVersion/bad2.py @@ -0,0 +1,39 @@ +# The isBadVersion API is already defined for you. +# @param version, an integer +# @return a bool +# def isBadVersion(version): + +class Solution(object): + def firstBadVersion(self, n): + """ + :type n: int + :rtype: int + """ + + # Binary Search is better + left = 0 + right = n + while left < right: + mid = left + (right-left)//2 + if isBadVersion(mid): + right = mid + else: + left = mid + + if right-left == 1: + if isBadVersion(left): + return left + else: + return right + + return right + + # O(N) - You can go front or backwards both would be n --> we need to reduce it + """ + i = 0 + while i < n: + if isBadVersion(i): + return i + i += 1 + return i + """ diff --git a/ProblemSolving/firstCompletelyPaintedRowOrCol/first.py b/ProblemSolving/firstCompletelyPaintedRowOrCol/first.py new file mode 100644 index 0000000..4d09f90 --- /dev/null +++ b/ProblemSolving/firstCompletelyPaintedRowOrCol/first.py @@ -0,0 +1,34 @@ +class Solution(object): + def firstCompleteIndex(self, arr, mat): + """ + :type arr: List[int] + :type mat: List[List[int]] + :rtype: int + """ + + checkRow = [0]*len(mat) + checkCol = [0]*len(mat[0]) + + cacheNums = [[0] * len(mat[0]) for i in range(len(mat))] + cacheIndices = {} + + for i in range(len(mat)): + for j in range(len(mat[0])): + target = mat[i][j] + if target not in cacheIndices: + cacheIndices[target] = [] + cacheIndices[target].append((i,j)) + + for i in range(len(arr)): + c = arr[i] + for indi in cacheIndices[c]: + r, c = indi + checkRow[r] += 1 + checkCol[c] += 1 + if checkRow[r] == len(mat[0]): + return i + if checkCol[c] == len(mat): + return i + return -1 + + diff --git a/ProblemSolving/firstUniqueCharacterInAString/first.py b/ProblemSolving/firstUniqueCharacterInAString/first.py new file mode 100644 index 0000000..e341079 --- /dev/null +++ b/ProblemSolving/firstUniqueCharacterInAString/first.py @@ -0,0 +1,13 @@ +class Solution(object): + def firstUniqChar(self, s): + """ + :type s: str + :rtype: int + """ + import collections + freq = collections.Counter(s) + for i in range(len(s)): + if freq[s[i]] == 1: + return i + return -1 + diff --git a/ProblemSolving/fixedPoint/fix.py b/ProblemSolving/fixedPoint/fix.py new file mode 100644 index 0000000..619b80b --- /dev/null +++ b/ProblemSolving/fixedPoint/fix.py @@ -0,0 +1,38 @@ +class Solution(object): + def fixedPoint(self, A): + """ + :type A: List[int] + :rtype: int + """ + + + # Logic 1: Naive O(N) Iteration of the list - 10.5 % faster + """ + for i in range(len(A)): + if A[i] == i: + return i + return -1 + """ + + # Logic 2: Binary Search Iteration - 99% faster + + # From the question, + """ + Remember the order is already sorted, + * A[i] - i < 0 as we want to find a condition A[i] == i then the element lesser than this index wont apply too + """ + + left = 0 + right = len(A)-1 + # Binary search + while left < right: + mid = left + (right-left)//2 # mid point + if A[mid] - mid < 0: + left = mid+1 + else: + right = mid + if A[left] == left: + return left + else: + return -1 + diff --git a/ProblemSolving/fizzBuzz/fizz.py b/ProblemSolving/fizzBuzz/fizz.py index 5b6d19c..9aadce9 100644 --- a/ProblemSolving/fizzBuzz/fizz.py +++ b/ProblemSolving/fizzBuzz/fizz.py @@ -17,4 +17,28 @@ def fizzBuzz(self, n): result.append(str(i)) return result +# Alternate Logic +""" +class Solution(object): + def fizzBuzz(self, n): + """ + :type n: int + :rtype: List[str] + """ + + result = [] + for i in range(1,n+1): + current = "" + # Divisible by 3 + if i%3 == 0: + current += "Fizz" + # Divisible by 5 + if i%5 == 0: + current += "Buzz" + # Not visible by Both + if not current: + current = str(i) + result.append(current) + return result +""" diff --git a/ProblemSolving/flattenNestedListIterator/flatten.py b/ProblemSolving/flattenNestedListIterator/flatten.py new file mode 100644 index 0000000..50de32d --- /dev/null +++ b/ProblemSolving/flattenNestedListIterator/flatten.py @@ -0,0 +1,54 @@ +# """ +# This is the interface that allows for creating nested lists. +# You should not implement it, or speculate about its implementation +# """ +#class NestedInteger: +# def isInteger(self) -> bool: +# """ +# @return True if this NestedInteger holds a single integer, rather than a nested list. +# """ +# +# def getInteger(self) -> int: +# """ +# @return the single integer that this NestedInteger holds, if it holds a single integer +# Return None if this NestedInteger holds a nested list +# """ +# +# def getList(self) -> [NestedInteger]: +# """ +# @return the nested list that this NestedInteger holds, if it holds a nested list +# Return None if this NestedInteger holds a single integer +# """ + +class NestedIterator: + def __init__(self, nestedList: [NestedInteger]): + self.nested = nestedList + self.flatten = [] + + def flattener(self): + curr_nested = self.nested.pop(0) + + if curr_nested.isInteger(): + self.flatten.append(curr_nested.getInteger()) + return + + if curr_nested.getList(): + self.nested = curr_nested.getList() + self.nested + return self.flattener() + + def next(self) -> int: + #print("ss", self.flatten) + return self.flatten.pop(0) + + def hasNext(self) -> bool: + #print(self.nested, self.nested == True) + while self.nested: + self.flattener() + if self.nested or self.flatten: + return True + return False + + +# Your NestedIterator object will be instantiated and called as such: +# i, v = NestedIterator(nestedList), [] +# while i.hasNext(): v.append(i.next()) diff --git a/ProblemSolving/floodFill/fill.py b/ProblemSolving/floodFill/fill.py new file mode 100644 index 0000000..ad6b974 --- /dev/null +++ b/ProblemSolving/floodFill/fill.py @@ -0,0 +1,72 @@ +class Solution(object): + def floodFill(self, image, sr, sc, newColor): + """ + :type image: List[List[int]] + :type sr: int + :type sc: int + :type newColor: int + :rtype: List[List[int]] + """ + + # Logic 1: Iterative approach - 93% faster + """ + # Stack to keep track of the affected pixel + stack = [[sr, sc]] # initialize with the first pixel + visited = [] # Keep track of visied pixel to not revisit again + + # dimensions + n = len(image) + m = len(image[0]) + + # Iterate until all the pixels have been flooded + while stack: + print(stack) + # Current pixel for consideration + current = stack.pop(0) + visited.append(current) + + # Add all the affected pixels + # Top Row + if current[0]-1 >= 0: + index = [current[0]-1, current[1]] + if index not in visited and image[index[0]][index[1]] == image[current[0]][current[1]]: + stack.append(index) + # Botton Row + if current[0]+1 < n: + index = [current[0]+1, current[1]] + if index not in visited and image[index[0]][index[1]] == image[current[0]][current[1]]: + stack.append(index) + # Left Column + if current[1]-1 >= 0: + index = [current[0], current[1]-1] + if index not in visited and image[index[0]][index[1]] == image[current[0]][current[1]]: + stack.append(index) + # Right Column + if current[1]+1 < m: + index = [current[0], current[1]+1] + if index not in visited and image[index[0]][index[1]] == image[current[0]][current[1]]: + stack.append(index) + + # Alter color of the current pixel + image[current[0]][current[1]] = newColor + + return image + """ + + # Logic 2: Recursive approach - 99% faster + + # Recursive Helper Function + def fill_pixel(i, j): + image[i][j] = newColor + for x, y in [(i+1, j), (i-1, j), (i, j+1), (i, j-1)]: + if 0 <= x < n and 0 <= y < m and image[x][y] == original: + fill_pixel(x, y) + + # dimensions + n = len(image) # Rows + m = len(image[0]) # Columns + original = image[sr][sc] # Original Color + if original != newColor: + fill_pixel(sr, sc) + return image + diff --git a/ProblemSolving/flowerPlantingWithNoAdjacent/flower.py b/ProblemSolving/flowerPlantingWithNoAdjacent/flower.py new file mode 100644 index 0000000..248ed0a --- /dev/null +++ b/ProblemSolving/flowerPlantingWithNoAdjacent/flower.py @@ -0,0 +1,39 @@ +class Solution(object): + def gardenNoAdj(self, N, paths): + """ + :type N: int + :type paths: List[List[int]] + :rtype: List[int] + """ + + graph = {} + + if not paths: + return [1]*N + + for gard in paths: + if gard[0] not in graph: + graph[gard[0]] = [gard[1]] + else: + graph[gard[0]].append(gard[1]) + if gard[1] not in graph: + graph[gard[1]] = [gard[0]] + else: + graph[gard[1]].append(gard[0]) + + flowers = [1 for i in range(N+1)] + + #print(graph) + for i in graph.keys(): + fls = [] + for v in graph[i]: + fls.append(flowers[v]) + #print(i, fls) + for c in range(1, 5): + if c not in fls: + flowers[i] = c + break + #print(flowers) + + return flowers[1:] + diff --git a/ProblemSolving/fruitIntoBaskets/fruit.py b/ProblemSolving/fruitIntoBaskets/fruit.py new file mode 100644 index 0000000..aa551c3 --- /dev/null +++ b/ProblemSolving/fruitIntoBaskets/fruit.py @@ -0,0 +1,42 @@ +class Solution(object): + def totalFruit(self, tree): + """ + :type tree: List[int] + :rtype: int + """ + basket1 = 0 + b1type = None + b1i = 0 + basket2 = 0 + b2type = None + b2i = 0 + + max_basket = 0 + + f = 0 + while f < len(tree): + if b1type == None: + b1type = tree[f] + b1i = f + elif b2type == None and b1type != tree[f]: + b2type = tree[f] + b2i = f + + if tree[f] == b1type: + basket1 += 1 + f += 1 + elif tree[f] == b2type: + basket2 += 1 + f += 1 + else: + b1type = None + b2type = None + basket1 = basket2 = 0 + f = b2i + + max_basket = max(max_basket, basket1+basket2) + #print(b1type, b2type, basket1, basket2) + + return max_basket + + diff --git a/ProblemSolving/fruitIntoBaskets/fruit2.py b/ProblemSolving/fruitIntoBaskets/fruit2.py new file mode 100644 index 0000000..282431d --- /dev/null +++ b/ProblemSolving/fruitIntoBaskets/fruit2.py @@ -0,0 +1,29 @@ +class Solution: + def totalFruit(self, tree: List[int]) -> int: + max_fruits = 0 + for start in range(len(tree)): + types = {tree[start]} + start_max = 0 + while tree[start] > 0: + if tree[start] not in types and len(types) < 2: + types.add(tree[start]) + + # Return if more than tree types + if len(types) == 2 and tree[start] not in types: + break + + # Break if no fruit else add + if tree[start] > 0: + start_max += 1 + tree[start] -= 1 + else: + break + + # Rotate and continue if condition satisfies + if start+1 < len(tree) and tree[start+1] > 0: + start = start + 1 + elif start + 1 == len(tree) and tree[0] > 0: + start = 0 + if start_max > max_fruits: + max_fruits = start_max + return max_fruits diff --git a/ProblemSolving/generateAStringWithCharactersThatHaveOddCounts/gen.py b/ProblemSolving/generateAStringWithCharactersThatHaveOddCounts/gen.py new file mode 100644 index 0000000..73ee228 --- /dev/null +++ b/ProblemSolving/generateAStringWithCharactersThatHaveOddCounts/gen.py @@ -0,0 +1,21 @@ +class Solution: + def generateTheString(self, n: int) -> str: + + # Logic 1: choose alphas at random, you would need only 2 --> Odd with one and Even with 2 chars - 92 % faster + """ + import string + alphas = list(string.ascii_lowercase) + if n%2 == 0: + return alphas.pop(0)*(n-1)+alphas.pop(0) + else: + return alphas.pop(0)*n + """ + + # Logic 2: Bit more optmize by loosing all the char list - 98% faster + first = "x" + sec = "y" + if n%2 == 0: + return first*(n-1)+sec + else: + return sec*n + diff --git a/ProblemSolving/generateParantheses/gen2.py b/ProblemSolving/generateParantheses/gen2.py new file mode 100644 index 0000000..a83a36e --- /dev/null +++ b/ProblemSolving/generateParantheses/gen2.py @@ -0,0 +1,42 @@ +class Solution(object): + def generateParenthesis(self, n): + """ + :type n: int + :rtype: List[str] + """ + # Logic 1: Recursion + # Kind of like backtracking, tree of valid paranthesis combinations + """ + def generate(current, o, c, selected): + #print(current, selected, o, c) + if o == c == 0: + selected.append(current) + return + if o > 0: + generate(current+"(", o-1, c, selected) + if c > 0 and c > o: + generate(current+")", o, c-1, selected) + return selected + + # Every N pair can be N of open and close paran + open_braces = n + closed_braces = n + return generate("", open_braces, closed_braces, []) + """ + + # Logic 2: Iterative of the same logic + result = [] + possible_ones = [["", n, n]] # [combination, open, close] + while possible_ones: + n = len(possible_ones) + while n > 0: + comb, o, c = possible_ones.pop(0) + if o == c == 0: + result.append(comb) + else: + if o > 0: + possible_ones.append([comb+"(", o-1, c]) + if c > 0 and c > o: + possible_ones.append([comb+")", o, c-1]) + n -= 1 + return result diff --git a/ProblemSolving/generateParantheses/generate.py b/ProblemSolving/generateParantheses/generate.py new file mode 100644 index 0000000..ca76551 --- /dev/null +++ b/ProblemSolving/generateParantheses/generate.py @@ -0,0 +1,42 @@ +class Solution(object): + def generateParenthesis(self, n): + """ + :type n: int + :rtype: List[str] + """ + + def gen_valid_paran(left, right, paran): + if left: + gen_valid_paran(left-1, right, paran + "(") + if right > left: + gen_valid_paran(left, right-1, paran + ")") + if not right: + self.params += paran, + + self.params = [] + gen_valid_paran(n, n, "") + return self.params + +""" +class Solution(object): + def generateParenthesis(self, n): + """ + :type n: int + :rtype: List[str] + """ + + def create(o, c, current): + if o == c == 0: + self.result.append(current) + return + if o > 0: + create(o-1, c, current+"(") + if c > o: + create(o, c-1, current+")") + print(current) + + + self.result = [] + create(n, n, "") + return self.result +""" diff --git a/ProblemSolving/generateParantheses/generate_iterative.py b/ProblemSolving/generateParantheses/generate_iterative.py new file mode 100644 index 0000000..8a54daf --- /dev/null +++ b/ProblemSolving/generateParantheses/generate_iterative.py @@ -0,0 +1,25 @@ +class Solution: + def generateParenthesis(self, n: int) -> List[str]: + + if not n: + return [] + + self.stack = [["(",n-1,n]] + self.params = [] + + def iterative_to_form(): + while self.stack: + n = len(self.stack) + while n: + current, l, r = self.stack.pop(0) + if l > 0: + self.stack.append([current+"(",l-1,r]) + if r > 0 and l < r: + self.stack.append([current+")",l,r-1]) + if l == r == 0: + self.params.append(current) + n -= 1 + print(self.stack) + + iterative_to_form() + return self.params diff --git a/ProblemSolving/getTargetCopy/get.py b/ProblemSolving/getTargetCopy/get.py new file mode 100644 index 0000000..7117d0c --- /dev/null +++ b/ProblemSolving/getTargetCopy/get.py @@ -0,0 +1,70 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def getTargetCopy(self, original: TreeNode, cloned: TreeNode, target: TreeNode) -> TreeNode: + + + # Logic 1: traverse cloned to find the same node with same children + def traverse(node): + + if not node: + return + + if node.val == target.val: + left = False + right = False + if node.left and target.left and node.left.val == target.left.val: + left = True + if node.right and target.right and node.right.val == target.right.val: + right = True + if not node.left and not target.left: + left = True + if not node.right and not target.right: + right = True + if left and right: + self.node = node + + # traversal + if node.left: + traverse(node.left) + if node.right: + traverse(node.right) + + return + + # Logic 2: traverse both the trees in parallel to find the exact node + def dualTraverse(tree1, tree2): + + if tree1 and tree1 == target: + return tree2 + + if not tree1: + return None + + l = None + r = None + if tree1.left: + l = dualTraverse(tree1.left, tree2.left) + if tree1.right: + r = dualTraverse(tree1.right, tree2.right) + + if l: + return l + elif r: + return r + else: + return None + + # logic 1 call + + #self.node = None + #traverse(cloned) + #return self.node + + # logic 2 call + return dualTraverse(original, cloned) diff --git a/ProblemSolving/greatestCommonDivisor/great.py b/ProblemSolving/greatestCommonDivisor/great.py new file mode 100644 index 0000000..77ec96c --- /dev/null +++ b/ProblemSolving/greatestCommonDivisor/great.py @@ -0,0 +1,48 @@ +class Solution(object): + def gcdOfStrings(self, str1, str2): + """ + :type str1: str + :type str2: str + :rtype: str + """ + + + + # Logic2: T + ... + T logic is S + # * Inconsistent logic fails certain tcs + """ + n = len(str1) + m = len(str2) + + if n < m: + divisor = str1 + dividend = str2 + else: + divisor = str2 + dividend = str1 + + result = "" + if divisor in dividend and set(divisor) == set(dividend): + i = len(divisor)-1 + while i > 0 and "".join(divisor.split(divisor[:i])) != "": + i -= 1 + if i > 0: + result = divisor[:i] + else: + result = divisor + more = dividend.split(result) + if len(more) > 1: + result += more[1] + return result + """ + + # Logic1 : Not caring about the order of the substring and the rule + # * Iterating o(N) to just find common strings + """ + result = "" + for i in str1: + if i in str2: + if i not in result: + result += i + return result + """ diff --git a/ProblemSolving/greatestCommonDivisorOfStrings/great.py b/ProblemSolving/greatestCommonDivisorOfStrings/great.py new file mode 100644 index 0000000..ac12bb0 --- /dev/null +++ b/ProblemSolving/greatestCommonDivisorOfStrings/great.py @@ -0,0 +1,55 @@ +class Solution(object): + def gcdOfStrings(self, str1, str2): + """ + :type str1: str + :type str2: str + :rtype: str + """ + + def str_div(substring, s1, s2): + c1 = s1.count(substring) + c2 = s2.count(substring) + return substring*c1 == s1 and substring*c2 == s2 + + if len(str1) < len(str2): + substr = str1 + else: + substr = str2 + + maxi = "" + for i in range(len(substr)): + left = substr[:i] + if left and str_div(left, str1, str2) and len(left) > len(maxi): + maxi = left + right = substr[i:] + if right and str_div(right, str1, str2) and len(right) > len(maxi): + maxi = right + return maxi + +""" +class Solution(object): + def gcdOfStrings(self, str1, str2): + """ + :type str1: str + :type str2: str + :rtype: str + """ + + def divide_string(str1, k): + div = str1.split(k) + if "".join(div) == "": + return True + else: + return False + + key = "" + current_key = "" + for i, j in zip(str1, str2): + if i == j: + current_key += i + else: + current_key = "" + if len(current_key) > len(key) and divide_string(str1, current_key) and divide_string(str2, current_key): + key = current_key + return key +""" diff --git a/ProblemSolving/groupAnagrams/group.go b/ProblemSolving/groupAnagrams/group.go new file mode 100644 index 0000000..519ae29 --- /dev/null +++ b/ProblemSolving/groupAnagrams/group.go @@ -0,0 +1,38 @@ +import ( + "fmt" +) + +// Logic 1: Using to create a char freq map for every string and use the map as key for another map to track similar anagrams ( implement something kind of like set intersection ) +// Can we use map as key to another map? +/* +func convertStringToMap(s string) map[rune]int { + charMap := make(map[rune]int) + for _, ch := range s { + charMap[ch] += 1 + } + return charMap +} +*/ + +// Logic 2: Sort the characters of a string and use them as key to the main anagram map + +func sortCharInString(s string) string { + split := strings.Split(s, "") + sort.Strings(split) + return strings.Join(split, "") +} + + +func groupAnagrams(strs []string) [][]string { + groups := make(map[string][]string) + for _, s := range strs { + //sMap := convertStringToMap(s) + sortStr := sortCharInString(s) + groups[sortStr] = append(groups[sortStr], s) + } + anagrams := [][]string{} + for _, value := range groups { + anagrams = append(anagrams, value) + } + return anagrams +} diff --git a/ProblemSolving/groupAnagrams/group.py b/ProblemSolving/groupAnagrams/group.py new file mode 100644 index 0000000..af70c72 --- /dev/null +++ b/ProblemSolving/groupAnagrams/group.py @@ -0,0 +1,19 @@ +class Solution(object): + def groupAnagrams(self, strs): + """ + :type strs: List[str] + :rtype: List[List[str]] + """ + + # Logic 1: 100 pass 80% faster - Instead of using collections for each word lets use sorted of each word and use them as key for dictionarys + anagrams = {} + for word in strs: + key = "".join(sorted(word)) + if key not in anagrams: + anagrams[key] = [] + anagrams[key].append(word) + result = [] + for key, value in anagrams.items(): + result.append(value) + return result + diff --git a/ProblemSolving/guessHighNumberOrLower/guess.py b/ProblemSolving/guessHighNumberOrLower/guess.py new file mode 100644 index 0000000..81c0751 --- /dev/null +++ b/ProblemSolving/guessHighNumberOrLower/guess.py @@ -0,0 +1,31 @@ +# The guess API is already defined for you. +# @param num, your guess +# @return -1 if num is higher than the picked number +# 1 if num is lower than the picked number +# otherwise return 0 +# def guess(num: int) -> int: + +class Solution: + def guessNumber(self, n: int) -> int: + + left = 1 + right = n + if left == right: + return left + + while left < right: + mid = (left+right)//2 + gues = guess(mid) + if gues == -1: + right = mid-1 + elif gues == 1: + left = mid+1 + else: + return mid + + if guess(left) == 0: + return left + elif guess(right) == 0: + return right + + return -1 diff --git a/ProblemSolving/hammingWeight/ham.py b/ProblemSolving/hammingWeight/ham.py new file mode 100644 index 0000000..62a1643 --- /dev/null +++ b/ProblemSolving/hammingWeight/ham.py @@ -0,0 +1,20 @@ +class Solution(object): + def hammingWeight(self, n): + """ + :type n: int + :rtype: int + """ + + # Logic 1: convert to binary and operate + #return bin(n).count("1") + import collections + b = list(bin(n)) + counts = collections.Counter(b) + return counts["1"] + + # Logic 2: Binary and removes the last signficant one for AND operation. 010 --> 011 --> 100 + ones = 0 + while n: + n = n & (n-1) + ones += 1 + return ones diff --git a/ProblemSolving/handOfStraights/hand.py b/ProblemSolving/handOfStraights/hand.py new file mode 100644 index 0000000..82a1de0 --- /dev/null +++ b/ProblemSolving/handOfStraights/hand.py @@ -0,0 +1,78 @@ +class Solution(object): + def isNStraightHand(self, hand, W): + """ + :type hand: List[int] + :type W: int + :rtype: bool + """ + + # Logic 1: Like literally solving by hand - 100 pass - longer run time... + + # First, Only if hand//W is a digit this should work + # Hacky whole number division logic + divided_parts = len(hand)/float(W) + if ".0" not in str(divided_parts): + return False + + # Second, make sure the list is sorted and remove consecutive numbers + result = [] + + # Size of the each divided section, some scenarios have divided_parts != size_of_each_part + size_of_each_part = len(hand)//int(divided_parts) + + # Iterate until hand remains + while hand: + # Set initials for every divided_parts + num = size_of_each_part # size of each part + hand = sorted(hand) # make sure it is sorted + result.append([]) # append to result list + i = 0 # initialize i to start at beginning every time (scenario of repetitive elements) + while num and i < len(hand): + # Check for repetitive element + if hand[i] not in result[-1]: + # Check for consecutive element + if result[-1] and result[-1][-1]+1 != hand[i]: + return False + result[-1].append(hand.pop(i)) + num -= 1 + else: + # Case of repetitive element + i += 1 + + # Final result check + if len(result) == int(divided_parts): + return True + else: + return False + + """ + # Different approach ---pending... + # Logic 2 - Using some shortcuts for a cleaner logic + + # By default we use the initial condition to beat unnecessary negative scenario cases + + # First, Only if hand//W is a digit this should work + # Hacky whole number division logic + division = len(hand)/float(W) + if ".0" not in str(division): + return False + + result = [] + # Size of each section that we divide + quant = len(hand)//int(division) + + for i in range(int(division)): + hand = set(hand) + select = hand[:quant] + if sum(select) != sum(range(select[0], select[quant])): + return False + result.append(select) + hand = set(hand[quant:]) + """ + + + + + + + diff --git a/ProblemSolving/heightChecker/height.py b/ProblemSolving/heightChecker/height.py new file mode 100644 index 0000000..1a56635 --- /dev/null +++ b/ProblemSolving/heightChecker/height.py @@ -0,0 +1,32 @@ +class Solution(object): + def heightChecker(self, heights): + """ + :type heights: List[int] + :rtype: int + """ + + # Logic 2 + # Looks hacky, I was thinking of just diff the sorted(array) vs array + + s_heights = sorted(heights) + count = 0 + for i in range(len(heights)): + if heights[i] != s_heights[i]: + count += 1 + return count + + """ + # Logic 1 + # As we iterate through the array + # * Record all the irregularities and append to a list + n = len(heights) + students = [] + i = 0 + while i < len(heights): + if (i+1 < len(heights) and heights[i+1] < heights[i]) or (i-1 >= 0 and heights[i-1] > heights[i]): + students.append(heights[i]) + heights.pop(i) + i += 1 + return len(students) + """ + diff --git a/ProblemSolving/highFive/high.py b/ProblemSolving/highFive/high.py new file mode 100644 index 0000000..73be377 --- /dev/null +++ b/ProblemSolving/highFive/high.py @@ -0,0 +1,63 @@ +class Solution(object): + def highFive(self, items): + """ + :type items: List[List[int]] + :rtype: List[List[int]] + """ + + # Logic 1: Create a data structure Dictionary and then solve - 62% faster + + # Build dictionary + students = {} + for item in items: + ide = item[0] + score = item[1] + if ide not in students: + students[ide] = [] + students[ide].append(score) + + # Iterate, sort and solve + result = [] + for k, v in students.items(): + avg = sum(sorted(v)[::-1][:5])//5 + result.append([k, avg]) + return result + + # Logic 2: Sort with custom logic and solve with iteration - 5% faster + """ + def custom_cmp(x1, x2): + # Index match first + if x1[0] < x2[0]: + return -1 + elif x1[0] > x2[0]: + return 1 + else: + # Score match next + if x1[1] < x2[1]: + return 1 + else: + return -1 + + # Sort with custom logic + items = sorted(items, cmp=custom_cmp) + + # Iterate to compute the answer + result = [[]] + for i in range(len(items)): + index = items[i][0] + score = items[i][1] + if len(result[-1]) == 0: + count = 1 + result[-1] = [index, score] + else: + if count < 5: + result[-1][1] += score + count += 1 + if (i+1 < len(items) and items[i][0] != items[i+1][0]) or i == len(items)-1: + result[-1][1] = result[-1][1]//5 + count = 0 + if i+1 < len(items): + result.append([]) + return result + """ + diff --git a/ProblemSolving/houseRobber/house2.py b/ProblemSolving/houseRobber/house2.py new file mode 100644 index 0000000..0ee4412 --- /dev/null +++ b/ProblemSolving/houseRobber/house2.py @@ -0,0 +1,38 @@ +class Solution(object): + def rob(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + + # Logic 1: + # * At each house, propagate the maximum amount that can be robbed alternatively one index or 2 index. + if len(nums) == 0: + return 0 + elif len(nums) == 1: + return nums[0] + max_rob = max(nums[0], nums[1]) + for i in range(2, len(nums)): + nums[i] += max(nums[i-2] if i-2 >= 0 else 0, nums[i-3] if i-3 >=0 else 0) + max_rob = max(max_rob, nums[i]) + print(nums) + return max_rob + + # Things that wont work below! + + # Thoughts 1: get max money index and calculate adjacent from there + #maxi = max(nums) + #huge_money = None + #for i in range(len(nums)): + # if nums[i] == maxi: + # huge_money = i + + # Thoughts 2: Calculate all adjacent from the beginning + """ + if len(nums) < 1: + return 0 + elif len(nums) == 1: + return nums[0] + else: + return max(sum([nums[0],nums[-1]]) if len(nums) > 2 else 0, max(sum([nums[i] for i in range(0, len(nums), 2)]), sum([nums[i] for i in range(1, len(nums), 2)]))) + """ diff --git a/ProblemSolving/houseRobber/house3.py b/ProblemSolving/houseRobber/house3.py new file mode 100644 index 0000000..6aaa18b --- /dev/null +++ b/ProblemSolving/houseRobber/house3.py @@ -0,0 +1,17 @@ +class Solution: + def rob(self, nums: List[int]) -> int: + + max_steals = {} + + def rob(house): + + if house in max_steals: + return max_steals[house] + if house >= len(nums): + return 0 + + max_steals[house] = max(nums[house]+rob(house+2), rob(house+1)) + return max_steals[house] + + rob(0) + return max_steals[0] diff --git a/ProblemSolving/houseRobberIII/rob.py b/ProblemSolving/houseRobberIII/rob.py new file mode 100644 index 0000000..4479fe5 --- /dev/null +++ b/ProblemSolving/houseRobberIII/rob.py @@ -0,0 +1,87 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right +class Solution: + def rob(self, root: Optional[TreeNode]) -> int: + + # Logic: Calculate including and not including parent separately + + memoSteal = {} + memoNoSteal = {} + + #@cache # indirect memo --> 100 pass 68% faster + def recurse(house, parent_stolen): + + if not house: + return 0 + + if parent_stolen: # then children is not stolen, so skip to next + if house in memoNoSteal: + return memoNoSteal[house] + + max_stolen_skipped = 0 + max_stolen_skipped += recurse(house.left, False) + max_stolen_skipped += recurse(house.right, False) + memoNoSteal[house] = max_stolen_skipped + + return memoNoSteal[house] + else: # parent is not stole, so we have choice to steal or not steal children --> calc both to check max + if house in memoSteal: + return memoSteal[house] + + max_stolen_robd = house.val + max_stolen_robd += recurse(house.left, True) + max_stolen_robd += recurse(house.right, True) + + max_stolen_skipped = 0 + max_stolen_skipped += recurse(house.left, False) + max_stolen_skipped += recurse(house.right, False) + + memoSteal[house] = max(max_stolen_robd, max_stolen_skipped) + + return memoSteal[house] + + return recurse(root, False) + + # Logic to decompose problem into adjacent level housing and solving wont work --> 2,1,3,null,4 adds usecase with not directly linked subtree selections + """ + + # 1. level order traverse to get house values by levels + # 2. perform adjacent house method + self.levels = [] + + def traverse(node, level): + + if level >= len(self.levels): + self.levels.append(0) + + self.levels[level] += node.val + + if node.left: + traverse(node.left, level+1) + if node.right: + traverse(node.right, level+1) + + self.memo = {} + + def robN(level): + + if level >= len(self.levels): + return 0 + + if level in self.memo: + return self.memo[level] + + self.memo[level] = max(self.levels[level]+robN(level+2), robN(level+1)) + return self.memo[level] + + traverse(root, 0) + robN(0) + + print(self.memo, self.levels) + return self.memo[0] + """ + diff --git a/ProblemSolving/howManyApplesCanYouPutIntoBasket/how.py b/ProblemSolving/howManyApplesCanYouPutIntoBasket/how.py new file mode 100644 index 0000000..3f9da49 --- /dev/null +++ b/ProblemSolving/howManyApplesCanYouPutIntoBasket/how.py @@ -0,0 +1,46 @@ +class Solution(object): + def maxNumberOfApples(self, arr): + """ + :type arr: List[int] + :rtype: int + """ + + # Logic to maximize the number of apples - 7% faster 100 pass + # 1. Sort the weight of apples + # 2. Remove the last apple (most weight) until weight is lesser than 5000 + arr.sort() + left = 0 + right = len(arr)-1 + while left < right: + if sum(arr[left:right+1]) < 5000: # Return as soon as you find the max num + return right-left+1 + right -= 1 + return 0 + + # This logic is to minimize the number of apples + """ + basket = 3000 + arr.sort(reverse=True) + apples = 0 + for w in arr: + if basket-w < 0: + continue + else: + basket -= w + apples += 1 + return apples + """ + + """ + basket = [] + apples = sorted(arr) + weight = 5000 + for apple in apples: + if weight-apple > 0: + basket.append(apple) + weight -= apple + #print(weight, apple) + else: + break + return len(basket) + """ diff --git a/ProblemSolving/implementPow/pow.py b/ProblemSolving/implementPow/pow.py new file mode 100644 index 0000000..990d9b8 --- /dev/null +++ b/ProblemSolving/implementPow/pow.py @@ -0,0 +1,60 @@ +class Solution(object): + def myPow(self, x, n): + """ + :type x: float + :type n: int + :rtype: float + """ + + # Clean GIST + if n == 0: + return 1 + other_half = 1 + N = abs(n) + if N%2 != 0: + other_half *= x + half_power = self.myPow(x, N//2) + answer = half_power * half_power * other_half + if n < 0: + answer = 1/answer + return answer + + # Logical + ## THE GIST + # Like merge sort, reduce by 2 as we calculate + # If odd change to the nearest even with -1 + """ + self.memo = [1] + def power(x,n): + print(x, n) + if n <= 1: + return 1 + else: + half_pow = power(x, n/2.0) + + + + # Nearest even power + odd = False + if n%2 != 0: + odd = True + n -= 1 + # Reduce to half and build from there + n = n//2 + result = power(x, n) + if odd: + result = x*result + return result + """ + + # Iterative - Time Limit Exceeded + """ + result = 1 + if n < 0: + x = 1/x + n = abs(n) + while n: + result *= x + n -= 1 + return result + """ diff --git a/ProblemSolving/implementQueueUsingStacks/queue2.py b/ProblemSolving/implementQueueUsingStacks/queue2.py new file mode 100644 index 0000000..c594f98 --- /dev/null +++ b/ProblemSolving/implementQueueUsingStacks/queue2.py @@ -0,0 +1,51 @@ +class MyQueue(object): + + def __init__(self): + """ + Initialize your data structure here. + """ + self.stack = [] + + + def push(self, x): + """ + Push element x to the back of queue. + :type x: int + :rtype: None + """ + self.stack.append(x) + + def pop(self): + """ + Removes the element from in front of queue and returns that element. + :rtype: int + """ + if self.stack: + return self.stack.pop(0) + + + def peek(self): + """ + Get the front element. + :rtype: int + """ + return self.stack[0] + + + def empty(self): + """ + Returns whether the queue is empty. + :rtype: bool + """ + if self.stack: + return False + else: + return True + + +# Your MyQueue object will be instantiated and called as such: +# obj = MyQueue() +# obj.push(x) +# param_2 = obj.pop() +# param_3 = obj.peek() +# param_4 = obj.empty() diff --git a/ProblemSolving/implementStrStr/str.py b/ProblemSolving/implementStrStr/str.py new file mode 100644 index 0000000..57dff16 --- /dev/null +++ b/ProblemSolving/implementStrStr/str.py @@ -0,0 +1,14 @@ +class Solution(object): + def strStr(self, haystack, needle): + """ + :type haystack: str + :type needle: str + :rtype: int + """ + + if haystack == needle or not needle: + return 0 + for i in range(len(haystack)): + if haystack[i] == needle[0] and haystack[i:i+len(needle)] == needle: + return i + return -1 diff --git a/ProblemSolving/increasingDecreasingSet/inc.py b/ProblemSolving/increasingDecreasingSet/inc.py new file mode 100644 index 0000000..e26f0b3 --- /dev/null +++ b/ProblemSolving/increasingDecreasingSet/inc.py @@ -0,0 +1,39 @@ +class Solution(object): + def sortString(self, s): + """ + :type s: str + :rtype: str + """ + + sl = list(s) + sl.sort() + + result = "" + #print(sl) + + while sl: + + i = 0 + inc = "" + while i < len(sl): + if inc == "" or (sl and sl[i] != inc[-1]): + inc += sl.pop(i) + else: + i += 1 + + result += inc + #print(inc) + + i = len(sl)-1 + dec = "" + while i >= 0: + #print(i, sl) + if dec == "" or (sl and sl[i] != dec[-1]): + dec += sl.pop(i) + i -= 1 + + result += dec + #print(dec) + + return result + diff --git a/ProblemSolving/increasingTripletSubsequence/triplet.py b/ProblemSolving/increasingTripletSubsequence/triplet.py new file mode 100644 index 0000000..a00e3e6 --- /dev/null +++ b/ProblemSolving/increasingTripletSubsequence/triplet.py @@ -0,0 +1,17 @@ +class Solution: + def increasingTriplet(self, nums: List[int]) -> bool: + + curr_maxis = [-float('inf'), -float('inf'), -float('inf')] + curr = 0 + for i in range(len(nums)-1, -1, -1): + for j in range(3): + if nums[i] >= curr_maxis[j]: + curr_maxis[j] = nums[i] + curr = j + break + print(curr_maxis) + if curr == 2 and curr_maxis != -float('inf'): + return True + + print(curr_maxis) + return False diff --git a/ProblemSolving/insertInterval/ins.py b/ProblemSolving/insertInterval/ins.py new file mode 100644 index 0000000..c8c135f --- /dev/null +++ b/ProblemSolving/insertInterval/ins.py @@ -0,0 +1,38 @@ +class Solution: + def insert(self, intervals: List[List[int]], newInterval: List[int]) -> List[List[int]]: + + def isOverlapped(int1, int2): + if int2[0] <= int1[0] <= int2[1] or int2[0] <= int1[1] <= int2[1]: + return True + elif int1[0] <= int2[0] <= int1[1] or int1[0] <= int2[1] <= int1[1]: + return True + return False + + overLappedIntervals = [] + resultingIntervals = [] + while intervals: + curr = intervals.pop(0) + left = curr[0] + right = curr[1] + if newInterval and isOverlapped(curr, newInterval): + overLappedIntervals.append(curr) + continue + if overLappedIntervals: + intervals = [curr] + intervals + break + if newInterval and newInterval[1] < curr[0]: + resultingIntervals.append(newInterval) + newInterval = [] + resultingIntervals.append(curr) + + if overLappedIntervals: + l = min(overLappedIntervals[0][0], newInterval[0]) + r = max(overLappedIntervals[-1][1], newInterval[1]) + resultingIntervals.append([l,r]) + resultingIntervals.extend(intervals) + return resultingIntervals + + if newInterval: + resultingIntervals.append(newInterval) + + return resultingIntervals diff --git a/ProblemSolving/insertIntoBinarySearchTree/insert.py b/ProblemSolving/insertIntoBinarySearchTree/insert.py new file mode 100644 index 0000000..a5c9d33 --- /dev/null +++ b/ProblemSolving/insertIntoBinarySearchTree/insert.py @@ -0,0 +1,65 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def insertIntoBST(self, root, val): + """ + :type root: TreeNode + :type val: int + :rtype: TreeNode + """ + + # Recursive Solution - Insert a Node + def recurse_insert(node, val): + + # Null node + if not node: + return + + # Guaranteed the node wont exist already so check for only smaller or greater than + # * Left - recurse for left node existence + # * else, add the left node + if val < node.val: + if node.left: + recurse_insert(node.left, val) + else: + node.left = TreeNode(val) + else: + # * Right - recurse for right node existence + # * else, add the right node + if node.right: + recurse_insert(node.right, val) + else: + node.right = TreeNode(val) + + def iterative_insert(node, val): + + # stack to traverse + stack = [node] + + while stack: + current_node = stack.pop(0) + + # Left and Right traverse + if val < current_node.val: + if current_node.left: + stack.append(current_node.left) + else: + current_node.left = TreeNode(val) + return + else: + if current_node.right: + stack.append(current_node.right) + else: + current_node.right = TreeNode(val) + return + + # Function call + recurse_insert(root, val) + #iterative_insert(root, val) + return root + diff --git a/ProblemSolving/integerBreak/int.py b/ProblemSolving/integerBreak/int.py new file mode 100644 index 0000000..3360de5 --- /dev/null +++ b/ProblemSolving/integerBreak/int.py @@ -0,0 +1,48 @@ +class Solution(object): + def integerBreak(self, n): + """ + :type n: int + :rtype: int + """ + + # Hard code minumum value that would be a constant + if n == 2: + return 1 + + # Memoization to maintain a record of max across numbers + memo = [1]*(n+1) + + # Iterate to n+1 so n is calculated for sure + for i in range(2, n+1): + # Calculate the different from 1 to i + for j in range(1, i): + # Compare already existing value vs new difference + calc_max = max(j*memo[i-j], j*(i-j)) + # Store the max difference + memo[i] = max(memo[i], calc_max) + return memo[n] + + + """ + # Logic: Brute force + # * Tried recursive strategy, stuck at places....pending on my own logic. + # * subtract iteratively (as long as atleast 2 + are present) until 0 and record the maximum product + self.memo = [1,1] + + def maxProd(k, current_max): + print self.memo + if k == 1: + return 1 + elif k < len(self.memo): + return self.memo[k] + else: + for i in range(1,k//2+1): + delta = k - i + product = i * maxProd(delta, 0) + if product > current_max: + self.memo.append(product) + return product + + maxProd(n,0) + return self.memo[n] + """ diff --git a/ProblemSolving/integerToRoman/int.py b/ProblemSolving/integerToRoman/int.py new file mode 100644 index 0000000..f02e34b --- /dev/null +++ b/ProblemSolving/integerToRoman/int.py @@ -0,0 +1,44 @@ +class Solution: + def intToRoman(self, num: int) -> str: + + romanNum = "" + + roman = { + 1: "I", + 5: "V", + 10: "X", + 50: "L", + 100: "C", + 500: "D", + 1000: "M" + } + + number = [] + + while num: + n = num%10 + number = [n]+number + num = num//10 + + while number: + n = number.pop(0) + r = 10**len(number) + ns = n*r + + if ns in roman: + romanNum += roman[ns] + print(romanNum, n, r, ns) + continue + + print(romanNum, n, r, ns) + + if n == 4: + romanNum += roman[r] + roman[5*r] + elif n == 9: + romanNum += roman[r] + roman[10*r] + elif n > 5: + romanNum += roman[5*r] + roman[r*1]*(n-5) + else: + romanNum += roman[1*r]*(n) + + return romanNum diff --git a/ProblemSolving/intersectionOfMultipleArrays/intersect.py b/ProblemSolving/intersectionOfMultipleArrays/intersect.py new file mode 100644 index 0000000..8fa8076 --- /dev/null +++ b/ProblemSolving/intersectionOfMultipleArrays/intersect.py @@ -0,0 +1,29 @@ +class Solution: + def intersection(self, nums: List[List[int]]) -> List[int]: + + intersection_logic = {} + sorted_intersection = [] + + for n in nums: + + for k in range(len(n)): + + if n[k] not in intersection_logic: + intersection_logic[n[k]] = 0 + intersection_logic[n[k]] += 1 + + if intersection_logic[n[k]] == len(nums): + if not sorted_intersection: + sorted_intersection = [n[k]] + else: + for i in range(len(sorted_intersection)): + if i == len(sorted_intersection)-1 and sorted_intersection[i] < n[k]: + sorted_intersection.append(n[k]) + break + elif n[k] < sorted_intersection[i]: + sorted_intersection = sorted_intersection[:i] + [n[k]] +sorted_intersection[i:] + break + + print(sorted_intersection,intersection_logic) + + return sorted_intersection diff --git a/ProblemSolving/intersectionOfThreeSortedArrays/intersect.py b/ProblemSolving/intersectionOfThreeSortedArrays/intersect.py new file mode 100644 index 0000000..c1e3593 --- /dev/null +++ b/ProblemSolving/intersectionOfThreeSortedArrays/intersect.py @@ -0,0 +1,65 @@ +class Solution(object): + def arraysIntersection(self, arr1, arr2, arr3): + """ + :type arr1: List[int] + :type arr2: List[int] + :type arr3: List[int] + :rtype: List[int] + """ + + # Logic1: Use SET intersections --> 98% faster + """ + return sorted(set(arr1).intersection(arr2).intersection(arr3)) + """ + + # Logic2: Using SET 'and' functionality --> 86% faster + """ + return sorted(set(arr1) & set(arr2) & set(arr3)) + """ + + # Logic3: Using COLLECTIONS (dictionary) in Python --> 30% faster + """ + return sorted(collections.Counter(arr1) & collections.Counter(arr2) & collections.Counter(arr3)) + """ + + # Logic4: Using naive/only dictionary + iteration method - 51% faster + """ + counter = {} + result = [] + for element in (arr1 + arr2 + arr3): + if element not in counter: + counter[element] = 0 + counter[element] += 1 + if counter[element] == 3: + result.append(element) + return result + """ + + # Logic5: Using iteration ( naive method ) --> Attempted not working + """ + def get_element(array, index): + if index > len(array): + return None + else: + return array[index] + + i = j = k = 0 + result = [] + + while 1: + while arr1[i] != arr2[j] != arr3[k]: + while arr1[i] < arr2[j]: + i += 1 + while arr2[j] < arr3[k]: + j += 1 + while arr3[k] < arr1[i]: + k += 1 + print(arr1[i], arr2[j], arr3[k]) + result.append(arr1[i]) + i += 1 + j += 1 + k += 1 + """ + + + diff --git a/ProblemSolving/intersectionOfTwoArray/inter2.py b/ProblemSolving/intersectionOfTwoArray/inter2.py new file mode 100644 index 0000000..1322bf3 --- /dev/null +++ b/ProblemSolving/intersectionOfTwoArray/inter2.py @@ -0,0 +1,47 @@ +class Solution(object): + def intersection(self, nums1, nums2): + """ + :type nums1: List[int] + :type nums2: List[int] + :rtype: List[int] + """ + + """ + # O(smaller_array) iteration - 30% faster + n = len(nums1) + m = len(nums2) + result = [] + for i in range(n): + if nums1[i] in nums2 and nums1[i] not in result: + result.append(nums1[i]) + return result + """ + + """ + # Logic 1: Set intersection ( set vs set ) - 83% faster + nums1 = set(nums1) + nums2 = set(nums2) + return nums1.intersection(nums2) + """ + + """ + # Logic 2: Set intersection ( set vs list ) - 72% faster + nums1 = set(nums1) + return nums1.intersection(nums2) + """ + + """ + # Logic 3: Dictionary Method - 77% faster + import collections + dic = collections.Counter(list(set(nums1))+list(set(nums2))) + result = [] + for k,v in dic.items(): + if v >= 2 and k not in result: + result.append(k) + return result + """ + + # Logic 4: Binary Search + + + diff --git a/ProblemSolving/intersectionOfTwoArrayII/inter2.py b/ProblemSolving/intersectionOfTwoArrayII/inter2.py new file mode 100644 index 0000000..a0a3480 --- /dev/null +++ b/ProblemSolving/intersectionOfTwoArrayII/inter2.py @@ -0,0 +1,32 @@ +class Solution(object): + def intersect(self, nums1, nums2): + """ + :type nums1: List[int] + :type nums2: List[int] + :rtype: List[int] + """ + + # Logic1: Using collections + """ + import collections + intersect = collections.Counter(nums1) & collections.Counter(nums2) + return intersect.elements() + """ + + # Logic2: Sort and iterate + nums1.sort() + nums2.sort() + i = j = 0 + + result = [] + while i < len(nums1) and j < len(nums2): + if nums1[i] == nums2[j]: + result.append(nums1[i]) + i += 1 + j += 1 + elif nums1 [i] < nums2[j]: + i += 1 + else: + j += 1 + return result + diff --git a/ProblemSolving/intervalListIntersection/interval.py b/ProblemSolving/intervalListIntersection/interval.py new file mode 100644 index 0000000..70302fb --- /dev/null +++ b/ProblemSolving/intervalListIntersection/interval.py @@ -0,0 +1,34 @@ +# Definition for an interval. +# class Interval(object): +# def __init__(self, s=0, e=0): +# self.start = s +# self.end = e + +class Solution(object): + def intervalIntersection(self, A, B): + """ + :type A: List[Interval] + :type B: List[Interval] + :rtype: List[Interval] + """ + + # Logic 1: 2 pointer method - 34% faster + left = right = 0 + result = [] + while left < len(A) and right < len(B): + if A[left][1] == B[right][1]: + if A[left][0] < B[right][0]: + result.append(B[right][0:]) + else: + result.append(A[left][0:]) + left += 1 + right += 1 + elif A[left][1] > B[right][1]: + if A[left][0] <= B[right][1]: + result.append([max(A[left][0],B[right][0]), B[right][1]]) + right += 1 + else: + if B[right][0] <= A[left][1]: + result.append([max(A[left][0],B[right][0]), A[left][1]]) + left += 1 + return result diff --git a/ProblemSolving/islandPerimeter/island.py b/ProblemSolving/islandPerimeter/island.py new file mode 100644 index 0000000..b2bd535 --- /dev/null +++ b/ProblemSolving/islandPerimeter/island.py @@ -0,0 +1,28 @@ +class Solution(object): + def islandPerimeter(self, grid): + """ + :type grid: List[List[int]] + :rtype: int + """ + + # Logic 1: + # * We are assured to have one island with no lakes + # * We just need to find the 1s and if this could be a border. + # * If it is a border it has 0 on that side. + + n = len(grid) + m = len(grid[0]) + + perimeter = 0 + for i in range(n): + for j in range(m): + if grid[i][j] == 1: + for side in [(i+1, j), (i-1, j), (i, j+1), (i, j-1)]: + if side[0] < 0 or side[1] < 0: + perimeter += 1 + elif side[0] >= n or side[1] >= m: + perimeter += 1 + elif grid[side[0]][side[1]] == 0: + perimeter +=1 + return perimeter + diff --git a/ProblemSolving/iteratorOfCombination/iter.py b/ProblemSolving/iteratorOfCombination/iter.py new file mode 100644 index 0000000..f427d20 --- /dev/null +++ b/ProblemSolving/iteratorOfCombination/iter.py @@ -0,0 +1,21 @@ +# Logic 1: Using itertools to get all combinations - 100 pass 86% faster +class CombinationIterator: + + def __init__(self, characters: str, combinationLength: int): + import itertools + self.combinations = list(map("".join, itertools.combinations(characters, r=combinationLength))) + + def next(self) -> str: + return self.combinations.pop(0) + + def hasNext(self) -> bool: + if self.combinations: + return True + return False + +# Logic 2: Without itertools with iterator? + +# Your CombinationIterator object will be instantiated and called as such: +# obj = CombinationIterator(characters, combinationLength) +# param_1 = obj.next() +# param_2 = obj.hasNext() diff --git a/ProblemSolving/jumpGame/jump.py b/ProblemSolving/jumpGame/jump.py new file mode 100644 index 0000000..9982575 --- /dev/null +++ b/ProblemSolving/jumpGame/jump.py @@ -0,0 +1,60 @@ +class Solution(object): + def canJump(self, nums): + """ + :type nums: List[int] + :rtype: bool + """ + + # Logic 0: Works Best and easy to understand - 75% faster + # Ref: https://leetcode.com/problems/jump-game/discuss/535541/Python-super-simple-solution-time%3A-O(N)-space-O(1) --> Good One! + jump_next = 1 # Move index wise to the right + for i in nums[:-1]: # O(N) Iteration - Omit the last element as we want to reach here and not jumo + jump_next = max(jump_next-1, i) # Every move reduce the jump_next as we moved to right and then calculate max jump here + if not jump_next: # Return false if jump becomes 0 + return False + return True + + # Logic 1: BackTrack - You for sure start at index 1 but you can make any jump up until the maximum possible jump to reach the destination - Memory Limit Exceeded ( Almost all passed! - Need optimization ) + self.last_index = len(nums)-1 + self.result = False + + def jump(position, jumps, path): + #print("==>",position, jumps, path, self.last_index) + if position == self.last_index: + if not self.result: + self.result = True + if position not in path: + for current_jump in jumps: + nxt = position + current_jump + path.add(position) + if nxt < len(nums) and nxt not in path: + jump(nxt, range(0, nums[nxt]+1), path) + else: + return + + jump(0, range(0, nums[0]+1), set()) + return self.result + + # Logic NA: BackTrack - Understood the question wrong --> Below logic is for all possible ways to jump to the last index + """ + self.last_index = len(nums)-1 + def jump(nxt, path): + if nxt == self.last_index: + if path: + return True + else: + return False + elif (nxt < len(nums) and nums[nxt] == 0) or nxt > self.last_index: + return False + else: + return jump(nxt+nums[nxt], path+[nxt]) + + for i in range(self.last_index+1): + if i == self.last_index and i == 0: + return True + else: + if jump(i, []): + return True + + return False + """ diff --git a/ProblemSolving/jumpGameVI/optimize_dp.py b/ProblemSolving/jumpGameVI/optimize_dp.py new file mode 100644 index 0000000..591e35d --- /dev/null +++ b/ProblemSolving/jumpGameVI/optimize_dp.py @@ -0,0 +1,30 @@ +# ref: similar to sliding window tech --> https://leetcode.com/problems/jump-game-vi/solution/ +class Solution: + def maxResult(self, nums: List[int], k: int) -> int: + + window = [] # window to hold all previous jump positions + scores = [0]*len(nums) # score at i from 0 + scores[0] = nums[0] # starting point at 0 + window.append(0) + + for i in range(1,len(nums)): + + # contain the window by removing indices where from where the jump cannot happen + while window and window[0] < i-k: + window.pop(0) + + # compute the current score + scores[i] = scores[window[0]] + nums[i] + + # prune window with no max potential + while window and scores[window[-1]] <= scores[i]: + window.pop() + + # update the window + window.append(i) + + return scores[-1] + + + + diff --git a/ProblemSolving/jumpGameVI/recurse_memo.py b/ProblemSolving/jumpGameVI/recurse_memo.py new file mode 100644 index 0000000..91839b3 --- /dev/null +++ b/ProblemSolving/jumpGameVI/recurse_memo.py @@ -0,0 +1,30 @@ +# works but time limit exceeded --> need to cut O(K) in O(NK) +class Solution: + def maxResult(self, nums: List[int], k: int) -> int: + + def play(curr_index, score): + #print(curr_index, score, self.memo) + + if curr_index in self.memo: + #print("in",curr_index, score, self.memo) + return self.memo[curr_index] + + if curr_index == len(nums)-1: + return score + + max_score = -float('inf') + curr_score = 0 + for i in range(1, k+1): + #print("here", curr_index+i) + if curr_index+i >= len(nums): + break + curr_score = play(curr_index+i, nums[curr_index+i]) + if curr_score > max_score: + max_score = curr_score + + #print("there", curr_index, max_score) + self.memo[curr_index] = score+max_score + return score+max_score + + self.memo = {} + return play(0, nums[0]) diff --git a/ProblemSolving/kClosestPointsToOrigin/kclose.py b/ProblemSolving/kClosestPointsToOrigin/kclose.py new file mode 100644 index 0000000..7879afc --- /dev/null +++ b/ProblemSolving/kClosestPointsToOrigin/kclose.py @@ -0,0 +1,58 @@ +class Solution(object): + def kClosest(self, points, K): + """ + :type points: List[List[int]] + :type K: int + :rtype: List[List[int]] + """ + + # 100 pass 976ms + # * A bit lousy logic with a number of datastructure or memory + + # Euclidean distance: Recollecting math... + # * Use Pythagoras Theorem (for a triangle - right angle) + # * Right Angle Triangle has 3 sides --> slanting (diagnal) + horizontal + vertical + # * Diagnal^2 = horizontal_line^2 + vertival_line^2 + # * Diagnal = sqrt(horizontal_line^2 + vertival_line^2) + # * Diagnal = sqrt([x2-x1]^2 + [y2-y1]^2) + # - x1,y1 and x2, y2 are the points connecting the diagnal + + import math # To calc square root + + # Initial point is always the origin (based on the question) + first_point = [0,0] + + # Dictionary to manage the distance vs the points + distances = {} + + # Iterate the next points from given list + for second_point in points: + # Get the x distance from origin + x_dist = first_point[0]-second_point[0] + # Y distance from origin + y_dist = first_point[1]-second_point[1] + # Euc distance calculation + euc_dist = math.sqrt(x_dist**2 + y_dist**2) + # Add relationship between second_point and respective euc_distances in dictionary + if euc_dist not in distances: + distances[euc_dist] = [] + # if More than one value having same euc_distance, so use list + distances[euc_dist].append(second_point) + + # Result list + result = [] + + # Arrange distances to origin is ascending order + closest_to_origin = sorted(distances.keys()) + + # Iterate until we get K elements + while len(result) < K: + # Get first entry from sorted distances + current_closest = closest_to_origin.pop(0) + + # Handle more than one second point having same euc distance + # * Append second points until the result length is less than K + while distances[current_closest] and len(result) < K: + result.append(distances[current_closest].pop(0)) + + return result diff --git a/ProblemSolving/kClosestPointsToOrigin/kclose2.py b/ProblemSolving/kClosestPointsToOrigin/kclose2.py new file mode 100644 index 0000000..f9c0985 --- /dev/null +++ b/ProblemSolving/kClosestPointsToOrigin/kclose2.py @@ -0,0 +1,16 @@ +class Solution(object): + def kClosest(self, points, K): + """ + :type points: List[List[int]] + :type K: int + :rtype: List[List[int]] + """ + + # (a, b) and (0, 0) ==> sqrt((a-0)^2 + (b-0)^2) ==> sqrt(a^2 + b^2) + + def euc_dist(point): + import math + return math.sqrt(point[0]**2 + point[1]**2) + + points = sorted(points, key=lambda x: euc_dist(x)) + return points[:K] diff --git a/ProblemSolving/keanuReeves/keanu.py b/ProblemSolving/keanuReeves/keanu.py new file mode 100644 index 0000000..20f2b52 --- /dev/null +++ b/ProblemSolving/keanuReeves/keanu.py @@ -0,0 +1,61 @@ +# Logic 1 +# * Its about finding the minimum number of cuts with all good possible combination +# * Lets go top down (though a dp problem we add a flavour of something similar to greedy) so we get the max and cut remaining to obtain min + +# Helper function to decide whether the 2 parts of the string are good or not +def good(word): + if word == "": + return False + import collections + counts = collections.Counter(word) + if counts['0'] == counts['1']: + return False + else: + return True + +def cuts(n, word, selected): + # Hold the minimum + mini = n + # Handle to choose the selected word based on the minimum + temp_mini = n + # Iterate all words (greedy way) from the larger word first + for i in range(n, 0, -1): + if good(word[:i]): # the first maximum good substring + temp_selected = [word[:i]] # Append the first word selected + m, s = cuts(n-i, word[i:], temp_selected+[word[i:]]) + mini = min(mini, 1+m) + #print(mini, temp_mini, s, selected) + if mini < temp_mini: + selected = s + # + print(mini, temp_mini, s, selected) + temp_mini = mini + return mini, selected + +def cuts2(n, word, words): + select = list(word) + for i in range(n, 0, -1): + if good(word[:i]): + if not words: + words = [word[:i]] + else: + words.append(word[:i]) + cuts2(n-i, word[i:], words) + print(word[:i],words, select) + if len(words) < len(select): + select = words + return select + else: + break + return select + +def main(): + n = int(input()) + string = str(input()) + select = string + res1 = cuts2(n, string, []) + print(len(res1)) + for r in res1: + if r: + print(r, end=' ') +main() diff --git a/ProblemSolving/keysAndRooms/key.py b/ProblemSolving/keysAndRooms/key.py new file mode 100644 index 0000000..e05fee4 --- /dev/null +++ b/ProblemSolving/keysAndRooms/key.py @@ -0,0 +1,30 @@ +class Solution(object): + def canVisitAllRooms(self, rooms): + """ + :type rooms: List[List[int]] + :rtype: bool + """ + + # Logic 1: Graph method would be feasible to solve this problem + # * Also, recusive approach first + # * (No extra space other than the recurse stack) + + def enter_all_rooms(room_num): + + # To maintain a visited list of rooms, conver the entry of visited rooms to 0 + if rooms[room_num] != 0: + current = rooms[room_num] + rooms[room_num] = 0 + + # Take the keys in each room and open other rooms + for key in current: + enter_all_rooms(key) + + # Room 0 is free to enter + enter_all_rooms(0) + + # If all the rooms are 0 then they are all visited else false + if rooms.count(0) == len(rooms): + return True + else: + return False diff --git a/ProblemSolving/kidsWithGreatestNumOfCandies/kids.py b/ProblemSolving/kidsWithGreatestNumOfCandies/kids.py new file mode 100644 index 0000000..98937a7 --- /dev/null +++ b/ProblemSolving/kidsWithGreatestNumOfCandies/kids.py @@ -0,0 +1,18 @@ +class Solution(object): + def kidsWithCandies(self, candies, extraCandies): + """ + :type candies: List[int] + :type extraCandies: int + :rtype: List[bool] + """ + + # Logic 1: Find maximum and iterate the array to construct result - 100 pass 56% - Probably 2*O(N) --> one to find max and other to iterate for result --> O(N) + greatestNumber = max(candies) + result = [] + for i in range(len(candies)): + becomeGreat = False + if candies[i] + extraCandies >= greatestNumber: + becomeGreat = True + result.append(becomeGreat) + return result + diff --git a/ProblemSolving/kokoEatingBananas/koko.py b/ProblemSolving/kokoEatingBananas/koko.py new file mode 100644 index 0000000..d2348dd --- /dev/null +++ b/ProblemSolving/kokoEatingBananas/koko.py @@ -0,0 +1,40 @@ +class Solution(object): + def minEatingSpeed(self, piles, H): + """ + :type piles: List[int] + :type H: int + :rtype: int + """ + + # Logic: Divide array by half and navigate correspondingly --> Binary Search Method + # * rewriting the same logic below in bs + + # 2 points for binary navigation + left = 1 + right = max(piles) + + # Iterate until left is equal to right + while left < right: + # Mid + mid = (left + right)//2 + # This was interesting reference: https://leetcode.com/problems/koko-eating-bananas/discuss/152324/C%2B%2BJavaPython-Binary-Search + # * sometimes I cant use % or // to test the number of times the pile divides like 11//4 which is 3 + # * Add divisor to the pile (subtract 1) to ensure it divides to one lesser and suffices + if sum((pile+mid-1)//mid for pile in piles) > H: + left = mid+1 + else: + right = mid + return left + + # Logic: Bruteforce - going from 2 to max piles fails (reduce the search --> use binary search to divide by half and navigate) + """ + if len(piles) == H: + return max(piles) + elif len(piles) < H: + for i in range(2, max(piles)): + if sum(list((pile+i-1)//i for pile in piles)) == H: + return i + else: + return "Cannot eat when len(piles) > H...!" + """ + diff --git a/ProblemSolving/kthLargestInAStream/kth.py b/ProblemSolving/kthLargestInAStream/kth.py index d6f2d8e..7f48803 100644 --- a/ProblemSolving/kthLargestInAStream/kth.py +++ b/ProblemSolving/kthLargestInAStream/kth.py @@ -1,4 +1,45 @@ +# 100 pass - Logic to sort only initially +# * Every add will be iterated across the k length array +class KthLargest(object): + + def __init__(self, k, nums): + """ + :type k: int + :type nums: List[int] + """ + + # initialize stream we need to use in the function + # * We only require k elements from the start, sort once and add everything later + self.nums = sorted(nums, reverse=True)[:k] + self.k = k-1 + + def add(self, val): + """ + :type val: int + :rtype: int + """ + + # Null criteria + if not self.nums: + self.nums = [val] + return val + + i = 0 + while i < len(self.nums) and self.nums[i] > val: + i += 1 + + self.nums = self.nums[:i] + [val] + self.nums[i:] + self.nums = self.nums[:self.k+1] + + return self.nums[self.k] + +# Your KthLargest object will be instantiated and called as such: +# obj = KthLargest(k, nums) +# param_1 = obj.add(val) + +""" # Pending -- time limit exceeded +# * Sorting everytime add is called doesnt make sense! class KthLargest(object): def __init__(self, k, nums): @@ -30,3 +71,4 @@ def add(self, val): # Your KthLargest object will be instantiated and called as such: # obj = KthLargest(k, nums) # param_1 = obj.add(val) +""" diff --git a/ProblemSolving/kthLargestInAnArray/kth.py b/ProblemSolving/kthLargestInAnArray/kth.py new file mode 100644 index 0000000..866f660 --- /dev/null +++ b/ProblemSolving/kthLargestInAnArray/kth.py @@ -0,0 +1,56 @@ +class Solution(object): + def findKthLargest(self, nums, k): + """ + :type nums: List[int] + :type k: int + :rtype: int + """ + + # One line hack using sorted method - 97% + #return sorted(nums, reverse=True)[k-1] + + # Merge Sort and Select - 30% + def mergeSort(arr): + if len(arr) > 1: + #print arr + # Divide the array + n = len(arr)//2 + + # Split array into left and right + left = arr[:n] + right = arr[n:] + + # Recursive call + mergeSort(left) + mergeSort(right) + + i = j = k = 0 + + while i < len(left) and j < len(right): + if left[i] < right[j]: + arr[k] = left[i] + i += 1 + else: + arr[k] = right[j] + j += 1 + k += 1 + + while i < len(left): + arr[k] = left[i] + i += 1 + k += 1 + + while j < len(right): + arr[k] = right[j] + j += 1 + k += 1 + + return arr + else: + return arr + + return mergeSort(nums)[-k] + + + + diff --git a/ProblemSolving/kthLargestInAnArray/quick_select.py b/ProblemSolving/kthLargestInAnArray/quick_select.py new file mode 100644 index 0000000..b500b56 --- /dev/null +++ b/ProblemSolving/kthLargestInAnArray/quick_select.py @@ -0,0 +1,57 @@ +class Solution: + def findKthLargest(self, nums: List[int], k: int) -> int: + + # Leveraging quick_select (kth smallest/largest in unordered list) + + def find_largest_k(nums, k): + + # select any pivot + pivot = nums[0] + + greater = [] + smaller = [] + equal = [] + + for i in range(len(nums)): + if nums[i] > pivot: + greater.append(nums[i]) + elif nums[i] < pivot: + smaller.append(nums[i]) + else: + equal.append(nums[i]) + + if k <= len(greater): + return find_largest_k(greater, k) + + if len(greater) + len(equal) < k: + return find_largest_k(smaller, k - len(greater) - len(equal)) + + return pivot + + def find_smaller_k(nums, k): + + # select any pivot + pivot = nums[0] + + greater = [] + smaller = [] + equal = [] + + for i in range(len(nums)): + if nums[i] > pivot: + greater.append(nums[i]) + elif nums[i] < pivot: + smaller.append(nums[i]) + else: + equal.append(nums[i]) + + if k <= len(smaller): + return find_smaller_k(smaller, k) + + if len(smaller) + len(equal) < k: + return find_smaller_k(greater, k - len(smaller) - len(equal)) + + return pivot + + print(find_smaller_k(nums, k)) + return find_largest_k(nums, k) diff --git a/ProblemSolving/kthLexicographicalStringOfAllHappyStringsofN/kth.py b/ProblemSolving/kthLexicographicalStringOfAllHappyStringsofN/kth.py new file mode 100644 index 0000000..4f90d66 --- /dev/null +++ b/ProblemSolving/kthLexicographicalStringOfAllHappyStringsofN/kth.py @@ -0,0 +1,29 @@ +class Solution: + def getHappyString(self, n: int, k: int) -> str: + + self.allowed = ["a", "b", "c"] + self.total = [] + self.n = n + + def backtrack(current, lastInd, totalInd): + if self.n == len(current): + self.total.append(current) + return + + if len(current) > self.n: + return + + for i in range(len(self.allowed)): + if lastInd == i: + continue + backtrack(current + self.allowed[i], i, totalInd+i) + + + for i in range(len(self.allowed)): + backtrack(self.allowed[i], i, i) + + print(self.total) + if k > len(self.total): + return "" + + return self.total[k-1] diff --git a/ProblemSolving/kthSmallestElementInABst/kth2.py b/ProblemSolving/kthSmallestElementInABst/kth2.py new file mode 100644 index 0000000..9f915eb --- /dev/null +++ b/ProblemSolving/kthSmallestElementInABst/kth2.py @@ -0,0 +1,26 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right +class Solution: + def kthSmallest(self, root: Optional[TreeNode], k: int) -> int: + + def inOrder(node, order): + + if node.left: + inOrder(node.left, order) + + order += [node.val] + + if node.right: + inOrder(node.right, order) + + return order + + + order = inOrder(root, []) + #print(order) + + return order[k-1] diff --git a/ProblemSolving/largestPerimeterTriangle/largestPerimeter.py b/ProblemSolving/largestPerimeterTriangle/largestPerimeter.py new file mode 100644 index 0000000..5a5201f --- /dev/null +++ b/ProblemSolving/largestPerimeterTriangle/largestPerimeter.py @@ -0,0 +1,73 @@ +class Solution(object): + def largestPerimeter(self, A): + """ + :type A: List[int] + :rtype: int + """ + + # Helper Methods + + def validTriangle(sides): + if (sides[0] + sides[1] > sides[2]) and (sides[2] + sides[1] > sides[0]) and (sides[0] + sides[2] > sides[1]): + return True + return False + + def area(sides): + # Implement Herons Formula for finding area with sides + # Reference: https://www.mathopenref.com/heronsformula.html + import math + perimeter = sum(sides) + p = perimeter/2.0 + area = p*(p-sides[0])*(p-sides[1])*(p-sides[2]) + if area > 0: + return perimeter, True + else: + return perimeter, False + + + # Logic 1: Brute force formula with combinations to go over all the combinations - 100 pass but TimeLimitExceeded on last test case + """ + import itertools + maxi = 0 + for sides in itertools.combinations(A, r=3): + if validTriangle(sides): + perimeter, valid = area(sides) + if valid: + maxi = max(maxi, perimeter) + return maxi + """ + + # Logic 2: Full iteration easier to sort the array of sides and return the first maximum valid triangle - 100 pass but TimeLimitExceeded on last test case + """ + A = sorted(A, reverse=True) + maxi = 0 + for i in range(len(A)-2): + for j in range(i+1, len(A)-1): + for k in range(j+1, len(A)): + sides = [A[i], A[j], A[k]] + #print(sides) + if validTriangle(sides): + perimeter, valid = area(sides) + if valid: + #maxi = max(maxi, perimeter) + return perimeter + return 0 + """ + + # Logic 3: Modify the worst case iteration into a single iteration with the sides being next to each other, this wont pass if there occurs combinations of sides that are valid across various ends of the array - 100% pass 97% faster + + A = sorted(A, reverse=True) + maxi = 0 + for i in range(0, len(A)-2): + sides = [A[i], A[i+1], A[i+2]] + print(sides) + if validTriangle(sides): + perimeter, valid = area(sides) + if valid: + return perimeter + return 0 + + + + + diff --git a/ProblemSolving/largestPlusSign/plus.py b/ProblemSolving/largestPlusSign/plus.py new file mode 100644 index 0000000..80be5f3 --- /dev/null +++ b/ProblemSolving/largestPlusSign/plus.py @@ -0,0 +1,62 @@ +class Solution: + # Logic 1: + # 1. Iterate row wise + # * iterate forward and reverse to get the distance with no mines + # 2. Iterate column wise + # * similar + # During the last iteration you should get the answer + def orderOfLargestPlusSign(self, N: int, mines: List[List[int]]) -> int: + # 1. Create a 2d map and mark mines + twod = [[0]*N for i in range(N)] + mineLoc = set() + for mine in mines: + mineLoc.add(tuple(mine)) + big = 0 + # 2. The possibilities are only in the center except the corners. So we backtrack on every selection? + + # row-wise iterate + for r in range(N): + # Forward + no_mine = 0 + for c in range(N): + if (r, c) in mineLoc: + no_mine = 0 + else: + no_mine += 1 + + twod[r][c] = no_mine + + # reverse + no_mine = 0 + for c in range(N-1, -1, -1): + if (r, c) in mineLoc: + no_mine = 0 + else: + no_mine += 1 + + twod[r][c] = min(no_mine, twod[r][c]) + + # column-wise iterate + for c in range(N): + # Forward + no_mine = 0 + for r in range(N): + if (r, c) in mineLoc: + no_mine = 0 + else: + no_mine += 1 + + twod[r][c] = min(no_mine, twod[r][c]) + + # reverse + no_mine = 0 + for r in range(N-1, -1, -1): + if (r, c) in mineLoc: + no_mine = 0 + else: + no_mine += 1 + + twod[r][c] = min(no_mine, twod[r][c]) + big = max(big, twod[r][c]) + + return big diff --git a/ProblemSolving/largestTimeFromDigits/large.py b/ProblemSolving/largestTimeFromDigits/large.py index e7db1d4..fbc6976 100644 --- a/ProblemSolving/largestTimeFromDigits/large.py +++ b/ProblemSolving/largestTimeFromDigits/large.py @@ -4,7 +4,86 @@ def largestTimeFromDigits(self, A): :type A: List[int] :rtype: str """ + # Logic: I was using permutations from before, but happened to try to reduce the num of iterations + # * This logic would iterate through the full permutation list everytime + # * Reference: https://leetcode.com/problems/largest-time-for-given-digits/discuss/211540/Python-simple-obvious-solution + # Get all permutations as usual, store in reverse order to get max hour and corresponding minute + import itertools + all_perm = sorted([i for i in itertools.permutations(A, r=4)], reverse=True) + + # Iterate through all permutations + for perm in all_perm: + + # Max hour being first 2 and corresponding minute being the last 2 + hour = str(perm[0])+str(perm[1]) + minute = str(perm[2])+str(perm[3]) + + # Check for aprropriate hour and minute + if int(hour) < 24 and int(minute) < 60: + return hour+":"+minute + + # Return for null cases + return "" + + """ + # Convert list to dictionary for faster lookup + import collections + As = collections.Counter(A) + + time = "" + + # To find the max hours, Iterating backwards for max hours + for i in range(23,-1,-1): + if len(str(i)) == 1: + i = str("0")+str(i) + else: + i = str(i) + # Hour found + if int(i[0]) in As and int(i[1]) in As: + print i, As + if (i[0] == i[1] and As[int(i[0])] > 1) or i[0] != i[1]: + time = i + if As[int(i[0])] > 1: + As[int(i[0])] -= 1 + else: + del As[int(i[0])] + if As[int(i[1])] > 1: + As[int(i[1])] -= 1 + else: + del As[int(i[1])] + break + + + if time == "": + return "" + + print time, As + time += ":" + minute = As.keys() + + if len(minute) == 1: + minute = str(minute[0])*2 + if int(minute) > 59: + return "" + time += minute + else: + minute = max(int(str(minute[0])+str(minute[1])), int(str(minute[1])+str(minute[0]))) + if minute > 59: + minute = str(minute)[::-1] + if int(minute) > 59: + return "" + time += str(minute) + + return time + """ + +""" +class Solution(object): + def largestTimeFromDigits(self, A): + # :type A: List[int] + # :rtype: str + # From the given array # * Get all the 2 digit number arranged in the descending order # * Highest delta from 24 would be the maximum hour @@ -27,9 +106,6 @@ def largestTimeFromDigits(self, A): hmax = i hmax = - - - """ # Single loop logic - try it import itertools max_hour = 24 @@ -56,6 +132,6 @@ def largestTimeFromDigits(self, A): return str(hmax)+":"+str(Mmax) else: return "" - """ +""" diff --git a/ProblemSolving/largestUniqueNumber/large.py b/ProblemSolving/largestUniqueNumber/large.py new file mode 100644 index 0000000..dc110ea --- /dev/null +++ b/ProblemSolving/largestUniqueNumber/large.py @@ -0,0 +1,10 @@ +# 100 pass +class Solution: + def largestUniqueNumber(self, A: List[int]) -> int: + import collections + maxi_uniq_val = -1 + counts = collections.Counter(A) + for val, count in counts.items(): + if count == 1 and val > maxi_uniq_val: + maxi_uniq_val = val + return maxi_uniq_val diff --git a/ProblemSolving/largestValuesFromLabels/large.py b/ProblemSolving/largestValuesFromLabels/large.py new file mode 100644 index 0000000..823198e --- /dev/null +++ b/ProblemSolving/largestValuesFromLabels/large.py @@ -0,0 +1,35 @@ +# Logic1: Literally following the problem with worst case complexity --> time limit exceeded (otherwise passes all case) + +class Solution(object): + def largestValsFromLabels(self, values, labels, num_wanted, use_limit): + """ + :type values: List[int] + :type labels: List[int] + :type num_wanted: int + :type use_limit: int + :rtype: int + """ + + indexes = range(0,len(values)) + maxi = -60000 + import itertools + for S in range(num_wanted+1): + for subset in itertools.combinations(indexes, r=S): + subset_label = [] + subset_values = [] + for item in subset: + subset_label.append(labels[item]) + subset_values.append(values[item]) + import collections + counts = collections.Counter(subset_label) + y = 0 + for c in counts.values(): + if c <= use_limit: + y += 1 + #print subset, subset_label, subset_values + if y == len(counts.keys()): + if sum(subset_values) > maxi: + maxi = sum(subset_values) + return maxi + + diff --git a/ProblemSolving/lastMomentBeforeAllAntsFallOutOfAPlank/time.py b/ProblemSolving/lastMomentBeforeAllAntsFallOutOfAPlank/time.py new file mode 100644 index 0000000..b48210a --- /dev/null +++ b/ProblemSolving/lastMomentBeforeAllAntsFallOutOfAPlank/time.py @@ -0,0 +1,21 @@ +class Solution: + def getLastMoment(self, n: int, left: List[int], right: List[int]) -> int: + last = first = -1 + if left: + last = max(left) + if right: + first = min(right) + if last == -1: + return n-first + if first == -1: + return last + + move = 0 + for i in range(n): + last -= 1 + first += 1 + if last < 0 and first > n: + return move + move += 1 + + return move diff --git a/ProblemSolving/lastStoneWeight/last.py b/ProblemSolving/lastStoneWeight/last.py new file mode 100644 index 0000000..668d041 --- /dev/null +++ b/ProblemSolving/lastStoneWeight/last.py @@ -0,0 +1,33 @@ +class Solution(object): + def lastStoneWeight(self, stones): + """ + :type stones: List[int] + :rtype: int + """ + + # Logic 1: BruteForce with the sorted function - 22.50% faster + + while len(stones) > 1: + + # 1. Sort the stones in decreasing order + stones = sorted(stones, reverse=True) + + print stones + + # 2. Get the first 2 stones + first = stones.pop(0) + second = stones.pop(0) + + # 3. Smashing the stones + if first == second: + if 0 not in stones: + stones.append(0) + else: + stones.append(abs(first-second)) + + # 4. Reorder the stones again while you enter the loop + + return stones[0] + + + # Different sorted logic? diff --git a/ProblemSolving/lastStoneWeight/last2.py b/ProblemSolving/lastStoneWeight/last2.py new file mode 100644 index 0000000..5858420 --- /dev/null +++ b/ProblemSolving/lastStoneWeight/last2.py @@ -0,0 +1,20 @@ +class Solution(object): + def lastStoneWeight(self, stones): + """ + :type stones: List[int] + :rtype: int + """ + + while len(stones) > 1: + print(stones) + stones = sorted(stones) + maxi1 = stones[-1] + maxi2 = stones[-2] + smash = abs(maxi1 - maxi2) + stones = stones[:-2] + if smash: + stones.append(smash) + if stones: + return stones[0] + else: + return 0 diff --git a/ProblemSolving/leafSimilarTrees/leaf.py b/ProblemSolving/leafSimilarTrees/leaf.py new file mode 100644 index 0000000..a20f4a4 --- /dev/null +++ b/ProblemSolving/leafSimilarTrees/leaf.py @@ -0,0 +1,67 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def leafSimilar(self, root1, root2): + """ + :type root1: TreeNode + :type root2: TreeNode + :rtype: bool + """ + + # Dictionary to store the value of the leaves for each tree + self.leaves = { + root1: [], + root2: [] + } + + # Null check + if not root1 or not root2: + return False + + # Traverse tree function + def get_leaves(root, node): + + # debug + """ + print node.val + if node.left: + print node.left.val + if node.right: + print node.right.val + print "debug end!" + """ + + # When node is None check + if not node: + return + + # detect Children + if node.left == None and node.right == None: + self.leaves[root].append(node.val) + + # Traverse nodes (Lesson: Use if loops not elif/else as it looks for only one possibility as we traverse) + if node.left: + get_leaves(root, node.left) + if node.right: + get_leaves(root, node.right) + + + get_leaves(root1, root1) + get_leaves(root2, root2) + + # Debug + #print self.leaves[root1], self.leaves[root2] + + if self.leaves[root1] == self.leaves[root2]: + return True + else: + return False + + #else: + # leaf ==> [node.left == None and node.right == None] + # self.leaves[root].append(node.val) diff --git a/ProblemSolving/leetContest1BiWeekly/hexSpeak.py b/ProblemSolving/leetContest1BiWeekly/hexSpeak.py new file mode 100644 index 0000000..5e25aa9 --- /dev/null +++ b/ProblemSolving/leetContest1BiWeekly/hexSpeak.py @@ -0,0 +1,27 @@ +""" +A decimal number can be converted to its Hexspeak representation by first converting it to an uppercase hexadecimal string, then replacing all occurrences of the digit 0 with the letter O, and the digit 1 with the letter I. Such a representation is valid if and only if it consists only of the letters in the set {"A", "B", "C", "D", "E", "F", "I", "O"}. + +Given a string num representing a decimal integer N, return the Hexspeak representation of N if it is valid, otherwise return "ERROR". + + + +Example 1: + +Input: num = "257" +Output: "IOI" +Explanation: 257 is 101 in hexadecimal. +Example 2: + +Input: num = "3" +Output: "ERROR" +""" +class Solution: + def toHexspeak(self, num: str) -> str: + valid = set(["A", "B", "C", "D", "E", "F", "I", "O"]) + hexi = hex(int(num))[2:] + hexi = hexi.replace("0", "O") + hexi = hexi.replace("1", "I") + for ch in hexi: + if ch.isdigit(): + return "ERROR" + return hexi.upper() diff --git a/ProblemSolving/lengthOfLastWord/len2.py b/ProblemSolving/lengthOfLastWord/len2.py new file mode 100644 index 0000000..c753f35 --- /dev/null +++ b/ProblemSolving/lengthOfLastWord/len2.py @@ -0,0 +1,3 @@ +class Solution: + def lengthOfLastWord(self, s: str) -> int: + return len(s.strip().split(" ")[-1]) # 43ms diff --git a/ProblemSolving/letterCombinationsOfAPhoneNumber/letter.py b/ProblemSolving/letterCombinationsOfAPhoneNumber/letter.py new file mode 100644 index 0000000..38e094b --- /dev/null +++ b/ProblemSolving/letterCombinationsOfAPhoneNumber/letter.py @@ -0,0 +1,74 @@ +class Solution(object): + def letterCombinations(self, digits): + """ + :type digits: str + :rtype: List[str] + """ + + # define number keys vs alphabets relation with datastructure + keys = { + "2": ["a", "b", "c"], + "3": ["d", "e", "f"], + "4": ["g", "h", "i"], + "5": ["j", "k", "l"], + "6": ["m", "n", "o"], + "7": ["p", "q", "r", "s"], + "8": ["t", "u", "v"], + "9": ["w", "x", "y", "z"] + } + + # Logic 1: Using itertools - 94% faster + """ + import itertools + combs = [] + result = [] + if not digits: + return [] + for d in digits: + combs.append(keys[d]) + for cmb in itertools.product(*combs): + result.append("".join(cmb)) + return result + """ + + # Logic 2: Backtrack - 45% faster + def backtrack(combination, remaining, result): + if remaining: + current = remaining[0] + remaining = remaining[1:] + if current in keys: + for key in keys[current]: + backtrack(combination+key, remaining, result) + return + else: + if combination: + result.append(combination) + return + + result = [] + backtrack("", digits, result) + return result + +""" +# Old logic worked out before a year but still works! +class Solution(object): + def letterCombinations(self, digits): + """ + :type digits: str + :rtype: List[str] + """ + import itertools + keys = [['+'],[''],['a','b','c'],['d','e','f'],['g','h','i'],['j','k','l'],['m','n','o'],['p','q','r','s'],['t','u','v'],['w','x','y','z']] + select = [] + result = [] + + for n in digits: + select.append(keys[int(n)]) + + if len(select) == 0: + return [] + + for comb in itertools.product(*select): + result.append("".join(comb)) + return result +""" diff --git a/ProblemSolving/letterCombinationsOfAPhoneNumber/letter2.py b/ProblemSolving/letterCombinationsOfAPhoneNumber/letter2.py new file mode 100644 index 0000000..b449881 --- /dev/null +++ b/ProblemSolving/letterCombinationsOfAPhoneNumber/letter2.py @@ -0,0 +1,40 @@ +class Solution: + def letterCombinations(self, digits: str) -> List[str]: + + letters = [ + [], + [], + ["a","b","c"], + ["d", "e", "f"], + ["g","h","i"], + ["j","k","l"], + ["m","n","o"], + ["p","q","r","s"], + ["t","u","v"], + ["w","x","y","z"] + ] + self.result = [] + + def backtrack(digits, selected): + + if not digits: + self.result.append(selected) + return + + d = digits[0] + if len(digits) > 1: + digits = digits[1:] + else: + digits = [] + + current = letters[int(d)] + + for l in current: + backtrack(digits, selected+l) + + if not digits: + return [] + + backtrack(digits, "") + return self.result + diff --git a/ProblemSolving/letterTilePossibilities/letter.py b/ProblemSolving/letterTilePossibilities/letter.py new file mode 100644 index 0000000..d1ea443 --- /dev/null +++ b/ProblemSolving/letterTilePossibilities/letter.py @@ -0,0 +1,29 @@ +import copy + +class Solution: + def numTilePossibilities(self, tiles: str) -> int: + + cache = {} + for i in range(len(tiles)): + t = tiles[i] + if t not in cache: + cache[t] = 0 + cache[t] += 1 + + # single + self.n = len(cache) + + def backtrack(comb, exists, remaining): + if len(comb) > 1 and comb not in exists: + exists.add(comb) + #print(exists) + self.n += 1 + for k, v in remaining.items(): + if v == 0: + continue + newr = copy.deepcopy(remaining) + newr[k] -= 1 + backtrack(comb+k, exists, newr) + + backtrack("", set(), cache) + return self.n diff --git a/ProblemSolving/letterTilesPossibilities/letter.py b/ProblemSolving/letterTilesPossibilities/letter.py new file mode 100644 index 0000000..6d1a8bf --- /dev/null +++ b/ProblemSolving/letterTilesPossibilities/letter.py @@ -0,0 +1,16 @@ +class Solution(object): + def numTilePossibilities(self, tiles): + """ + :type tiles: str + :rtype: int + """ + + def backtrack(labels, path, res): + if path and path not in res: + res.add(path) + for i in range(len(labels)): + backtrack(labels[:i]+labels[i+1:], path+labels[i], res) + + result = set() + backtrack(tiles, "", result) + return len(result) diff --git a/ProblemSolving/levelOrderTraversal/level2.py b/ProblemSolving/levelOrderTraversal/level2.py new file mode 100644 index 0000000..45144aa --- /dev/null +++ b/ProblemSolving/levelOrderTraversal/level2.py @@ -0,0 +1,30 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def levelOrder(self, root): + """ + :type root: TreeNode + :rtype: List[List[int]] + """ + + if not root: + return [] + stack = [root] + result = [] + while stack: + result.append([]) + n = len(stack) + while n: + current = stack.pop(0) + result[-1].append(current.val) + if current.left: + stack.append(current.left) + if current.right: + stack.append(current.right) + n -= 1 + return result diff --git a/ProblemSolving/lexicographicallySmallestEquivalentString/lexi.py b/ProblemSolving/lexicographicallySmallestEquivalentString/lexi.py new file mode 100644 index 0000000..ede38ee --- /dev/null +++ b/ProblemSolving/lexicographicallySmallestEquivalentString/lexi.py @@ -0,0 +1,35 @@ +class Solution: + def smallestEquivalentString(self, s1: str, s2: str, baseStr: str) -> str: + + def getAllEqui(c, graph, visited): + for nxt in graph[c]: + if nxt in visited: + continue + visited.add(nxt) + getAllEqui(nxt, graph, visited) + return visited + + graph = {} + + if len(s1) != len(s2): + return baseStr + + for i in range(len(s1)): + if s1[i] not in graph: + graph[s1[i]] = {s1[i]} + if s2[i] not in graph: + graph[s2[i]] = {s2[i]} + graph[s1[i]].add(s2[i]) + graph[s2[i]].add(s1[i]) + + equiLex = "" + for i in range(len(baseStr)): + if baseStr[i] not in graph: + equiLex += baseStr[i] + continue + visited = set() + getAllEqui(baseStr[i], graph, visited) + equiLex += sorted(visited)[0] + print(baseStr[i], visited, equiLex) + + return equiLex diff --git a/ProblemSolving/licenseKeyFormatting/lic2.py b/ProblemSolving/licenseKeyFormatting/lic2.py new file mode 100644 index 0000000..7b2b8b7 --- /dev/null +++ b/ProblemSolving/licenseKeyFormatting/lic2.py @@ -0,0 +1,24 @@ +class Solution(object): + def licenseKeyFormatting(self, S, K): + """ + :type S: str + :type K: int + :rtype: str + """ + + S = S.upper() + sub = S.split("-") + result = "" + + while sub: + nxt = sub.pop() + while sub and len(nxt) < K: + nxt = sub.pop() + nxt + if nxt: + if len(nxt) > K: + sub.append(nxt[:-K]) + nxt = nxt[-K:] + if result: + result = "-" + result + result = nxt + result + return result diff --git a/ProblemSolving/licenseKeyFormatting/lic3.py b/ProblemSolving/licenseKeyFormatting/lic3.py new file mode 100644 index 0000000..11ad8d5 --- /dev/null +++ b/ProblemSolving/licenseKeyFormatting/lic3.py @@ -0,0 +1,45 @@ +class Solution: + def licenseKeyFormatting(self, s: str, k: int) -> str: + + # Logic 1: Naive iteration - 100 & 5% faster + result = "" + + while s: + temp = k + while temp and s: + current = s[-1].upper() + s = s[:-1] + if current == "-": + continue + result = current + result + temp -= 1 + while s and s[0] == "-": + s = s[1:] + if temp == 0 and s: + result = "-" + result + #print(result, s) + return result + +""" +class Solution: + def licenseKeyFormatting(self, s: str, k: int) -> str: + # Logic 2: + + result = "" + sgroup = s.upper()#.replace("-","") + while sgroup: + temp = k + while sgroup and temp: + current = sgroup[-1] + if current == "-": + sgroup = sgroup[:-1] + continue + sgroup = sgroup[:-1] + result = current + result + temp -= 1 + while sgroup and sgroup[-1] == "-": + sgroup = sgroup[:-1] + if sgroup: + result = "-" + result + return result +""" diff --git a/ProblemSolving/loggerRateLimiter/log.py b/ProblemSolving/loggerRateLimiter/log.py new file mode 100644 index 0000000..73c9ec2 --- /dev/null +++ b/ProblemSolving/loggerRateLimiter/log.py @@ -0,0 +1,34 @@ +# Logic 1: Using dictionary to store message and timestamp - 100 pass - 92% faster +class Logger(object): + + def __init__(self): + """ + Initialize your data structure here. + """ + + # Track message with the second it was first displayed + # "message": "seconds of first display" + self.messages = {} + + + def shouldPrintMessage(self, timestamp, message): + """ + Returns true if the message should be printed in the given timestamp, otherwise returns false. + If this method returns false, the message will not be printed. + The timestamp is in seconds granularity. + :type timestamp: int + :type message: str + :rtype: bool + """ + + if message in self.messages and timestamp-self.messages[message] < 10: + return False + else: + self.messages[message] = timestamp + return True + + + +# Your Logger object will be instantiated and called as such: +# obj = Logger() +# param_1 = obj.shouldPrintMessage(timestamp,message) diff --git a/ProblemSolving/longestAbsoluteFilePath/long.py b/ProblemSolving/longestAbsoluteFilePath/long.py new file mode 100644 index 0000000..befb936 --- /dev/null +++ b/ProblemSolving/longestAbsoluteFilePath/long.py @@ -0,0 +1,66 @@ +class Solution(object): + def lengthLongestPath(self, inputs): + """ + :type input: str + :rtype: int + """ + + # Logic 1: Dictionary or Json way of storing stuff + dirs = {} + n = len(inputs) + key = "" + inputs = list(inputs) + parents = [] + nest = 0 + maxi = 0 + result = [] + #if n == 1: + # return 0 + ws = 0 + while inputs: + if len(inputs) >= 2 and inputs[0] == "\n": + inputs.pop(0) + #if not parents: + # parents.append(key) + if nest: + parents = parents[:nest] + else: + parents = [] + nest = 0 + if len(inputs) > 4 and "".join(inputs[:4]) == " "*4: + inputs = ["\t"] + inputs[4:] + #print("hi") + while inputs[0] == "\t": + inputs.pop(0) + nest += 1 + if not nest: + key = key.strip() + parents.append(key) + key = "" + ws = 0 + else: + if inputs[0] == " ": + #if key: + if nest: + key += inputs[0] + elif not parents and key: + key += inputs[0] + #else: + #ws += 1 + inputs.pop(0) + else: + key += inputs.pop(0) + if not inputs and key: + if nest: + parents = parents[:nest] + parents.append(key) + if parents and "." in parents[-1] and len("/".join(parents)) > maxi: + maxi = len("/".join(parents)) + result = "/".join(parents) + print(parents, nest, key) + print(result) + if ws//4 >= 1: + ws = ws//4 -1 + else: + ws = 0 + return len(result) diff --git a/ProblemSolving/longestCommonPrefix/lcp2.py b/ProblemSolving/longestCommonPrefix/lcp2.py new file mode 100644 index 0000000..65fa144 --- /dev/null +++ b/ProblemSolving/longestCommonPrefix/lcp2.py @@ -0,0 +1,14 @@ +class Solution(object): + def longestCommonPrefix(self, strs): + """ + :type strs: List[str] + :rtype: str + """ + + prefix = "" + for i in zip(*strs): + if len(set(i)) == 1: + prefix += i[0] + else: + break + return prefix diff --git a/ProblemSolving/longestConsecutiveSequence/better.py b/ProblemSolving/longestConsecutiveSequence/better.py new file mode 100644 index 0000000..0bc13a7 --- /dev/null +++ b/ProblemSolving/longestConsecutiveSequence/better.py @@ -0,0 +1,19 @@ +class Solution: + # 2*O(n) == O(n), add elements to memory and check for consecutive as we visit each one + def longestConsecutive(self, nums: List[int]) -> int: + visited = {} # can use set also + maxi = 0 + for i in nums: + visited[i] = True + for i in nums: + if i-1 in visited: + continue + current = i + longest = 0 + while current in visited: + longest += 1 + current += 1 + if longest > maxi: + maxi = longest + return maxi + diff --git a/ProblemSolving/longestConsecutiveSequence/long.py b/ProblemSolving/longestConsecutiveSequence/long.py new file mode 100644 index 0000000..1f15621 --- /dev/null +++ b/ProblemSolving/longestConsecutiveSequence/long.py @@ -0,0 +1,25 @@ +class Solution(object): + def longestConsecutive(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + + if not nums: + return 0 + + nums.sort() + + maxi = 1 + count = 1 + + for i in range(len(nums)-1): + if nums[i+1]-nums[i] == 1: + count += 1 + elif nums[i+1]-nums[i] == 0: + pass + else: + count = 1 + maxi = max(maxi, count) + return maxi + diff --git a/ProblemSolving/longestCycleInGraph/long.py b/ProblemSolving/longestCycleInGraph/long.py new file mode 100644 index 0000000..37d1b08 --- /dev/null +++ b/ProblemSolving/longestCycleInGraph/long.py @@ -0,0 +1,29 @@ +class Solution: + def longestCycle(self, edges: List[int]) -> int: + + self.longest = -1 + + def dfs(curr, dist, edges, visited, distance): + dist += 1 # inc dist every time + visited[curr] = True # mark visited + distance[curr] = dist # compute dist from start node + neighbour = edges[curr] + + # neighbour checks + + if neighbour == -1: # no route check + return + if neighbour not in visited: # not yet visited check + dfs(neighbour, dist, edges, visited, distance) + return + if neighbour in distance: # already visited then there is a cycle detected + self.longest = max(self.longest, distance[curr] - distance[neighbour] + 1) + return + + visited = {} # visit only once is enough as there can be only one cycle per node and we are not aware where we start + for i in range(len(edges)): + distance = {} # distance from start node as we are not aware prior + if i not in visited: + dfs(i, 0, edges, visited, distance) + + return self.longest diff --git a/ProblemSolving/longestIncreasingPathInMatrix/long.py b/ProblemSolving/longestIncreasingPathInMatrix/long.py new file mode 100644 index 0000000..14eac54 --- /dev/null +++ b/ProblemSolving/longestIncreasingPathInMatrix/long.py @@ -0,0 +1,66 @@ +# Logic 2: Backtrack with Memoization - 100 pass +class Solution: + def longestIncreasingPath(self, matrix: List[List[int]]) -> int: + + def backtrack(current, visited): + + if self.cache[current[0]][current[1]] != 0: + return self.cache[current[0]][current[1]] + + for i,j in [(0,1), (0,-1), (1,0), (-1,0)]: + + nxt = (current[0]+i, current[1]+j) + + if 0 <= nxt[0] < len(matrix) and 0 <= nxt[1] < len(matrix[0]): + + val = matrix[nxt[0]][nxt[1]] + if val <= matrix[current[0]][current[1]]: + continue + if nxt in visited: + continue + + self.cache[current[0]][current[1]] = max(self.cache[current[0]][current[1]], 1+backtrack(nxt, visited.union({nxt}))) + + return self.cache[current[0]][current[1]] + + self.mpath = 0 + self.cache = [[0 for i in range(len(matrix[0]))] for j in range(len(matrix))] + for i in range(len(matrix)): + for j in range(len(matrix[0])): + self.mpath = max(self.mpath, 1+backtrack((i,j), set())) + #print(self.cache) + return self.mpath + + +# Logic 1: Naive Backtrack - all pass but time limit exceeded +""" +class Solution: + def longestIncreasingPath(self, matrix: List[List[int]]) -> int: + + def backtrack(current, visited, path): + + #print(current) + if self.cache[current[0]][current[1]] != 0: + return self.cache[current[0]][current[1]] + + if len(path) > self.mpath: + self.mpath = len(path) + + for i,j in [(0,1), (0,-1), (1,0), (-1,0)]: + nxt = (current[0]+i, current[1]+j) + if 0 <= nxt[0] < len(matrix) and 0 <= nxt[1] < len(matrix[0]): + val = matrix[nxt[0]][nxt[1]] + if val <= matrix[current[0]][current[1]]: + continue + if nxt in visited: + continue + self.cache[current[0]][current[1]] = max(self.cache[current[0]][current[1]],backtrack(nxt, visited.union({nxt}), path+[nxt])) + return self.cache[current[0]][current[1]] + + self.mpath = 0 + self.cache = [[0 for i in range(len(matrix[0]))] for j in range(len(matrix))] + for i in range(len(matrix)): + for j in range(len(matrix[0])): + backtrack((i,j), set(), [(i,j)]) + return self.mpath +""" diff --git a/ProblemSolving/longestNiceSubstring/long.py b/ProblemSolving/longestNiceSubstring/long.py new file mode 100644 index 0000000..a631905 --- /dev/null +++ b/ProblemSolving/longestNiceSubstring/long.py @@ -0,0 +1,38 @@ +class Solution(object): + def longestNiceSubstring(self, s): + """ + :type s: str + :rtype: str + """ + + def getNiceSubStr(substr): + nice = {} + for s in substr: + if s not in nice: + nice[s] = 0 + nice[s] += 1 + return nice + + def isNice(substr): + for k,v in substr.items(): + if k.islower() and k.upper() in substr: + continue + elif k.isupper() and k.lower() in substr: + continue + else: + return False + return True + + # Logic 1: Sliding window + for i in range(len(s), -1, -1): + for j in range(len(s)): + if i+j > len(s): + continue + window = getNiceSubStr(s[j:j+i]) + #print(s[j:j+i], isNice(window)) + if isNice(window): + return s[j:j+i] + + return "" + + diff --git a/ProblemSolving/longestPalindromeSubstring/longPalin.py b/ProblemSolving/longestPalindromeSubstring/longPalin.py new file mode 100644 index 0000000..2299d41 --- /dev/null +++ b/ProblemSolving/longestPalindromeSubstring/longPalin.py @@ -0,0 +1,57 @@ +class Solution(object): + def longestPalindrome(self, s): + """ + :type s: str + :rtype: str + """ + + # Logic 1: 2 pointer method - Moving from right towards the left or vice versa - Failure + # * Solves some testcases but not everything + """ + left = 0 + right = len(s) + if right == 0: + return "" + elif len(set(s)) == 1: + return s + elif right <= 2: + return s[0] + while right > 0: + left = 0 + while (right-left) > 1: + #print(s[left:right]) + if s[left:right] == s[left:right][::-1]: + return s[left:right] + left += 1 + right -= 1 + return "" + """ + + # Logic 2: 100 pass 87% - Same 2 pointer expanding from an index outward. Gist obtained from the logic at https://leetcode.com/problems/longest-palindromic-substring/discuss/2954/Python-easy-to-understand-solution-with-comments-(from-middle-to-two-ends). + # * Start from the middle and expand for every index + # * Iterate O(N) and at every current index expand for a longest palindrome match + + def expand_window(string, left, right): + # Boundary of palindrome is when the characters at the end are equal + # left equal to 0 while right should be lesser than length of string always + while left >= 0 and right < len(string) and string[left] == string[right]: + left -= 1 + right += 1 + return string[left+1:right] + + # Palindrome can be 2 types + # * Odd length palindrome has a center character different like abcba + # * Even length palindrome is symmetric abba + result= "" + for i in range(len(s)): + # Odd length palindrome - expand from the same index + palindrome_substring = expand_window(s, i, i) + if len(palindrome_substring) > len(result): + result = palindrome_substring + # Even length palindrome - expand from next index so we can find the equal internal elem + palindrome_substring = expand_window(s, i, i+1) + if len(palindrome_substring) > len(result): + result = palindrome_substring + return result + + diff --git a/ProblemSolving/longestPalindromeSubstring/longPalin2.py b/ProblemSolving/longestPalindromeSubstring/longPalin2.py new file mode 100644 index 0000000..484a4fe --- /dev/null +++ b/ProblemSolving/longestPalindromeSubstring/longPalin2.py @@ -0,0 +1,22 @@ +class Solution(object): + def longestPalindrome(self, s): + """ + :type s: str + :rtype: str + """ + + def expand_window(string, left, right): + while left >= 0 and right <= len(s)-1 and string[left] == string[right]: + left -= 1 + right += 1 + return string[left+1:right] + + maxi = "" + for i in range(len(s)): + odd_palindrome = expand_window(s, i, i) + if len(maxi) < len(odd_palindrome): + maxi = odd_palindrome + even_palindrome = expand_window(s, i, i+1) + if len(maxi) < len(even_palindrome): + maxi = even_palindrome + return maxi diff --git a/ProblemSolving/longestPalindromeSubstring/longPalin3.py b/ProblemSolving/longestPalindromeSubstring/longPalin3.py new file mode 100644 index 0000000..d54b3de --- /dev/null +++ b/ProblemSolving/longestPalindromeSubstring/longPalin3.py @@ -0,0 +1,51 @@ +class Solution: + def longestPalindrome(self, s: str) -> str: + + if not s: + return "" + + self.longest = 1 + self.longest_palin = s[0] + + n = len(s) + possible_palindromes = [] + + for i in range(0, n-1): + if i > 0 and s[i-1] == s[i] == s[i+1]: + possible_palindromes.append((i,"o")) + possible_palindromes.append((i,"e")) + elif i > 0 and s[i-1] == s[i+1]: + possible_palindromes.append((i,"o")) + elif s[i] == s[i+1]: + possible_palindromes.append((i,"e")) + + m = len(possible_palindromes) + #print(possible_palindromes) + + for i in range(m): + index, types = possible_palindromes[i] + if types == "o": + l = index-1 + h = index+1 + else: + l = index + h = index+1 + print(l,h,possible_palindromes[i], s[index]) + target = s[l] == s[h] == s[l-1] + while l-1 >= 0 and h+1 <= n-1 and s[l-1] == s[h+1]: + l -= 1 + h += 1 + #print("-->", l,h, possible_palindromes[i], s[l-1], s[h+1]) + if types == "e" and target: + while l-1 >= 0 and s[l-1] == s[l]: + l -= 1 + while h+1 <= n-1 and s[h+1] == s[h]: + h += 1 + total = h-l+1 + if total > self.longest: + self.longest = total + print("-->", l,h, possible_palindromes[i]) + self.longest_palin = s[l:h+1] + + return self.longest_palin + diff --git a/ProblemSolving/longestStrictlyIncreasingOrDecreassingSubarray/long.py b/ProblemSolving/longestStrictlyIncreasingOrDecreassingSubarray/long.py new file mode 100644 index 0000000..df6d164 --- /dev/null +++ b/ProblemSolving/longestStrictlyIncreasingOrDecreassingSubarray/long.py @@ -0,0 +1,18 @@ +class Solution: + def longestMonotonicSubarray(self, nums: List[int]) -> int: + + def findLongest(narr: List[int], reverse: bool) -> int: + longest = 1 + result = 1 + for i in range(len(nums)-1): + if not reverse and nums[i] < nums[i+1]: + longest += 1 + result = max(result, longest) + elif reverse and nums[i] > nums[i+1]: + longest += 1 + result = max(result, longest) + else: + longest = 1 + return result + + return max(findLongest(nums, True), findLongest(nums, False)) diff --git a/ProblemSolving/longestSubstringWithoutRepeatingCharacters/long1.py b/ProblemSolving/longestSubstringWithoutRepeatingCharacters/long1.py new file mode 100644 index 0000000..a49ae29 --- /dev/null +++ b/ProblemSolving/longestSubstringWithoutRepeatingCharacters/long1.py @@ -0,0 +1,30 @@ +class Solution(object): + def lengthOfLongestSubstring(self, s): + """ + :type s: str + :rtype: int + """ + + # Logic 1: Sliding window using a dictionary/map - 24% faster + freqs = {} + maxi = 0 + i = 0 + + while i < len(s): + ch = s[i] + + if ch not in freqs: + freqs[ch] = i + else: + dup = freqs[ch] + for k,v in freqs.items(): + if v <= dup: + del freqs[k] + freqs[ch] = i + + if len(freqs) > maxi: + maxi = len(freqs) + + i += 1 + + return maxi diff --git a/ProblemSolving/longestUnivaluePath/long.py b/ProblemSolving/longestUnivaluePath/long.py new file mode 100644 index 0000000..6dad56f --- /dev/null +++ b/ProblemSolving/longestUnivaluePath/long.py @@ -0,0 +1,77 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def longestUnivaluePath(self, root): + """ + :type root: TreeNode + :rtype: int + """ + + # Logic + # * Tweak the logic to work for every subtree as the current node == root + # * At every subtree the univalue path through it should be maximum then return + self.max_univalue = 0 + + def univalue_traverse(node): + + if not node: + return 0 + + left_univalue = univalue_traverse(node.left) + right_univalue = univalue_traverse(node.right) + + if node.left and node.val == node.left.val: + left_univalue += 1 + else: + left_univalue = 0 + + if node.right and node.val == node.right.val: + right_univalue += 1 + else: + right_univalue = 0 + + subtree_univalue = left_univalue + right_univalue + + self.max_univalue = max(self.max_univalue, subtree_univalue) + + return max(left_univalue, right_univalue) + + univalue_traverse(root) + return self.max_univalue + + """ + # The below logic would work for vertical paths. The example2 shows horizontal univalue path which this logic doesnt work for. + # Logic: + # * Try Depth first search as it may traverse the possible longest path + # * Track the same value occurrences and update max depth + + self.max_univalue = 0 + + def univalue_traverse(node, parent, univalue): + + # Update univalue path + if node.val == parent: + univalue += 1 + + # Track the maximum univalue path + self.max_univalue = max(univalue, self.max_univalue) + + # Left Node + if node.left: + univalue_traverse(node.left, node.val, univalue) + + # Right Node + if node.right: + univalue_traverse(node.right, node.val, univalue) + + if not root: + return 0 + + univalue_traverse(root, 0, 0) + return self.max_univalue + """ diff --git a/ProblemSolving/longestWordInDictionaryThroughDeleting/long.py b/ProblemSolving/longestWordInDictionaryThroughDeleting/long.py new file mode 100644 index 0000000..bddb09b --- /dev/null +++ b/ProblemSolving/longestWordInDictionaryThroughDeleting/long.py @@ -0,0 +1,23 @@ +class Solution(object): + def findLongestWord(self, s, d): + """ + :type s: str + :type d: List[str] + :rtype: str + """ + + # Collections Counter method + from collections import Counter + result = "" + last_temp = "" + for word in d: + temp = list((Counter(s) & Counter(word)).elements()) + print temp, result, word + if len(temp) > len(last_temp): + last_temp = temp + result = word + elif len(temp) == len(last_temp): + if word < "".join(last_temp): + result = word + + return result diff --git a/ProblemSolving/lowestCommonAncestorOfABinaryTree/low2.py b/ProblemSolving/lowestCommonAncestorOfABinaryTree/low2.py new file mode 100644 index 0000000..135d405 --- /dev/null +++ b/ProblemSolving/lowestCommonAncestorOfABinaryTree/low2.py @@ -0,0 +1,34 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode': + + # Logic: Create key based on p and q visied. Bottom up to verify key + def findLca(node, p, q): + + if not node: + return "" + + key = "" + if node == p: + key = "p" + if node == q: + key = "q" + + key += findLca(node.left, p, q) + key += findLca(node.right, p, q) + + if (key == "pq" or key == "qp") and self.lca == None: + self.lca = node + + return key + + self.lca = None + findLca(root, p, q) + return self.lca + diff --git a/ProblemSolving/lowestCommonAncestorOfDeepestLeaves/low.py b/ProblemSolving/lowestCommonAncestorOfDeepestLeaves/low.py new file mode 100644 index 0000000..cc9f2f2 --- /dev/null +++ b/ProblemSolving/lowestCommonAncestorOfDeepestLeaves/low.py @@ -0,0 +1,53 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def lcaDeepestLeaves(self, root): + """ + :type root: TreeNode + :rtype: TreeNode + """ + + # Logic 1: Find height separate and iterate until height + """ + def height(node): + if not node: + return -1 + else: + return 1+max(height(node.left), height(node.right)) + + def traverse(node, height): + + + if not root: + return None + self.depth = height(root) + ancestor = traverse(root, 0) + return ancestor + """ + + # Logic 2: calculate the height as we traverse + def traverse(node): + + # Null check + if not node: + return 0, None + + depth1, ancestor1 = traverse(node.left) + depth2, ancestor2 = traverse(node.right) + + if depth1 > depth2: + return depth1+1, ancestor1 + elif depth1 < depth2: + return depth2+1, ancestor2 + + return depth1+1 ,node + + return traverse(root)[1] + + + diff --git a/ProblemSolving/magicSquaresInGrid/magic.py b/ProblemSolving/magicSquaresInGrid/magic.py new file mode 100644 index 0000000..87902af --- /dev/null +++ b/ProblemSolving/magicSquaresInGrid/magic.py @@ -0,0 +1,89 @@ +class Solution(object): + def numMagicSquaresInside(self, grid): + """ + :type grid: List[List[int]] + :rtype: int + """ + + def is_magic_square(matrix): + + #print(matrix) + # For a 3x3 grid + + # continue only if 3x3 grid + if len(matrix[0]) != 3 and len(matrix) != 3: + return False + + # distinct number check + distinct = set() + for r in matrix: + distinct = distinct.union(set(r)) + #print(distinct) + if len(distinct) != 9: + return False + + # Check all the sum + check = sum(matrix[0]) + + # row sum + for r in range(1, len(matrix)): + if check != sum(matrix[r]): + return False + + # column and diagnal sum + for c in range(len(matrix[0])): + + # column sum + col_sum = 0 + for r in range(len(matrix)): + # Distinct digits from 1 to 9 only rule + if matrix[r][c] < 1 or matrix[r][c] > 9: + return False + col_sum += matrix[r][c] + if col_sum != check: + return False + + # forward diagnal sum + diag_sum = 0 + row = 0 + column = c + while row < 3 and column < 3: + diag_sum += matrix[row][column] + #print(matrix[row][column], row, column) + row += 1 + column += 1 + if row == 3 and column == 3 and diag_sum != check: + return False + + # backward diagnal sum + diag_sum = 0 + row = 0 + column = c + while row < 3 and column >= 0: + diag_sum += matrix[row][column] + #print(matrix[row][column], row, column) + row += 1 + column -= 1 + #print(diag_sum, row, column) + if row == 3 and column == -1 and diag_sum != check: + return False + + return True + + count = 0 + r = 0 + while r < len(grid): + for c in range(len(grid[0])): + #print(r, c, r+2, c+2) + if r+2 < len(grid) and c+2 < len(grid[0]): + new_matrix = [] + for row in range(r, r+3): + new_matrix.append(grid[row][c:c+3]) + if is_magic_square(new_matrix): + count += 1 + r += 1 + return count + + # Note: [[10,3,5],[1,6,11],[7,9,2]] was a correct magic square but violates the question of 1 to 9 distinct digits so the answer is False, this was very confusing to me as it was a magic square already with all sum equalities + + diff --git a/ProblemSolving/majorityElementII/maj.py b/ProblemSolving/majorityElementII/maj.py new file mode 100644 index 0000000..c90bdc9 --- /dev/null +++ b/ProblemSolving/majorityElementII/maj.py @@ -0,0 +1,53 @@ +class Solution(object): + def majorityElement(self, nums): + """ + :type nums: List[int] + :rtype: List[int] + """ + + nums.sort() + n = len(nums) + i = 0 + while i < len(nums): + count = 1 + j = i + 1 + while j < len(nums) and nums[j] == nums[i]: + nums.pop(j) + count += 1 + if count <= n//3: + nums.pop(i) + else: + i += 1 + print(nums, i, j) + return nums + + +""" +class Solution(object): + def majorityElement(self, nums): + """ + :type nums: List[int] + :rtype: List[int] + """ + + nums.sort() + count = 1 + temp = 0 + i = 1 + k = len(nums) + while i < len(nums): + if nums[i] == nums[temp]: + count += 1 + nums.pop(i) + else: + if count > k//3: + temp = temp + 1 + else: + nums.pop(temp) + i = temp+1 + count = 1 + #print(count, i, temp, nums) + if temp < len(nums) and count <= k//3: + nums.pop(temp) + return nums +""" diff --git a/ProblemSolving/makeTheLargestNumber/make.py b/ProblemSolving/makeTheLargestNumber/make.py new file mode 100644 index 0000000..3fcd8e0 --- /dev/null +++ b/ProblemSolving/makeTheLargestNumber/make.py @@ -0,0 +1,57 @@ +""" +Given a number of integers, combine them so it would create the largest number. + +Example: +Input: [17, 7, 2, 45, 72] +Output: 77245217 +def largestNum(nums): + # Fill this in. + +print largestNum([17, 7, 2, 45, 72]) +# 77245217 +""" + +def largestNum(nums): + # Logic 1: BruteForce - 100 pass but might lead to timelimit exceeded + """ + import itertools + string_arr = [str(i) for i in nums] + maxi = 0 + for comb in itertools.permutations(string_arr, r=len(nums)): + maxi = max(maxi, int("".join(comb))) + return maxi + """ + + # Logic 2: Arranging sorted digit wise ( 1st, 2nd ... ) will solve this + #nums = sorted(nums, key= lambda x: int(list(str(x))[0]), reverse=True) + return "".join(sorted(map(str, nums), cmp=lambda x, y: cmp(x+y,y+x))[::-1]).lstrip('0') or '0' + #return "".join([str(i) for i in nums]) + # for same first digits we need to check before applying + """ + ans = "" + i = 0 + while i < len(nums): + nums[i] = str(nums[i]) + if i+1 < len(nums) and str(nums[i+1])[0] == nums[i][0]: + nums[i+1] = str(nums[i+1]) + j = i + 1 + while j< len(nums) and str(nums[j])[0] == nums[i][0]: + nums[j] = str(nums[j]) + j += 1 + temp = j + j -= 1 + while int(nums[j]) > int(nums[j][0]*2): + ans += nums[j] + j -= 1 + for k in range(i, j+1): + ans += nums[k] + i = temp + else: + ans += nums[i] + i += 1 + + return ans + """ +print largestNum([17, 7, 2, 45, 72]) +print largestNum([3, 30, 34, 5, 9]) +# 77245217 diff --git a/ProblemSolving/matrixCellsInDistanceOrder/matrix.py b/ProblemSolving/matrixCellsInDistanceOrder/matrix.py new file mode 100644 index 0000000..16e7f05 --- /dev/null +++ b/ProblemSolving/matrixCellsInDistanceOrder/matrix.py @@ -0,0 +1,46 @@ +class Solution(object): + def allCellsDistOrder(self, R, C, r0, c0): + """ + :type R: int + :type C: int + :type r0: int + :type c0: int + :rtype: List[List[int]] + """ + + # Logic 1: Using sorted method with custom key for the matrix - O(N) + O(NlogN) - 58%faster + """ + def distance(x): + return abs(r0-x[0])+abs(c0-x[1]) + + matrix = [] + for i in range(0, R): + for j in range(0, C): + #print(distance([i,j])) + matrix.append([i,j]) + return sorted(matrix, key=lambda x: distance(x)) + """ + + # Logic 2: Re arrange with distance calculation - O(N)? --> Use some property of the matrix + + + # Logic 3: Using datastructures - 152ms - 58%faster + def distance(x): + return abs(r0-x[0])+abs(c0-x[1]) + + distanc = set() + dist = {} + + for i in range(0, R): + for j in range(0, C): + d = distance([i,j]) + if d not in dist: + dist[d] = [] + dist[d].append([i,j]) + distanc.add(d) + result = [] + for d in distanc: + result.extend(dist[d]) + return result + + diff --git a/ProblemSolving/maxAncestorDiffTree/maxi.py b/ProblemSolving/maxAncestorDiffTree/maxi.py new file mode 100644 index 0000000..a7032d1 --- /dev/null +++ b/ProblemSolving/maxAncestorDiffTree/maxi.py @@ -0,0 +1,33 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def maxAncestorDiff(self, root): + """ + :type root: TreeNode + :rtype: int + """ + + # Logic1: Literally follow the instructions ( No shortcuts ) - 100 pass 10% 100% + # * At every node, maintain the hierarchy and check differences with all ancestors + + def ancestorDiff(node, hierarchy): + + for ancestor in hierarchy: + if abs(ancestor.val - node.val) > self.maxDiff: + self.maxDiff = abs(ancestor.val - node.val) + + if node.left: + ancestorDiff(node.left, hierarchy+[node]) + if node.right: + ancestorDiff(node.right, hierarchy+[node]) + + + self.maxDiff = 0 + ancestorDiff(root, []) + return self.maxDiff + diff --git a/ProblemSolving/maxAreaOfIsland/max.py b/ProblemSolving/maxAreaOfIsland/max.py new file mode 100644 index 0000000..9c36a68 --- /dev/null +++ b/ProblemSolving/maxAreaOfIsland/max.py @@ -0,0 +1,58 @@ +class Solution(object): + def maxAreaOfIsland(self, grid): + """ + :type grid: List[List[int]] + :rtype: int + """ + + """ + result = [set()] + maxi = -float('inf') + for i in range(len(grid)): + for j in range(len(grid[0])): + if grid[i][j] == 1: + # create new island + if not result[-1]: + result[-1].add((i, j)) + # column + if i-1 >= 0 and grid[i-1][j] == 1: + result[-1].add((i-1, j)) + if i+1 < len(grid) and grid[i+1][j] == 1: + result[-1].add((i+1, j)) + # row + if j-1 >= 0 and grid[i][j-1] == 1: + result[-1].add((i, j-1)) + if j+1 < len(grid[0]) and grid[i][j+1] == 1: + result[-1].add((i, j+1)) + + if len(result[-1]) > maxi: + maxi = len(result[-1]) + + next_island = True + for x,y in result[-1]: + print(x,y) + if (x+1 < len(grid) and grid[x+1][y] != 0) and (y+1 < len(grid[0]) and grid[x][y+1] != 0): + next_island = False + + if next_island: + result.append(set()) + print(result) + + return maxi + """ + + # Recursive Logic + def sizeOfIsland(grid, i, j): + if i >= 0 and i < len(grid) and j >= 0 and j < len(grid[0]) and grid[i][j] == 1: + grid[i][j] = 0 + return 1 + sizeOfIsland(grid, i-1, j) + sizeOfIsland(grid, i+1, j) + sizeOfIsland(grid, i, j+1) + sizeOfIsland(grid, i, j-1) + return 0 + + maxSize = 0 + for i in range(len(grid)): + for j in range(len(grid[0])): + if grid[i][j] == 1: + maxSize = max(maxSize, sizeOfIsland(grid, i, j)) + print(grid) + return maxSize + diff --git a/ProblemSolving/maxHeightNaryTree/max.py b/ProblemSolving/maxHeightNaryTree/max.py new file mode 100644 index 0000000..36e415a --- /dev/null +++ b/ProblemSolving/maxHeightNaryTree/max.py @@ -0,0 +1,102 @@ +""" +# Definition for a Node. +class Node(object): + def __init__(self, val, children): + self.val = val + self.children = children +""" +class Solution(object): + def maxDepth(self, root): + """ + :type root: Node + :rtype: int + """ + + + # Recursive Method of finding depth + def depth(node): + + # when a null node is reached from being recursive + if not node: + return 0 + else: + # Node is not None and Node has children (Children check) + # -- Go with maximum depth child as we progress + if node.children: + return 1 + max([depth(child) for child in node.children]) + else: + # When the node has no children count its position + return 1 + + # Root Node Null check + if not root: + return 0 + + return depth(root) + + + """ + # Iterative method -- 100% pass + + # Fill in each level (BFS mode) as a list of levels of a tree + # -- The length of this (list of list/levels) will be the maximum depth + + # Null check + if not root: + return 0 + + # Traverse levels helper + stack = [[root]] + + # Levels list --- values at each level + levels = [] + + # Iterate until exhaust + while stack: + + # current level to traverse in list + current_level = stack.pop(0) + + # current levels values list + levels.append([]) + + # Next level list of children + next_level = [] + + # Exhaust current level list (all the current nodes) + while current_level: + # Remove node in each level (left to right) + current_node = current_level.pop(0) + + # Update the current node values list (always the last in the list for that level) + levels[-1].append(current_node.val) + + # Add all children to next level for traversing + if current_node.children: + next_level.extend(current_node.children) + + # If there are nodes to traverse in the next level + if next_level: + stack.append(next_level) + + #print levels + + # Depth + return len(levels) + """ + + """ + # Helpers/THoughts + i, n = 0, len(prev_level) + next_level = [] + while i < n: + current = prev_level[i] + if current.children: + stack.append([]) + for child in current.children: + stack[-1].append(child) + next_level.append(child.val) + i += 1 + stack.append(next_level) + """ + diff --git a/ProblemSolving/maxPointsOnALine/max.py b/ProblemSolving/maxPointsOnALine/max.py new file mode 100644 index 0000000..1affbd5 --- /dev/null +++ b/ProblemSolving/maxPointsOnALine/max.py @@ -0,0 +1,26 @@ +class Solution: + def maxPoints(self, points: List[List[int]]) -> int: + + # ref: https://leetcode.com/problems/max-points-on-a-line/solutions/2910679/max-points-on-a-line/comments/1747602 + # Use https://math.stackexchange.com/questions/701862/how-to-find-if-the-points-fall-in-a-straight-line-or-not + def calcSlope(p1, p2): + + if p1[0] == p2[0]: + return float('inf') # y2-y1 / x2-x1 is infinity + if p1[1] == p2[1]: + return 0 + return (p2[1]-p1[1]) / (p2[0]-p1[0]) + + max_points = 0 + + for p in range(len(points)): + slopes = {} + for other in range(p+1, len(points)): + curr_slope = calcSlope(points[p], points[other]) + if curr_slope not in slopes: + slopes[curr_slope] = 1 + else: + slopes[curr_slope] += 1 + max_points = max(max_points, slopes[curr_slope]) + + return max_points+1 diff --git a/ProblemSolving/maxStack/max.py b/ProblemSolving/maxStack/max.py new file mode 100644 index 0000000..a29a51f --- /dev/null +++ b/ProblemSolving/maxStack/max.py @@ -0,0 +1,51 @@ +# Logic 1: Naive iteration for popMax otherwise array ops --> 100 pass +class MaxStack: + + def __init__(self): + """ + initialize your data structure here. + """ + self.stack = [] + self.max = -float('inf') + self.max_level = 0 + + def push(self, x: int) -> None: + if x >= self.max: + self.max = x + n = len(self.stack) + self.max_level = -len(self.stack)-1 + self.stack = [x] + self.stack + + def pop(self) -> int: + popped = self.stack[0] + if popped == self.max: + return self.popMax() + self.stack = self.stack[1:] + return popped + + def top(self) -> int: + return self.stack[0] + + def peekMax(self) -> int: + return self.max + + def popMax(self) -> int: + n = len(self.stack) + m = n+self.max_level + self.stack = self.stack[:m] + self.stack[m+1:] + prev_max = self.max + self.max = -float('inf') + for i in range(len(self.stack)): + if self.stack[i] > self.max: + self.max = self.stack[i] + self.max_level = -(len(self.stack)-i) + return prev_max + + +# Your MaxStack object will be instantiated and called as such: +# obj = MaxStack() +# obj.push(x) +# param_2 = obj.pop() +# param_3 = obj.top() +# param_4 = obj.peekMax() +# param_5 = obj.popMax() diff --git a/ProblemSolving/maxSubarray/maxi.py b/ProblemSolving/maxSubarray/maxi.py new file mode 100644 index 0000000..858fada --- /dev/null +++ b/ProblemSolving/maxSubarray/maxi.py @@ -0,0 +1,38 @@ +class Solution(object): + def maxSubArray(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + + # Logic 1: Brute force: Worst case O(N2) ==> get the current sum + check all the sum of subarray before it + """ + maxi = nums[0] + for i in range(1, len(nums)): + nums[i] = nums[i] + nums[i-1] + maxi = max(maxi, nums[i]) + for j in range(0, i): + maxi = max(maxi, nums[i]-nums[j]) + maxi = max(maxi, nums[-1]) + return maxi + """ + + # Logic 2: DP Like --> Calculate the Sum of the subarray including the current element + # * If adding the sum would help maximum then add it else 0 + # * We want the sum to be max, so get the sum of the contiguous subarray from the previous value as we calculate and only when it is above 0 use it as it helps maximum else stop. + """ + ans = nums[0] + for i in range(1, len(nums)): + nums[i] = nums[i] + (nums[i-1] if nums[i-1] > 0 else 0) + ans = max(ans, nums[i]) + return ans + """ + + # Logic 3: Referring to https://leetcode.com/problems/maximum-subarray/discuss/20211/Accepted-O(n)-solution-in-java a math property + + maxHere = nums[0] + maxUntilNow = nums[0] + for i in range(1, len(nums)): + maxHere = max(nums[i], nums[i]+maxHere) + maxUntilNow = max(maxUntilNow, maxHere) + return maxUntilNow diff --git a/ProblemSolving/maxSumOfAPairWithEqualSumOfDigits/max.py b/ProblemSolving/maxSumOfAPairWithEqualSumOfDigits/max.py new file mode 100644 index 0000000..45c8fb9 --- /dev/null +++ b/ProblemSolving/maxSumOfAPairWithEqualSumOfDigits/max.py @@ -0,0 +1,36 @@ +class Solution: + def maximumSum(self, nums: List[int]) -> int: + + def sumOfDigits(num): + s = 0 + while num: + s += num%10 + num = num//10 + return s + + numsSumDigits = {} + cacheSod = {} + result = -1 + computed = set() + + nums.sort(reverse=True) + + for i in range(len(nums)): + if nums[i] in cacheSod: + sd = cacheSod[nums[i]] + else: + sd = sumOfDigits(nums[i]) + cacheSod[nums[i]] = sd + if sd in computed: + continue + if sd not in numsSumDigits: + numsSumDigits[sd] = [] + #for s in numsSumDigits[sd]: + # result = max(result, s+nums[i]) + if len(numsSumDigits[sd]) == 1: + result = max(result, numsSumDigits[sd][0] + nums[i]) + computed.add(sd) + numsSumDigits[sd].append(nums[i]) + + return result + diff --git a/ProblemSolving/maxTwinSumOfALinkedList/max.py b/ProblemSolving/maxTwinSumOfALinkedList/max.py new file mode 100644 index 0000000..b4290d3 --- /dev/null +++ b/ProblemSolving/maxTwinSumOfALinkedList/max.py @@ -0,0 +1,30 @@ +""" +https://leetcode.com/contest/biweekly-contest-69/problems/maximum-twin-sum-of-a-linked-list/ +""" + +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next +class Solution: + def pairSum(self, head: Optional[ListNode]) -> int: + nodes = {} + index = 0 + + while head: + nodes[index] = head.val + head = head.next + index += 1 + + n = len(nodes.keys()) + max_twin_sum = 0 + print(nodes) + + index -= 1 + while index > 0: + if nodes[index] + nodes[n-index-1] > max_twin_sum: + max_twin_sum = nodes[index] + nodes[n-index-1] + index -= 1 + + return max_twin_sum diff --git a/ProblemSolving/maximizeIceCreamBars/maxi.py b/ProblemSolving/maximizeIceCreamBars/maxi.py new file mode 100644 index 0000000..9bc433f --- /dev/null +++ b/ProblemSolving/maximizeIceCreamBars/maxi.py @@ -0,0 +1,13 @@ +class Solution: + def maxIceCream(self, costs: List[int], coins: int) -> int: + + # buy in any order and maximize + costs.sort() + icecream_bars = 0 + + # iterate to maximize no of icecream_bars + while costs and coins >= costs[0]: + coins -= costs.pop(0) + icecream_bars += 1 + + return icecream_bars diff --git a/ProblemSolving/maximumBinaryTree/maxi.py b/ProblemSolving/maximumBinaryTree/maxi.py index 17442c0..c664bcc 100644 --- a/ProblemSolving/maximumBinaryTree/maxi.py +++ b/ProblemSolving/maximumBinaryTree/maxi.py @@ -1,5 +1,3 @@ -#### Pending... - # Definition for a binary tree node. # class TreeNode(object): # def __init__(self, x): @@ -14,92 +12,92 @@ def constructMaximumBinaryTree(self, nums): :rtype: TreeNode """ - # Finding the root - root = max(nums) - rootIndex = nums.index(root) - - # Create a tree - rootNode = TreeNode(root) - - # Left and the Right Subarray - left = nums[:rootIndex] - right = nums[rootIndex+1:] + # Recursive method + def recurse(array): + + if not array: + return + + # Select maximum and compute left and right subtree + maxi = max(array) + maxi_ind = array.index(maxi) + left = array[:maxi_ind] + right = array[maxi_ind+1:] + + # Create a node + node = TreeNode(maxi) + + # Add left and right to each node + node.left = recurse(left) + node.right = recurse(right) + + # return node so the tree is build as we recurse + return node - # First left and the right node - if len(left) >= 1: - rootNode.left = TreeNode(max(left)) - leftTree = rootNode.left - if len(right) >= 1: - rootNode.right = TreeNode(max(right)) - rightTree = rootNode.right + # Iterative method + # * the list persistence (left,right) could have been done better. The indexes get corrupted between array, left, right hence stored the node with the corresponding next array to operate + def iterative(array): + + # Select maximum and create root + maxi = max(array) + root = TreeNode(maxi) - count = len(left)-1 - while count > 0: - maxi = left.index(leftTree.val) - l = left[:maxi] - r = left[maxi+1:] - left.pop(maxi) - if len(l) >= 1: - leftTree.left = TreeNode(max(l)) - leftTree = leftTree.left - count -= 1 - if len(r) >= 1: - leftTree.right = TreeNode(max(r)) - leftTree = leftTree.right - count -= 1 + # Stack to track the traversal - Storing the node with the corresponding array to operate next. + # * Find some way to persist array, indexes across iteration + stack = [(root, array)] + + # Iterate through all the nodes + while stack: + # pop 0 as per breath first traversal + current = stack.pop(0) + # Extract the node and corresponding array + current_node = current[0] + array = current[1] + + # Debug + #print current_node.val, array + + # Maximum index and left and right sub array + index = array.index(current_node.val) + left = array[:index] + right = array[index+1:] + + # Operate on left + # * Create node, Add left node and then to stack to continue traversal + if left: + left_node = TreeNode(max(left)) + current_node.left = left_node + stack.append((left_node, left)) + + # Operate on right + # * Create node, Add right node and then to stack to continue traversal + if right: + right_node = TreeNode(max(right)) + current_node.right = right_node + stack.append((right_node, right)) + + return root - count = len(right)-1 - while count > 0: - maxi = right.index(rightTree.val) - l = right[:maxi] - r = right[maxi+1:] - right.pop(maxi) - if len(l) >= 1: - rightTree.left = TreeNode(max(l)) - rightTree = rightTree.left - count -= 1 - if len(r) >= 1: - rightTree.right = TreeNode(max(r)) - rightTree = rightTree.right - count -= 1 - - return rootNode - """ - # This logic is with respect to a bst - problem statement works on the maximum element - - # Left and the Right Subtree split - left = sorted(nums[:rootIndex], reverse=True) - right = sorted(nums[rootIndex+1:],reverse=True) - - # First left and the right node - if len(left) >= 1: - rootNode.left = TreeNode(left[0]) - leftTree = rootNode.left - if len(right) >= 1: - rootNode.right = TreeNode(right[0]) - rightTree = rootNode.right + # Recursive Solution + # Function call and return + root = recurse(nums) + return root - if len(left[1:]) > 1: - # Iterate to fill in every node - for num in left[1:]: - if num > leftTree.val: - leftTree.left = TreeNode(num) - leftTree = leftTree.left - else: - leftTree.right = TreeNode(num) - leftTree = leftTree.right + # Iterative solution + #return iterative(nums) - if len(right[1:]) >= 1: - for num in right[1:]: - if num < rightTree.val: - rightTree.left = TreeNode(num) - rightTree = rightTree.left - else: - rightTree.right = TreeNode(num) - rightTree = rightTree.right - return rootNode - """ + """ + # Plain thinking + maxi = max(nums) + root_index = nums.index(maxi) + root = TreeNode(nums[root_index]) + left = nums[:root_index] + right = nums[root_index+1:] + while left: + maxi = max(left) + """ + diff --git a/ProblemSolving/maximumBinaryTree/other_logic_pending.py b/ProblemSolving/maximumBinaryTree/other_logic_pending.py new file mode 100644 index 0000000..17442c0 --- /dev/null +++ b/ProblemSolving/maximumBinaryTree/other_logic_pending.py @@ -0,0 +1,105 @@ +#### Pending... + +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def constructMaximumBinaryTree(self, nums): + """ + :type nums: List[int] + :rtype: TreeNode + """ + + # Finding the root + root = max(nums) + rootIndex = nums.index(root) + + # Create a tree + rootNode = TreeNode(root) + + # Left and the Right Subarray + left = nums[:rootIndex] + right = nums[rootIndex+1:] + + # First left and the right node + if len(left) >= 1: + rootNode.left = TreeNode(max(left)) + leftTree = rootNode.left + if len(right) >= 1: + rootNode.right = TreeNode(max(right)) + rightTree = rootNode.right + + count = len(left)-1 + while count > 0: + maxi = left.index(leftTree.val) + l = left[:maxi] + r = left[maxi+1:] + left.pop(maxi) + if len(l) >= 1: + leftTree.left = TreeNode(max(l)) + leftTree = leftTree.left + count -= 1 + if len(r) >= 1: + leftTree.right = TreeNode(max(r)) + leftTree = leftTree.right + count -= 1 + + + count = len(right)-1 + while count > 0: + maxi = right.index(rightTree.val) + l = right[:maxi] + r = right[maxi+1:] + right.pop(maxi) + if len(l) >= 1: + rightTree.left = TreeNode(max(l)) + rightTree = rightTree.left + count -= 1 + if len(r) >= 1: + rightTree.right = TreeNode(max(r)) + rightTree = rightTree.right + count -= 1 + + return rootNode + """ + # This logic is with respect to a bst - problem statement works on the maximum element + + # Left and the Right Subtree split + left = sorted(nums[:rootIndex], reverse=True) + right = sorted(nums[rootIndex+1:],reverse=True) + + # First left and the right node + if len(left) >= 1: + rootNode.left = TreeNode(left[0]) + leftTree = rootNode.left + if len(right) >= 1: + rootNode.right = TreeNode(right[0]) + rightTree = rootNode.right + + if len(left[1:]) > 1: + # Iterate to fill in every node + for num in left[1:]: + if num > leftTree.val: + leftTree.left = TreeNode(num) + leftTree = leftTree.left + else: + leftTree.right = TreeNode(num) + leftTree = leftTree.right + + if len(right[1:]) >= 1: + for num in right[1:]: + if num < rightTree.val: + rightTree.left = TreeNode(num) + rightTree = rightTree.left + else: + rightTree.right = TreeNode(num) + rightTree = rightTree.right + + return rootNode + """ + + diff --git a/ProblemSolving/maximumDepthOfBinaryTree/maxi.py b/ProblemSolving/maximumDepthOfBinaryTree/maxi.py new file mode 100644 index 0000000..bb94cc7 --- /dev/null +++ b/ProblemSolving/maximumDepthOfBinaryTree/maxi.py @@ -0,0 +1,21 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def maxDepth(self, root): + """ + :type root: TreeNode + :rtype: int + """ + + def depth(node): + if not node: + return 0 + else: + return 1+max(depth(node.right), depth(node.left)) + + return depth(root) diff --git a/ProblemSolving/maximumDistanceInArrays/max.py b/ProblemSolving/maximumDistanceInArrays/max.py new file mode 100644 index 0000000..e810c52 --- /dev/null +++ b/ProblemSolving/maximumDistanceInArrays/max.py @@ -0,0 +1,33 @@ +class Solution(object): + def maxDistance(self, arrays): + """ + :type arrays: List[List[int]] + :rtype: int + """ + + # Logic 1: Naive 2 iteration for 2 array pick - Time Limit Exceeded! + """ + maxi = -float('inf') + for i in range(len(arrays)): + for j in range(i+1, len(arrays)): + #print(arrays[i], arrays[j]) + if abs(arrays[j][-1] - arrays[i][0]) > maxi: + maxi = abs(arrays[j][-1] - arrays[i][0]) + if abs(arrays[j][0] - arrays[i][-1]) > maxi: + maxi = abs(arrays[j][0] - arrays[i][-1]) + return maxi + """ + + # Logic 2: Take the first and the last and find maxi as we iterate - 64% faster - 100 pass + first = arrays[0][0] + last = arrays[0][-1] + maxi = -float('inf') + for i in range(1, len(arrays)): + maxi = max(maxi, abs(first-arrays[i][0]), abs(first-arrays[i][-1])) + maxi = max(maxi, abs(last-arrays[i][0]), abs(last-arrays[i][-1])) + if arrays[i][0] < first: + first = arrays[i][0] + if arrays[i][-1] > last: + last = arrays[i][-1] + return maxi + diff --git a/ProblemSolving/maximumLengthOfPairChain/max.py b/ProblemSolving/maximumLengthOfPairChain/max.py new file mode 100644 index 0000000..212baa8 --- /dev/null +++ b/ProblemSolving/maximumLengthOfPairChain/max.py @@ -0,0 +1,45 @@ +class Solution(object): + def findLongestChain(self, pairs): + """ + :type pairs: List[List[int]] + :rtype: int + """ + + # Logic 1: Naive iteration at every index - O(n**2) + # Logic 2: Sort with b < c logic and then find the longest + """ + def custom(p1, p2): + if p1[1] <= p2[0]: + return 0 + else: + return -1 + + p = sorted(pairs, cmp=custom) + print(p) + i = 0 + count = 0 + maxi = 0 + while i+1 < len(p): + if custom(p[i], p[i+1]): + print(p[i], p[i+1], count) + count += 1 + else: + maxi = max(maxi, count) + count = 0 + i -= 1 + i += 1 + maxi = max(maxi, count) + return maxi + """ + + # Logic 3: Sort by pair[1] so its arranged accordingly and then iterate - 57% faster + # Ref: https://leetcode.com/problems/maximum-length-of-pair-chain/discuss/105607/4-Liner-Python-Greedy + order = sorted(pairs, key=lambda x: x[1]) + current, result = -float('inf'), 0 + for o in order: + if current < o[0]: + current = o[1] + result += 1 + return result + + diff --git a/ProblemSolving/maximumLevelSumsOfABinarySearchTree/max.py b/ProblemSolving/maximumLevelSumsOfABinarySearchTree/max.py new file mode 100644 index 0000000..ea1a359 --- /dev/null +++ b/ProblemSolving/maximumLevelSumsOfABinarySearchTree/max.py @@ -0,0 +1,52 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def maxLevelSum(self, root): + """ + :type root: TreeNode + :rtype: int + """ + + self.levelSums = {} + self.max = -float('inf') + self.max_level = 1 + + # Depth First Search Logic + def maxLevelSumUsingDFS(node, height): + + # Add height (level) key to a global dictionary + if height not in self.levelSums: + self.levelSums[height] = 0 + + # Add value to sum of current level + self.levelSums[height] += node.val + + """ + # Dont do this while it is being cooked + # Set the maximum once obtained + if self.levelSums[height] > self.max: + self.max = self.levelSums[height] + self.max_level = height + elif self.levelSums[height] == self.max: # Minimum height gets max height + if height < self.max_level: + self.max_level = height + """ + + # Recurse or Traverse + if node.left: + maxLevelSumUsingDFS(node.left, height+1) + if node.right: + maxLevelSumUsingDFS(node.right, height+1) + + maxLevelSumUsingDFS(root, 1) + + # Do this after it is being cooked! + self.max = max(self.levelSums.values()) + for key in sorted(self.levelSums.keys()): + if self.levelSums[key] == self.max: + return key diff --git a/ProblemSolving/maximumNumberOfBalloons/max.go b/ProblemSolving/maximumNumberOfBalloons/max.go new file mode 100644 index 0000000..a2d48c0 --- /dev/null +++ b/ProblemSolving/maximumNumberOfBalloons/max.go @@ -0,0 +1,62 @@ +import ( + "strings" + "fmt" +) + +func maxNumberOfBalloons(text string) int { + balloons := map[string]int{ + "b": 0, + "a": 0, + "l": 0, + "o": 0, + "n": 0, + } + counts := 0 + for _, ch := range text { + char := string(ch) + if strings.Contains("ban", char) { + balloons[char] += 1 + } else if strings.Contains("lo", char) { + balloons[char] += 1 + } + } + mini_ones := 0 + mini_twos := 0 + if balloons["b"] < balloons["a"] { + mini_ones = balloons["b"] + } else { + mini_ones = balloons["a"] + } + if balloons["n"] < mini_ones { + mini_ones = balloons["n"] + } + if balloons["l"] < balloons["o"] { + mini_twos = balloons["l"] + } else { + mini_twos = balloons["o"] + } + mini_twos /= 2 + if mini_ones < mini_twos { + counts = mini_ones + } else { + counts = mini_twos + } + return counts +} + +/* +for key, value := range balloons { + if key == "l" || key == "o" { + twos += value + } else { + ones += value + } +} +twos = twos/2 +if twos%2 != 0 {twos -= 1} +counts += (ones-(ones%3))/3 +fmt.Println(counts, twos, balloons) +for twos < counts { + counts -= 1 +} +*/ diff --git a/ProblemSolving/maximumProductOfWordLengths/max2.py b/ProblemSolving/maximumProductOfWordLengths/max2.py new file mode 100644 index 0000000..0ed3771 --- /dev/null +++ b/ProblemSolving/maximumProductOfWordLengths/max2.py @@ -0,0 +1,40 @@ +class Solution(object): + def maxProduct(self, words): + """ + :type words: List[str] + :rtype: int + """ + + # Logic 1: naive iteration (O(N)*2) with comparison -> 29% faster + + def hasIntersection(d1, d2): + for k,v in d1.items(): + if k != "length" and k in d2: + return True + return False + + def makeDict(word): + d = {} + for w in range(len(word)): + if word[w] not in d: + d[word[w]] = 0 + d[word[w]] += 1 + d["length"] = len(word) + return d + + maps = [] + max_l = 0 + + for i in range(len(words)): + d = makeDict(words[i]) + for another_d in maps: + #print(d, another_d) + if hasIntersection(d, another_d): + continue + l = d["length"]*another_d["length"] + if l > max_l: + max_l = l + maps.append(d) + + return max_l + diff --git a/ProblemSolving/maximumSumOfArrayAfterKNegations/max.py b/ProblemSolving/maximumSumOfArrayAfterKNegations/max.py new file mode 100644 index 0000000..2ef14fc --- /dev/null +++ b/ProblemSolving/maximumSumOfArrayAfterKNegations/max.py @@ -0,0 +1,37 @@ +class Solution(object): + def largestSumAfterKNegations(self, A, K): + """ + :type A: List[int] + :type K: int + :rtype: int + """ + + # Logic 1 - 70% faster + # We need to maximize the sum + # * This means for any minimum number we can convert it to negative + # * This also means for any maximum number we can convert it to positive (by negation) + # Also, these + # * For even number of times of negation in all positive integer array - do not negate + + A.sort() + i = 0 + left = 0 + right = len(A) + while left < right: + if A[left] < 0: + A[left] = -(A[left]) + i += 1 + if i == K: + break + left += 1 + sumi = sum(A) + #print(sumi, i, A) + if i < K and (K-i)%2 != 0: + sumi -= min(A)*2 + return sumi + + + + + + diff --git a/ProblemSolving/maximumUnitsOnATruck/maxi.py b/ProblemSolving/maximumUnitsOnATruck/maxi.py new file mode 100644 index 0000000..e8016aa --- /dev/null +++ b/ProblemSolving/maximumUnitsOnATruck/maxi.py @@ -0,0 +1,13 @@ +class Solution: + def maximumUnits(self, boxTypes: List[List[int]], truckSize: int) -> int: + total_units = 0 + boxTypes = sorted(boxTypes, key=lambda x: x[1], reverse=True) + for typ in boxTypes: + if truckSize == 0: + break + for bx in range(1,typ[0]+1): + if truckSize > 0 : + total_units += typ[1] + #print(total_units) + truckSize -=1 + return total_units diff --git a/ProblemSolving/maximumWidthOfBinaryTree/maxi.py b/ProblemSolving/maximumWidthOfBinaryTree/maxi.py new file mode 100644 index 0000000..1579a1c --- /dev/null +++ b/ProblemSolving/maximumWidthOfBinaryTree/maxi.py @@ -0,0 +1,146 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def widthOfBinaryTree(self, root): + """ + :type root: TreeNode + :rtype: int + """ + # Referring to https://leetcode.com/problems/maximum-width-of-binary-tree/discuss/106650/Python... - converting this logic to recursive --> Number the NODES in the tree + + # Logic 3: Do not recurse for None and do not consider None - 100 pass + + def levelOrderTraverse(node, height, num): + + if height not in self.levelOrder: + self.levelOrder[height] = [0, 0] # Just consider left and right pointer for boundaries + + if self.levelOrder[height][0] == 0: + self.levelOrder[height][0] = num + else: + self.levelOrder[height][1] = num + + if self.levelOrder[height][0] > 0 and self.levelOrder[height][1] > 0: + self.max_width = max(self.max_width, self.levelOrder[height][1] - self.levelOrder[height][0] + 1) + + # Traverse by incrementing height + if node.left: + levelOrderTraverse(node.left, height+1, num*2) + + if node.right: + levelOrderTraverse(node.right, height+1, num*2+1) + + self.levelOrder = {} + self.max_width = 0 + levelOrderTraverse(root, 1, 1) + if self.max_width == 0 and root: + self.max_width = 1 + print(self.levelOrder) + return self.max_width + + + # Logic 3: Iterative + """ + stack = [(1, root)] # level and node + width = 1 + while stack: + width = max(width, stack[-1][0]-stack[0][0]+1) # Last node of current level and first node difference and + 1 + next_level = [] + for num, node in stack: + if node.left: + next_level.append((num*2, node.left)) + if node.right: + next_level.append((num*2+1, node.right)) + #print(stack, next_level) + stack = next_level + return width + """ + + + # Logic 2: Recursive Loop with max width calculation within loop - Still Time Limit Exceeded? ( Can you not recurse for None nodes and add something to improvise?) + """ + def levelOrderTraverse(node, height): + + if height in self.levelOrder and height-1 in self.levelOrder and len(self.levelOrder[height]) >= 2*len(self.levelOrder[height-1]): + return + + if node: + # If there is a node then create height + # Add height to dictionary + if height not in self.levelOrder: + self.levelOrder[height] = None + + # Update height - We can calculcate the length here as we know for sure this is a number that could represent a boundary + #self.levelOrder[height]["nodes"].append(str(node.val)) + if not self.levelOrder[height]: + self.levelOrder[height] = [str(node.val)] + else: + self.levelOrder[height].append(str(node.val)) + + self.max_width = max(self.max_width, len(self.levelOrder[height])) + + # Update max_width as we add a number that represents a boundary + #if self.levelOrder[height]["nodes"]["left"] == None: + # self.levelOrder[height]["nodes"]["left"] = + # self.levelOrder[height]["nodes"]["right"] = len(self.levelOrder[height]["nodes"]-1) + # self.max_width = max(self.max_width, len(self.levelOrder[height]["nodes"][self.levelOrder[height]["left"]:self.levelOrder[height]["right"]])) + + # Traverse by incrementing height + levelOrderTraverse(node.left, height+1) + levelOrderTraverse(node.right, height+1) + elif height in self.levelOrder and height-1 in self.levelOrder and len(self.levelOrder[height]) < 2*len(self.levelOrder[height-1]): + # Update NULL - lets use empty space count only inbetween nulls - and only if they have a left boundary + if height in self.levelOrder and len(self.levelOrder[height]) < 2*len(self.levelOrder[height-1]): + self.levelOrder[height].append(None) + if height+1 in self.levelOrder and self.levelOrder[height+1] != None and len(self.levelOrder[height+1]) < 2*len(self.levelOrder[height]): + levelOrderTraverse(None, height+1) + levelOrderTraverse(None, height+1) + + self.levelOrder = {} + self.max_width = 0 + levelOrderTraverse(root, 1) + return self.max_width + """ + + # Logic 1: Perform a Level Order Search for each height and then calculate length - time limit exceeded ( can you fit the length calculation during the recurse itself? ) + """ + def levelOrderTraverse(node, height): + + # Add height to dictionary + if height not in self.levelOrder: + self.levelOrder[height] = [] + + if node: + # Update height + self.levelOrder[height].append(str(node.val)) + + # Traverse by incrementing height + levelOrderTraverse(node.left, height+1) + levelOrderTraverse(node.right, height+1) + else: + # Update NULL - lets use empty space count only inbetween nulls + self.levelOrder[height].append(None) + if height+1 in self.levelOrder: + levelOrderTraverse(None, height+1) + levelOrderTraverse(None, height+1) + + self.levelOrder = {} + levelOrderTraverse(root, 1) + print(self.levelOrder) + max_width = 0 + for level in self.levelOrder.keys(): + #max_width = max(len("".join(self.levelOrder[level]).strip()), max_width) + left, right = 0, len(self.levelOrder[level])-1 + while left < right and self.levelOrder[level][left] == None: + left += 1 + while right > left and self.levelOrder[level][right] == None: + right -= 1 + print(self.levelOrder[level], left, right) + max_width = max(max_width, len(self.levelOrder[level][left:right+1])) + return max_width + """ diff --git a/ProblemSolving/meetingRooms/meet.py b/ProblemSolving/meetingRooms/meet.py new file mode 100644 index 0000000..5df778c --- /dev/null +++ b/ProblemSolving/meetingRooms/meet.py @@ -0,0 +1,13 @@ +class Solution: + def canAttendMeetings(self, intervals: List[List[int]]) -> bool: + # Logic 1: Sort by start times and O(N) iteration over intrevals to find if they overlap --> 68.84% faster + """ + meetings = sorted(intervals, key= lambda x: x[0]) # sort by start times + for i in range(1, len(meetings)): + previous = meetings[i-1] + if meetings[i][0] < previous[1]: # meeting starts while the previous meeting ongoing + return False + return True + """ + + # Logic 2: Bruteforce to find the overlap O(N2) diff --git a/ProblemSolving/meetingRoomsII/meet.py b/ProblemSolving/meetingRoomsII/meet.py new file mode 100644 index 0000000..0ae3415 --- /dev/null +++ b/ProblemSolving/meetingRoomsII/meet.py @@ -0,0 +1,23 @@ +class Solution(object): + def minMeetingRooms(self, intervals): + """ + :type intervals: List[List[int]] + :rtype: int + """ + + # Logic 1: Sort + Dictionary to store schedule - 100 pass - 95% faster + def meeting_rooms(meetings): + schedule = {} + meetings.sort() + for meet in meetings: + if schedule: + room = 1 + while room in schedule and schedule[room][1] > meet[0]: + room += 1 + schedule[room] = meet + else: + schedule[1] = meet + return len(schedule.keys()) + return meeting_rooms(intervals) + + # Optimize can you do without sorting...? diff --git a/ProblemSolving/mergeKSortedLists/merge.py b/ProblemSolving/mergeKSortedLists/merge.py new file mode 100644 index 0000000..4f46b4c --- /dev/null +++ b/ProblemSolving/mergeKSortedLists/merge.py @@ -0,0 +1,130 @@ +# Definition for singly-linked list. +# class ListNode(object): +# def __init__(self, x): +# self.val = x +# self.next = None + +class Solution(object): + def mergeKLists(self, lists): + """ + :type lists: List[ListNode] + :rtype: ListNode + """ + + # Simple sort and create linkedlist + + if not lists: + return ListNode("") + + def get_values_from_linked_list(array): + result = [] + while array: + result.append(array.val) + array = array.next + return result + + def create_linked_list_from_list(array): + if array: + result = ListNode(array[0]) + ans = result + for i in range(1, len(array)): + result.next = ListNode(array[i]) + result = result.next + result.next = None + return ans + else: + return ListNode("") + + all_values = [] + for linkedlist in lists: + all_values.extend(get_values_from_linked_list(linkedlist)) + all_values.sort() + + return create_linked_list_from_list(all_values) + + + """ + Logic 2: time limit exceeded but all other cases passed + + # Resulting linked list to hold all merged nodes + result = None + ans = None + min_next = None + + if not lists: + return ListNode("") + + # Iterate until all the lists have been iterated ( that is None for every linkedlist ) + while lists and set(lists) != set([None]): + #print(min_next) + if min_next != None and lists[min_next]: + if result == None: + result = ListNode(lists[min_next].val) + if ans == None: + ans = result + else: + result.next = ListNode(lists[min_next].val) + result = result.next + if lists[min_next]: + lists[min_next] = lists[min_next].next + print([p.val if p != -1 and p != None else str(p) for p in lists], min_next, result.val if result != None else result) + pointer = 0 + min_next = 0 + while pointer < len(lists): + # Set the head node of each linkedlist when the indicator is hit + if lists[pointer] != None: + if lists[min_next] == None: + min_next = pointer + elif lists[pointer] and lists[pointer].val < lists[min_next].val: + min_next = pointer + pointer += 1 + else: + lists.pop(pointer) + return ans + """ + + + """ + Logic 3: time limit exceeded but all other cases passed (with helpers pointer array) + + # Pointers to store the start of each list ( avoid iterations and have a key to indicate start: say "-1" ) + pointers = [-1]*len(lists) + + # Resulting linked list to hold all merged nodes + result = None + ans = None + min_next = None + + if not lists: + return ListNode("") + + # Iterate until all the lists have been iterated ( that is None for every linkedlist ) + while set(pointers) != set([None]): + #print(min_next) + if min_next != None: + if result == None: + result = ListNode(pointers[min_next].val) + if ans == None: + ans = result + else: + result.next = ListNode(pointers[min_next].val) + result = result.next + if pointers[min_next]: + pointers[min_next] = pointers[min_next].next + #print([p.val if p != -1 and p != None else str(p) for p in pointers], min_next, result.val if result != None else result) + pointer = 0 + min_next = 0 + while pointer < len(pointers): + # Set the head node of each linkedlist when the indicator is hit + if pointers[pointer] != None: + if pointers[pointer] == -1: + pointers[pointer] = lists[pointer] + if pointers[min_next] == None: + min_next = pointer + elif pointers[pointer] and pointers[pointer].val < pointers[min_next].val: + min_next = pointer + #print(min_next) + pointer += 1 + return ans + """ + diff --git a/ProblemSolving/mergeSortedArray/merge2.py b/ProblemSolving/mergeSortedArray/merge2.py new file mode 100644 index 0000000..3ed08e2 --- /dev/null +++ b/ProblemSolving/mergeSortedArray/merge2.py @@ -0,0 +1,32 @@ +class Solution(object): + def merge(self, nums1, m, nums2, n): + """ + :type nums1: List[int] + :type m: int + :type nums2: List[int] + :type n: int + :rtype: None Do not return anything, modify nums1 in-place instead. + """ + + + i = m-1 + j = n-1 + k = len(nums1)-1 + + while i >= 0 and j >= 0: + if nums1[i] > nums2[j]: + nums1[k] = nums1[i] + i -= 1 + else: + nums1[k] = nums2[j] + j -= 1 + k -= 1 + + #print(nums1) + + while j >= 0: + nums1[k] = nums2[j] + j -= 1 + k -= 1 + + return nums1 diff --git a/ProblemSolving/mergeStringsAlternatively/merge.py b/ProblemSolving/mergeStringsAlternatively/merge.py new file mode 100644 index 0000000..da86269 --- /dev/null +++ b/ProblemSolving/mergeStringsAlternatively/merge.py @@ -0,0 +1,18 @@ +class Solution: + def mergeAlternately(self, word1: str, word2: str) -> str: + result = "" + alternate = False + while word1 or word2: + alternate = not alternate + if alternate: + if not word1: + continue + result += word1[0] + word1 = word1[1:] + else: + if not word2: + continue + result += word2[0] + word2 = word2[1:] + print(word1, word2, result, alternate) + return result diff --git a/ProblemSolving/mergeTwoBinaryTrees/merge.py b/ProblemSolving/mergeTwoBinaryTrees/merge.py new file mode 100644 index 0000000..bcbada6 --- /dev/null +++ b/ProblemSolving/mergeTwoBinaryTrees/merge.py @@ -0,0 +1,47 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def mergeTrees(self, t1, t2): + """ + :type t1: TreeNode + :type t2: TreeNode + :rtype: TreeNode + """ + + # 100 pass -95% runtime and 100% space + # Recursive function to traverse the trees + def traverse(node1, node2): + + # When both the nodes are present, change value to their sum + if node1 and node2: + node1.val = node1.val+node2.val + + # If both left are present recurse, else if node2 only present then replace node1 as node2 + if node1.left and node2.left: + traverse(node1.left, node2.left) + elif node2.left: + node1.left = node2.left + + # If both right are present recurse, else if node2 only present then replace node1 as node2 + if node1.right and node2.right: + traverse(node1.right, node2.right) + elif node2.right: + node1.right = node2.right + + # Null check for root node of both tree + if not t1: + return t2 + if not t2: + return t1 + + # Recursive call + traverse(t1, t2) + + # Return the root of the first tree + return t1 + diff --git a/ProblemSolving/middleOfTheLinkedList/middle.go b/ProblemSolving/middleOfTheLinkedList/middle.go new file mode 100644 index 0000000..7fc8a55 --- /dev/null +++ b/ProblemSolving/middleOfTheLinkedList/middle.go @@ -0,0 +1,34 @@ +/** + * Definition for singly-linked list. + * type ListNode struct { + * Val int + * Next *ListNode + * } + */ + +import ( + "fmt" +) + +func middleNode(head *ListNode) *ListNode { + + // Logic 1: 2*O(N) iteration over linked list - First for length and next for finding middle + first := head // for 1st iteration + second := head // for 2nd iteration + length := 0 + for first != nil { + length += 1 + first = first.Next + } + middle := length/2 + fmt.Println(middle) + length = 0 + for second != nil { + if length == middle { + return second + } + length += 1 + second = second.Next + } + return nil +} diff --git a/ProblemSolving/minCostClimbingStairs/min2.py b/ProblemSolving/minCostClimbingStairs/min2.py new file mode 100644 index 0000000..6fa8371 --- /dev/null +++ b/ProblemSolving/minCostClimbingStairs/min2.py @@ -0,0 +1,40 @@ +class Solution: + # Reference the solution in leetcode which is elaboarate: https://leetcode.com/problems/min-cost-climbing-stairs/solution/ + def minCostClimbingStairs(self, cost: List[int]) -> int: + + # Dynamic Programming + + # 1. tabular + """ + step_cost = [0]*(len(cost)+1) + for i in range(2, len(step_cost)): + one_down = step_cost[i-1]+cost[i-1] + two_down = step_cost[i-2]+cost[i-2] + step_cost[i] = min(one_down, two_down) + return step_cost[-1] + """ + + # 2. recursive with memo + """ + def min_cost(step): + if step <= 1: + return 0 + + if step in memo: + return memo[step] + + down_one = cost[step-1]+min_cost(step-1) + down_two = cost[step-2]+min_cost(step-2) + memo[step] = min(down_one, down_two) + return memo[step] + memo={} + return min_cost(len(cost)) + """ + + # 3. constant space + down_one = down_two = 0 + for i in range(2, len(cost)+1): + temp = down_one + down_one = min(down_one + cost[i-1], down_two+cost[i-2]) + down_two = temp + return down_one diff --git a/ProblemSolving/minStack/min2.py b/ProblemSolving/minStack/min2.py new file mode 100644 index 0000000..b48f341 --- /dev/null +++ b/ProblemSolving/minStack/min2.py @@ -0,0 +1,44 @@ +class MinStack(object): + + def __init__(self): + """ + initialize your data structure here. + """ + self.stack = [] + self.min = -float('inf') + + def push(self, x): + """ + :type x: int + :rtype: None + """ + self.stack.append(x) + + + def pop(self): + """ + :rtype: None + """ + self.stack.pop() + + def top(self): + """ + :rtype: int + """ + return self.stack[-1] + + + def getMin(self): + """ + :rtype: int + """ + return min(self.stack) + + + +# Your MinStack object will be instantiated and called as such: +# obj = MinStack() +# obj.push(x) +# obj.pop() +# param_3 = obj.top() +# param_4 = obj.getMin() diff --git a/ProblemSolving/minimumAbsoluteDifference/minAbsDiff.py b/ProblemSolving/minimumAbsoluteDifference/minAbsDiff.py index 6daa294..19dbfac 100644 --- a/ProblemSolving/minimumAbsoluteDifference/minAbsDiff.py +++ b/ProblemSolving/minimumAbsoluteDifference/minAbsDiff.py @@ -14,13 +14,21 @@ def minimumAbsoluteDifference(n, arr): min = diff return min """ - min = 10 ** 10 + + # O(N) + """ + min = 10 ** 10 # or float('inf') arr = sorted(arr) for i in range(n-1): diff = abs(arr[i] - arr[i+1]) if diff < min: min = diff return min + """ + + # O(logN) assuming sorted or sort() uses best sorting + arr.sort() + return arr[1]-arr[0] if __name__ == "__main__": diff --git a/ProblemSolving/minimumAbsoluteDifferenceInBST/min2.py b/ProblemSolving/minimumAbsoluteDifferenceInBST/min2.py new file mode 100644 index 0000000..b9df06a --- /dev/null +++ b/ProblemSolving/minimumAbsoluteDifferenceInBST/min2.py @@ -0,0 +1,37 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right +class Solution: + def getMinimumDifference(self, root: Optional[TreeNode]) -> int: + + self.min_abs_diff = float('inf') + + # assuming root and immediate node is the abs diff (but there can be right --> left subtrees that come close) + def traverse(node): + + if node.left: + self.min_abs_diff = min(self.min_abs_diff, abs(node.val - node.left.val)) + traverse(node.left) + + if node.right: + self.min_abs_diff = min(self.min_abs_diff, abs(node.val - node.right.val)) + traverse(node.right) + + self.arrange = [] + + # Use inorder to get the sorted version of tree and compute absolute as they are already arranged + def inOrder(node): + + if node.left: + inOrder(node.left) + if self.arrange: + self.min_abs_diff = min(self.min_abs_diff, abs(self.arrange[-1]-node.val)) + self.arrange.append(node.val) + if node.right: + inOrder(node.right) + + inOrder(root) + return self.min_abs_diff diff --git a/ProblemSolving/minimumAbsoluteDifferenceOfPairs/mini.py b/ProblemSolving/minimumAbsoluteDifferenceOfPairs/mini.py new file mode 100644 index 0000000..22c09d2 --- /dev/null +++ b/ProblemSolving/minimumAbsoluteDifferenceOfPairs/mini.py @@ -0,0 +1,47 @@ +class Solution(object): + def minimumAbsDifference(self, arr): + """ + :type arr: List[int] + :rtype: List[List[int]] + """ + + # Logic 2: Arrange consecutive or sorted and just calculate i, i+1 which will be most optimal choice for min - 100 pass 55% faster + arr = sorted(arr) + result = [] + mini = arr[1]-arr[0] + for i in range(len(arr)-1): + pair = [arr[i], arr[i+1]] + if (arr[i+1]-arr[i]) < mini: + mini = arr[i+1]-arr[i] + result = [[arr[i],arr[i+1]]] + elif (arr[i+1]-arr[i]) == mini: + result.append([arr[i],arr[i+1]]) + return result + + # Logic 1: Naive Iteration without Sorted ( we might have to use merge sort instead of insertion ) - Fail! Obvious time limit exceeded! + """ + result = [] + mini = float('inf') + for i in range(len(arr)-1): + for j in range(i+1, len(arr)): + pair = [arr[i], arr[j]] + diff = abs(arr[i]-arr[j]) + ans = [min(pair), max(pair)] + if diff < mini: + mini = diff + result = [ans] + elif diff == mini: + k = 0 + br = True + while k < len(result): + if ans[0] >= result[k][0]: + k += 1 + else: + break + #print(result[:i] + [ans] + result[i:]) + result = result[:k]+[ans]+result[k:] + return result + """ + + + diff --git a/ProblemSolving/minimumAdditionToMakeIntegerBeautiful/min.py b/ProblemSolving/minimumAdditionToMakeIntegerBeautiful/min.py new file mode 100644 index 0000000..5606163 --- /dev/null +++ b/ProblemSolving/minimumAdditionToMakeIntegerBeautiful/min.py @@ -0,0 +1,55 @@ +class Solution: + def makeIntegerBeautiful(self, n: int, target: int) -> int: + + + def calcSumOfDigits(k): + sumOfDigits = 0 + while k: + i = k%10 + k = k//10 + sumOfDigits += i + return sumOfDigits + + s = calcSumOfDigits(n) + if s <= target: + return 0 + + """ + # Logic1: n iteration + for i in range(10**12+1): + t = calcSumOfDigits(n+i) + if t <= target: + return i + + return 0 + """ + + # Logic 2: Make zeros from unit place + carry = 0 + chk = n + remaining = [] + while chk: + i = chk%10 + chk = chk//10 + remaining += [10-i] + + chk = n + add = 0 + total = 0 + for i in range(len(remaining)): + ind = i + extra = 10**ind + if extra == 0: + extra = 1 + if extra > 1: + remaining[i] = remaining[i]-1 + add = (remaining[i])*extra + total += add + chk += add + print(total, chk,add, ind, extra,remaining) + if calcSumOfDigits(chk) <= target: + return total + + return 0 + + diff --git a/ProblemSolving/minimumFallingPathSum/min.py b/ProblemSolving/minimumFallingPathSum/min.py new file mode 100644 index 0000000..33118ef --- /dev/null +++ b/ProblemSolving/minimumFallingPathSum/min.py @@ -0,0 +1,31 @@ +class Solution(object): + def minFallingPathSum(self, A): + """ + :type A: List[List[int]] + :rtype: int + """ + + # Logic2: 100 pass only 5%faster.. better one yet? + # * Iterate through row and columsn (i,j) + # * For each column, the previous possible combinations are i-1, j-1 and i-1, j and i-1, j+1 + # * Get the minimum of those combinations and add as we iterate to the last row + # * Return the minimum possible from the last row sums. + # * Reference: https://leetcode.com/problems/minimum-falling-path-sum/discuss/186843/Python-easy-4-liner + + for i in range(1, len(A)): # Row iteration + for j in range(len(A)): # Column iteration + A[i][j] += min(A[i-1][j-1] if j-1 >= 0 else float("inf"), A[i-1][j], A[i-1][j+1] if j+1 < len(A) else float("inf")) + print A[-1] + return min(A[-1]) + + """ + # Logic 1: Wrong + # * This takes into account the paths that cannot be traversed in a square like 1,4,9 + min_path = float('inf') + import itertools + for path in itertools.product(*A): + min_path = min(sum(path), min_path) + return min_path + """ + + diff --git a/ProblemSolving/minimumGeneticMutations/min.py b/ProblemSolving/minimumGeneticMutations/min.py new file mode 100644 index 0000000..9d973af --- /dev/null +++ b/ProblemSolving/minimumGeneticMutations/min.py @@ -0,0 +1,35 @@ +class Solution: + def minMutation(self, startGene: str, endGene: str, bank: List[str]) -> int: + + # ref + bank = set(bank) + self.mini = float('inf') + + def backtrack(current, visited): + print(current, visited) + + if current == endGene: + self.mini = min(self.mini, len(visited)) + return + + for i in range(len(current)): + for select in ["A", "C", "G", "T"]: + result = current[:i] + select + current[i+1:] + print(current, result) + if result not in bank: + continue + if result in visited: + continue + backtrack(result, visited | {result}) + + return + + + if startGene == endGene: + return 0 + + backtrack(startGene, set()) + + if self.mini == float('inf'): + return -1 + return self.mini diff --git a/ProblemSolving/minimumNumOfArrowsBurstBallons/mini.py b/ProblemSolving/minimumNumOfArrowsBurstBallons/mini.py new file mode 100644 index 0000000..b44eaa0 --- /dev/null +++ b/ProblemSolving/minimumNumOfArrowsBurstBallons/mini.py @@ -0,0 +1,62 @@ +class Solution(object): + def findMinArrowShots(self, points): + """ + :type points: List[List[int]] + :rtype: int + """ + + # Logic: Using the start and end indexed + # - Solve by just checking if the ranges bisect + # Steps: + # * Sort the ranges (on start or end) + # * Find if they intersect + + # Sort ranges with the end index so every subset range fall in line + points = sorted(points, key = lambda x: x[1]) + # Control variables + arrow = 0 + previous_range_end = -float("inf") # negative infinity to satify first iteration + # Iterate ranges in points, if start of current range exceeds end of last range then they dont intersect... + for start, end in points: + if start > previous_range_end: + arrow += 1 + # Update end only when the range intersection does not exist + previous_range_end = end + + return arrow + + """ + # Logic1: All scenarios work except for scale case ==> memory limit exceeded (why? this expands the full range which we do not need for this problem, only the arrow count is required...) + # Using set intersection assuming the input is list + ## set(a).intersection(set(b)) or + ## set(a) & set(b) or + ## set(a).intersection(b) + # * this might have a o(N2) complexity + + if len(points) == 1: + return 1 + + minimum_arrows = None + count = 0 + + points = sorted(points) + + for ranges in points: + if minimum_arrows: + minimum_arrows = set(minimum_arrows).intersection(range(ranges[0], ranges[1]+1)) + if not minimum_arrows: + count += 1 + minimum_arrows = range(ranges[0], ranges[1]+1) + + else: + minimum_arrows = range(ranges[0], ranges[1]+1) + + if minimum_arrows: + count += 1 + + return count + + # Other attempts: + # * iteration with enumerate + # * using dictionary to check + """ diff --git a/ProblemSolving/minimumNumOfArrowsBurstBallons/mini2.py b/ProblemSolving/minimumNumOfArrowsBurstBallons/mini2.py new file mode 100644 index 0000000..84af645 --- /dev/null +++ b/ProblemSolving/minimumNumOfArrowsBurstBallons/mini2.py @@ -0,0 +1,22 @@ +class Solution: + def findMinArrowShots(self, points: List[List[int]]) -> int: + + points = sorted(points, key=lambda x: x[0]) + arrows = 0 + + print(points) + curr_point = [] + if len(points) > 0: + curr_point = points.pop(0) + while points: + nxt = points.pop(0) + if curr_point[0] <= nxt[0] <= curr_point[1] or curr_point[0] <= nxt[1] <= curr_point[1]: + curr_point[0] = min(curr_point[0], nxt[0]) + curr_point[1] = min(curr_point[1], nxt[1]) + else: + arrows += 1 + curr_point = nxt + print(curr_point, nxt, arrows) + if curr_point: + arrows += 1 + return arrows diff --git a/ProblemSolving/minimumNumberOfRefuelingStops/min.py b/ProblemSolving/minimumNumberOfRefuelingStops/min.py new file mode 100644 index 0000000..1d87cef --- /dev/null +++ b/ProblemSolving/minimumNumberOfRefuelingStops/min.py @@ -0,0 +1,50 @@ +class Solution: + def minRefuelStops(self, target: int, startFuel: int, stations: List[List[int]]) -> int: + + # logic 1: backtrack all choices for reaching the destination --> all basic passed except for time limit exceeded on scale test case + """" + stations.sort(key=lambda x: x[0]) + + def backtrack(fuel, pos, last_stop, stations_visited): + + #print(fuel, pos, last_stop, stations_visited) + + if pos >= target or pos+fuel >= target: + if len(stations_visited) < self.min_stops: + self.min_stops = len(stations_visited) + return + + for s in range(last_stop, len(stations)): + fuel_pos, new_fuel = stations[s] + if pos+fuel >= fuel_pos: + # greedy if s+1 < len(stations) and pos+fuel < stations[s+1][0]: + backtrack(fuel-(fuel_pos-pos)+new_fuel, fuel_pos, s+1, stations_visited+[fuel_pos]) + else: + break + + return + + self.min_stops = float('inf') + backtrack(startFuel, 0, 0, []) + if self.min_stops == float('inf'): + return -1 + return self.min_stops + """ + + # 2 --> Dynamic Programming (sol ref) --> maximize the fuel at every stations + + dp = [startFuel] + [0]*len(stations) + + for i in range(len(stations)): + loc, fuel = stations[i] + for j in range(i,-1,-1): + if loc > dp[j]: + continue + dp[j+1] = max(dp[j+1], dp[j]+fuel) + + #print(dp) + for i in range(len(dp)): + if dp[i] >= target: + return i + + return -1 diff --git a/ProblemSolving/minimumPathSum/min.py b/ProblemSolving/minimumPathSum/min.py new file mode 100644 index 0000000..5006bbc --- /dev/null +++ b/ProblemSolving/minimumPathSum/min.py @@ -0,0 +1,87 @@ +class Solution(object): + def minPathSum(self, grid): + """ + :type grid: List[List[int]] + :rtype: int + """ + + # Logic 3 - DP Iterative + M = len(grid) + N = len(grid[0]) + + for i in range(M): + if i > 0: + grid[i][0] += grid[i-1][0] + for j in range(1, N): + if i > 0: + grid[i][j] += min(grid[i-1][j], grid[i][j-1]) + else: + grid[i][j] += grid[i][j-1] + print grid + return grid[-1][-1] + + # Logic 2 - DP - Recursive Memoization with an extra grid + """ + self.row = len(grid)-1 + self.column = len(grid[0])-1 + self.grid = grid + self.memo_grid = [[-1]*(self.column+1)]*(self.row+1) + + # Recurse and find all path like traversing a bst + def recurse_all_paths(g_element, grid, memo): + M = len(grid) + N = len(grid[0]) + + # Grid is a tuple with m x n + m = g_element[0] + n = g_element[1] + + print(m, n) + + if m == M or n == N: + return float('inf') + elif memo[m][n] != -1: + return memo[m][n] + else: + # Recurse down and right path at each point + memo[m][n] = min(recurse_all_paths([m+1, n], grid, memo), recurse_all_paths([m, n+1], grid, memo)) + grid[m][n] + + return memo[m][n] + + self.memo_grid[self.row][self.column] = self.grid[self.row][self.column] + return recurse_all_paths([0, 0], self.grid, self.memo_grid) + """ + + # Brute force - Only recursive through all the path - Time Limit Exceeded - (No memoization) + """ + self.mini_path = float('inf') + self.row = len(grid)-1 + self.column = len(grid[0])-1 + self.grid = grid + + # Recurse and find all path like traversing a bst + def recurse_all_paths(g_element, path_sum): + #print(g_element, path_sum) + + # Grid is a tuple with m x n + m = g_element[0] + n = g_element[1] + + # Path_sum is an integer record of all the values met + # Update path sum as we iterate over each element + path_sum += self.grid[m][n] + + # End Sum Calculation when length is reached + if m == self.row and n == self.column: + if path_sum < self.mini_path: + self.mini_path = path_sum + else: + # Recurse down and right path at each point + if m < self.row and (path_sum+self.grid[m+1][n]) < self.mini_path: + recurse_all_paths([m+1, n], path_sum) + if n < self.column and (path_sum+self.grid[m][n+1]) < self.mini_path: + recurse_all_paths([m, n+1], path_sum) + + recurse_all_paths([0, 0], 0) + return self.mini_path + """ diff --git a/ProblemSolving/minimumRemoveToMakeValidParentheses/min.py b/ProblemSolving/minimumRemoveToMakeValidParentheses/min.py new file mode 100644 index 0000000..48e154f --- /dev/null +++ b/ProblemSolving/minimumRemoveToMakeValidParentheses/min.py @@ -0,0 +1,27 @@ +class Solution: + def minRemoveToMakeValid(self, s: str) -> str: + + stack = [] + ends = [] + + for i in range(len(s)): + + if s[i] == "(": + stack.append(i) + elif s[i] == ")": + if stack and s[stack[-1]] == "(": + stack.pop() + else: + ends.append(i) + + #print(stack, ends) + + stack.extend(ends) + result = list(s) + + while stack: + i = stack.pop() + result[i] = "" + s = "".join(result) + + return s diff --git a/ProblemSolving/minimumRoundsToCompleteAllTasks/min.py b/ProblemSolving/minimumRoundsToCompleteAllTasks/min.py new file mode 100644 index 0000000..023a318 --- /dev/null +++ b/ProblemSolving/minimumRoundsToCompleteAllTasks/min.py @@ -0,0 +1,33 @@ +class Solution: + def minimumRounds(self, tasks: List[int]) -> int: + + # 1. Memoize the difficulty levels and find maximum difficulty + difficulty = {} + round = 0 + for t in range(len(tasks)): + if tasks[t] not in difficulty: + difficulty[tasks[t]] = 1 + continue + difficulty[tasks[t]] += 1 + + # 2. DP: Calc mins of all difficulty upto max difficulty + difficulty_memo = { + 0: 0, + 1: float('inf'), + 2: 1, + 3: 1 + } + def recurse_min(n): + if n in difficulty_memo: + return difficulty_memo[n] + difficulty_memo[n] = 1 + min(recurse_min(n-2), recurse_min(n-3)) + return difficulty_memo[n] + + for k,v in difficulty.items(): + min_rounds = recurse_min(v) + if min_rounds == float('inf'): + return -1 + round += min_rounds + print(difficulty_memo, k, v, round) + + return round diff --git a/ProblemSolving/minimumTicketCost/ticketCost.py b/ProblemSolving/minimumTicketCost/ticketCost.py new file mode 100644 index 0000000..dd4fa27 --- /dev/null +++ b/ProblemSolving/minimumTicketCost/ticketCost.py @@ -0,0 +1,84 @@ +class Solution(object): + def mincostTickets(self, days, cost): + """ + :type days: List[int] + :type costs: List[int] + :rtype: int + """ + + # Logic 1: Solving with Dynamic Programming + # This logic as inreference to the discuss thread - https://leetcode.com/problems/minimum-cost-for-tickets/discuss/228421/Python-solution + + # Create dictionary for faster lookup of days + import collections + days_dict = collections.Counter(days) + + # Create a table of all the day cost + # * Instead of creating a 365 days table, we create until the last day on the days list + table = [0 for i in range(0, days[-1]+1)] + + for i in range(0, days[-1]+1): + # If the current day is not present in the travel days dictionary, it takes the previous value + if i not in days_dict: + table[i] = table[i-1] + else: + # Used max to identify if the index exists + table[i] = min( + table[max(0,i-1)]+cost[0], # per days value + table[max(0,i-7)]+cost[1], # per week value + table[max(0,i-30)]+cost[2] # per year value + ) + + return table[-1] + + """ + # Logic 2: Solving without Dynamic Programming literally going over the logic definition mathmatically + # * fails in some scenarios where the minimum cost could be achieved in a more different way + + # Days of travel + # Costs - {per day, per 7 days, per month} + + n = len(days) + i = 0 + + import math + # How much individual days cost to a week's pass + per_day_cost_week = cost[1]//7 # (days) + minimum_days_benefit_week_pass = cost[1]//cost[0] #(days) + # How much individual week cost to a year's pass + per_day_cost_year = cost[2]//365 # (days) + minimum_days_benefit_month_pass = cost[2]//cost[0] #(days) + + total_cost = 0 + print minimum_days_benefit_week_pass, minimum_days_benefit_month_pass + + while i < n : + # Each day + # * Check yearly cost + # * Check weekly pass benefit + week_days_from_current_day = days[i]+7 + week_count = 0 + j = i + while j < n and days[j] < week_days_from_current_day: + week_count += 1 + j += 1 + month_days_from_current_day = days[i]+30 + month_count = week_count + k = j + while k < n and days[k] < month_days_from_current_day: + month_count += 1 + k += 1 + if week_count > minimum_days_benefit_week_pass: + # Single week cost will be a benefit! + total_cost += cost[1] + i = j + elif month_count > minimum_days_benefit_month_pass: + total_cost += cost[2] + i = k + else: + # Single day cost will only be a benefit! + total_cost += cost[0] + i += 1 + print total_cost, week_count, month_count + return total_cost + """ \ No newline at end of file diff --git a/ProblemSolving/minimumTimeVisitingAllPoints/min.py b/ProblemSolving/minimumTimeVisitingAllPoints/min.py new file mode 100644 index 0000000..c829db2 --- /dev/null +++ b/ProblemSolving/minimumTimeVisitingAllPoints/min.py @@ -0,0 +1,37 @@ +class Solution: + def minTimeToVisitAllPoints(self, points: List[List[int]]) -> int: + + # Logic 2: 67% faster + # By math distance formula d^2 = (x2-x2)^2 + (y2-y1)^2 + # Kind of digesting this, we would know x2-x1 and y2-y1 is x, y distances. + # always choose diagnal to go twice and then resort to hor, ver + seconds = 0 + current = points[0] + nxt = 1 + while nxt < len(points): + seconds += max(abs(points[nxt][0]-current[0]), abs(points[nxt][1]-current[1])) + current = points[nxt] + nxt += 1 + return seconds + + """ + # Logic 1: Literally moving through points + seconds = 0 + current = points[0] + nxt = 1 + # all 1s operations + # * (0, +/- 1) + # * (+/- 1, 0) + # * (+/- 1, +/- 1) + while nxt < len(points): + while current != points[nxt]: + # go diagnal first + if current[0]+1 < points[nxt][0] and current[1]+1 < points[nxt][1]: + current[0] += 1 + current[1] += 1 + seconds += 1 + else if current[0]+1 < points[nxt][0] + nxt += 1 + """ + + diff --git a/ProblemSolving/missingNumber/mis.py b/ProblemSolving/missingNumber/mis.py index e5566a0..23df811 100644 --- a/ProblemSolving/missingNumber/mis.py +++ b/ProblemSolving/missingNumber/mis.py @@ -43,7 +43,18 @@ def missingNumber(self, nums): """ # 4. sort it and do it - - # 5. Use a dictionary """ + + # 5. Use a dictionary + class Solution: + def missingNumber(self, nums: List[int]) -> int: + import collections + n = range(len(nums)) + num = collections.Counter(n) + for i in range(len(nums)): + num[nums[i]] += 1 + for k,v in num.items(): + if v == 1: + return k + return n[-1]+1 diff --git a/ProblemSolving/missingNumber/mis2.py b/ProblemSolving/missingNumber/mis2.py new file mode 100644 index 0000000..7868f3a --- /dev/null +++ b/ProblemSolving/missingNumber/mis2.py @@ -0,0 +1,41 @@ +class Solution(object): + def missingNumber(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + + # Logic 1: Sort and Find diff to be consecutive - 44% faster + + nums.sort() + + # Last integer missing + if nums and nums[-1] != len(nums): + return nums[-1]+1 + + # Starting integer missing + if nums and nums[0] != 0: + return 0 + + # Anything in the middle + for i in range(1, len(nums)): + if nums[i]-nums[i-1] == 1: + continue + return nums[i]-1 + return -1 + + + # Logic 2: 2*O(n), find len(nums) and construct dict/set. Then iterate again for finding missing until len(nums) - 5% faster + """ + integers = {} + for i in nums: + integers[i] = 1 + + for i in range(len(nums)+1): + if i not in nums: + return i + return -1 + """ + + # Logic 3 --> substract sums --> 56% faster + return sum(range(len(nums)+1)) - sum(nums) diff --git a/ProblemSolving/missingNumberInArithmeticProgression/missing.py b/ProblemSolving/missingNumberInArithmeticProgression/missing.py new file mode 100644 index 0000000..662a30e --- /dev/null +++ b/ProblemSolving/missingNumberInArithmeticProgression/missing.py @@ -0,0 +1,53 @@ +class Solution(object): + def missingNumber(self, arr): + """ + :type arr: List[int] + :rtype: int + """ + + # Logic 2: Reading Q again, we are told that the first and the last position are always correct and there is only one chance of misplacement - 32 ms - 66% faster + + a = arr[0] + n = len(arr) + + # AR formula nth number = a + (n-1)d + # d = (arr[n] - a)//(n-1) + if arr[0] < arr[-1]: + d = (arr[-1] - a)//(n) + print(a, d) + for i in range(1, len(arr)): + ith = arr[i-1] + d + if arr[i] != ith: + return ith + else: + d = (arr[-1] - a)//-(n) + print(a, d) + for i in range(1, len(arr)): + ith = arr[i-1] - d + if arr[i] != ith: + return ith + return 0 + + + """ + Logic 1: with dictionary to track diffs - Fail + + n = len(arr) + if arr[n-1] < arr[0]: + arr = arr[::-1] + diffs = {} + maxi = -float('inf') + d = 0 + removed = 0 + for i in range(1, len(arr)): + diff = arr[i]-arr[i-1] + if diff not in diffs: + diffs[diff] = [0, i] + diffs[diff][0] += 1 + if diffs[diff][0] > maxi: + maxi = diffs[diff][0] + d = diff + if maxi > -float('inf'): + removed = arr[diffs[d][1]] + d + return removed + """ diff --git a/ProblemSolving/missingRanges/miss.py b/ProblemSolving/missingRanges/miss.py new file mode 100644 index 0000000..a2be2f7 --- /dev/null +++ b/ProblemSolving/missingRanges/miss.py @@ -0,0 +1,39 @@ +class Solution: + + # Naive iteration logic: 95% faster 100 pass + + def constructStrRange(self, l,u): + if l == u: + return str(l) + else: + return str(l)+"->"+str(u) + + def findMissingRanges(self, nums: List[int], lower: int, upper: int) -> List[str]: + missing_ranges = [] + for i in range(len(nums)): + # Edge case 1 + if nums[i] < lower or nums[i] > upper: + continue + + # Initial ranges + if i == 0 and nums[i] > lower: + missing_ranges.append(self.constructStrRange(lower, nums[i]-1)) + if i == len(nums)-1 and nums[i]+1 <= upper: + missing_ranges.append(self.constructStrRange(nums[i]+1, upper)) + + # Edge case 2 + if i+1 >= len(nums): + continue + if nums[i]+1 == nums[i+1]: + continue + + # Add ranges + l = nums[i]+1 + h = nums[i+1]-1 + missing_ranges.append(self.constructStrRange(l, h)) + + if not nums: + missing_ranges.append(self.constructStrRange(lower, upper)) + + return missing_ranges + diff --git a/ProblemSolving/monotonicArray/monotonic.py b/ProblemSolving/monotonicArray/monotonic.py new file mode 100644 index 0000000..34dc2f3 --- /dev/null +++ b/ProblemSolving/monotonicArray/monotonic.py @@ -0,0 +1,61 @@ +class Solution(object): + def isMonotonic(self, A): + """ + :type A: List[int] + :rtype: bool + """ + + # Logic 1: Naive iteration - 100 pass 5% faster - O(N) + # * First fine whether it is increasing or decreasing + # * Second iterate to check whether they are monotonic + + + # First figure out Monotonic Increasing or Decreasing + i = 0 + n = len(A) + + # Single element array handle + if n == 1: + return True + + # Logic of same element array + # all Equal elements bypass + if len(set(A)) == 1: + return True + + # while elements are equal incremenrt + while i+1 < len(A) and A[i] == A[i+1]: + i += 1 + #if i == len(A)-1: + # return True + + # monotonic + if A[i] <= A[i+1]: + i += 1 + for i in range(i, n-1): + if A[i] > A[i+1]: + return False + elif A[i] >= A[i+1]: + i += 1 + for i in range(i, n-1): + if A[i] < A[i+1]: + return False + return True + + + # Logic 2: Use inbuilt sorted method to easily achieve this - 100 pass 5 percent faster - assuming sorted function uses merge sort internally n*log(n) + """ + sorted_array = sorted(A) + if A == sorted_array or A == sorted_array[::-1]: + return True + else: + return False + """ + +# Other Thoughts: +# * dictionary logic? +# * Sorted or any arrangement +# * 2 pointer method +# * Tree Building? +# * Diff logic + diff --git a/ProblemSolving/mostFrequentEvenElement/most.py b/ProblemSolving/mostFrequentEvenElement/most.py new file mode 100644 index 0000000..47df5e2 --- /dev/null +++ b/ProblemSolving/mostFrequentEvenElement/most.py @@ -0,0 +1,21 @@ +class Solution: + def mostFrequentEven(self, nums: List[int]) -> int: + + import collections + c = collections.Counter(nums) + + maxi = 0 + mink = float('inf') + + for k,v in c.items(): + if k%2 == 0 and v >= maxi: + if v == maxi and k < mink: + mink = k + if v > maxi: + mink = k + maxi = v + + if mink == float('inf'): + return -1 + + return mink diff --git a/ProblemSolving/mostFrequentSubtreeSum/freq.py b/ProblemSolving/mostFrequentSubtreeSum/freq.py new file mode 100644 index 0000000..fe08b42 --- /dev/null +++ b/ProblemSolving/mostFrequentSubtreeSum/freq.py @@ -0,0 +1,123 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def findFrequentTreeSum(self, root): + """ + :type root: TreeNode + :rtype: List[int] + """ + + # Logic 2: One tree traversal ==> 96% fast and 100% less storage + # * Record all the subtree sums and add to dictionary + # * calc max_freq from dictionary + + # frequency dictionary + frequency = {} + + # calculate sum of all subtree and record them in dictionary + def subtree_sum_calculate(node): + + # left subtree sum + if node.left: + left_sum = subtree_sum_calculate(node.left) + else: + left_sum = 0 + + # right subtree sum + if node.right: + right_sum = subtree_sum_calculate(node.right) + else: + right_sum = 0 + + # calculate total subtree sum (root+left+right) + subtree_sum_at_node = node.val + left_sum + right_sum + + # Add total sum (subtree_sum_at_node) to dictionary + if subtree_sum_at_node not in frequency: + frequency[subtree_sum_at_node] = 0 + frequency[subtree_sum_at_node] +=1 + + # Return sum of the subtree + return subtree_sum_at_node + + # null check + if not root: + return [] + + # function trigger + subtree_sum_calculate(root) + + # Max freq + max_freq = max(frequency.values()) + result = [] + + # Iterate dictionary for max freq items + for k, v in frequency.items(): + if max_freq == v: + result.append(k) + + return result + + + """ + # Logic 1: Separate functions to take care of subtree sum calc and to traverse tree (kind of reptitive, implement better logic to perform this in one traversal) ==> 6% fast and 100% less storage + + # sums dictionary + sums = {} + + # calculate sum of a subtree + def subtree_sum_calculate(node): + + # left subtree sum + if node.left: + left_sum = subtree_sum_calculate(node.left) + else: + left_sum = 0 + + # right subtree sum + if node.right: + right_sum = subtree_sum_calculate(node.right) + else: + right_sum = 0 + + # Return sum of the subtree + return node.val + left_sum + right_sum + + # Traverse to calculate subtree sum of each node as root + def traverse(node): + + if node: + subtree_sum_node = subtree_sum_calculate(node) + if subtree_sum_node not in sums: + sums[subtree_sum_node] = 0 + sums[subtree_sum_node] +=1 + + if node.left: + traverse(node.left) + if node.right: + traverse(node.right) + + # null check + if not root: + return [] + + # function trigger + traverse(root) + + # Max freq + max_freq = max(sums.values()) + result = [] + + # Iterate dictionary for max freq items + for k, v in sums.items(): + if max_freq == v: + result.append(k) + + return result + """ + diff --git a/ProblemSolving/mostPopularVideoCreator/pop.py b/ProblemSolving/mostPopularVideoCreator/pop.py new file mode 100644 index 0000000..5652193 --- /dev/null +++ b/ProblemSolving/mostPopularVideoCreator/pop.py @@ -0,0 +1,35 @@ +class Solution: + def mostPopularCreator(self, creators: List[str], ids: List[str], views: List[int]) -> List[List[str]]: + + highPopular = 0 + relation = {} + + for i in range(len(creators)): + + if creators[i] not in relation: + relation[creators[i]] = {} + relation[creators[i]]["totalPopular"] = 0 + relation[creators[i]]["highPopVal"] = 0 + relation[creators[i]]["highPopIndex"] = "z" + + relation[creators[i]]["totalPopular"] += views[i] + highPopular = max(relation[creators[i]]["totalPopular"], highPopular) + + #print(relation[creators[i]]["highPopIndex"], ids[i]) + if views[i] > relation[creators[i]]["highPopVal"]: + relation[creators[i]]["highPopVal"] = views[i] + relation[creators[i]]["highPopIndex"] = ids[i] + elif views[i] == relation[creators[i]]["highPopVal"] and relation[creators[i]]["highPopIndex"] > ids[i]: + relation[creators[i]]["highPopVal"] = views[i] + relation[creators[i]]["highPopIndex"] = ids[i] + + ans = [] + visited = set() + for i in range(len(creators)): + if creators[i] in visited: + continue + if relation[creators[i]]["totalPopular"] == highPopular: + ans.append([creators[i], relation[creators[i]]["highPopIndex"]]) + visited.add(creators[i]) + + return ans diff --git a/ProblemSolving/moveZeroes/move.py b/ProblemSolving/moveZeroes/move.py new file mode 100644 index 0000000..8b102d1 --- /dev/null +++ b/ProblemSolving/moveZeroes/move.py @@ -0,0 +1,18 @@ +class Solution(object): + def moveZeroes(self, nums): + """ + :type nums: List[int] + :rtype: None Do not return anything, modify nums in-place instead. + """ + + temp = None + for i in range(len(nums)): + if nums[i] != 0 and temp != None: + nums[i], nums[temp] = nums[temp], nums[i] + temp += 1 + else: + if temp == None and nums[i] == 0: + temp = i + #print(temp, nums, i) + #print(nums) + return nums diff --git a/ProblemSolving/movingAverageFromDataStream/move.py b/ProblemSolving/movingAverageFromDataStream/move.py new file mode 100644 index 0000000..82fbd16 --- /dev/null +++ b/ProblemSolving/movingAverageFromDataStream/move.py @@ -0,0 +1,60 @@ +# Logic 1: Naive queue type method --> 100 pass 21% faster --> O(N) +""" +class MovingAverage: + + def __init__(self, size: int): + self.sliding_window = [] + self.size = size + + + def next(self, val: int) -> float: + # Maintian window size + n = len(self.sliding_window) + if len(self.sliding_window) == self.size: + self.sliding_window = self.sliding_window[1:] + self.sliding_window.append(val) + # calculate the average + return float(sum(self.sliding_window)/len(self.sliding_window)) # This causes it to be O(N) + +# Your MovingAverage object will be instantiated and called as such: +# obj = MovingAverage(size) +# param_1 = obj.next(val) +""" + +# Logic 2: Queue with head/tail + window sum tracking - 98% faster ( ref from solutions in lt ) +class MovingAverage: + + def __init__(self, size: int): + """ + Initialize your data structure here. + """ + self.sliding_window = [0]*size + self.size = size + + self.head = 0 + self.window_sum = 0 + self.stream_length = 0 + + + def next(self, val: int) -> float: + # Update the current window length + self.stream_length += 1 + + # Set the tail properly + tail = (self.head + 1) % self.size + + # Calculate the moving window sum + self.window_sum = self.window_sum - self.sliding_window[tail] + val + + # update head and values + self.head = (self.head + 1) % self.size + self.sliding_window[self.head] = val + + # calculate avg + return self.window_sum/min(self.stream_length, self.size) + +# Your MovingAverage object will be instantiated and called as such: +# obj = MovingAverage(size) +# param_1 = obj.next(val) + + diff --git a/ProblemSolving/movingStonesUntilConsecutive/move.py b/ProblemSolving/movingStonesUntilConsecutive/move.py new file mode 100644 index 0000000..9584109 --- /dev/null +++ b/ProblemSolving/movingStonesUntilConsecutive/move.py @@ -0,0 +1,32 @@ +class Solution(object): + def numMovesStones(self, a, b, c): + """ + :type a: int + :type b: int + :type c: int + :rtype: List[int] + """ + + # Logic 1: Sort the ranges to obtain possible consecutive + a, b, c = sorted([a,b,c]) + moves = [0, 0] + # Minimum should exist or be 1 or be 2 at the max + if (b-a) == 1 and (c-b) == 1: + moves[0] = 0 + elif (b-a) > 2 and (c-b) > 2: + moves[0] = 2 + else: + moves[0] = 1 + # Maximum must be total length and empty spots + moves[1] = c - a - 2 # c - a is full range and minus 2 for c,a + return moves + + """ + # Scribble + moves = [0, 0] + if abs(a-b) != 1 or abs(b-c) != 1: + n = max([a,b,c]) + moves[0] = 1 + moves[1] = n-3 + return moves + """ diff --git a/ProblemSolving/multiplyStrings/multiply.py b/ProblemSolving/multiplyStrings/multiply.py new file mode 100644 index 0000000..9fbee2e --- /dev/null +++ b/ProblemSolving/multiplyStrings/multiply.py @@ -0,0 +1,30 @@ +# Logic 1: Naive method of using dictionary to map string and numbers representation of integers ( 0-9) - 80% faster +class Solution: + def multiply(self, num1: str, num2: str) -> str: + + def numberFromString(n, numStr): + num = 0 + l = len(n)-1 + for i in range(l+1): + num += 10**(l-i) * numStr[n[i]] + return num + + # 1. String number dictionary - it can be hardcoded without using str() one time + numStr = {} + for i in range(10): + numStr[str(i)] = i + strNum = {} + for i in range(10): + strNum[i] = str(i) + + # 2. Construct number from string + prod = numberFromString(num1, numStr)*numberFromString(num2, numStr) + + # 3. Construct string after product + result = "" + while prod: + result = strNum[prod%10] + result + prod = prod//10 + if result == "" and prod == 0: + return "0" + return result diff --git a/ProblemSolving/myCalendarI/my.py b/ProblemSolving/myCalendarI/my.py new file mode 100644 index 0000000..224c249 --- /dev/null +++ b/ProblemSolving/myCalendarI/my.py @@ -0,0 +1,75 @@ +class Node: + def __init__(self, value): + self.val = value + self.left = None + self.right = None + + +class MyCalendar(object): + + # Logic 1: expand ranges and use set property - Time limit exceeded + """ + def __init__(self): + + # Data structure to store all the events + + # Logic 1 + # List with all the ranges in the expanded form + self.events = [] + + def book(self, start, end): + + # Overlapping intervals using SET() + if set(self.events).intersection(range(start, end)): + return False + else: + self.events.extend(range(start,end)) + return True + """ + + # Logic 2: range as tuples on a list and iterate o(N) - 100 pass 5% gaster + + def __init__(self): + + # Data structure to store all the events + + # Literally store all the range in list as tuples + self.events = [] + def book(self, start, end): + + # Iterate O(N) over all the ranges + for intervals in self.events: + s = intervals[0] + e = intervals[1] + # Start, End within the intervals - directly overlapping sets + if (s <= start <= e-1) or (s <= (end-1) <= e-1): + #print(intervals, start, end) + return False + elif (start <= s <= end-1) or (start <= (e-1) <= end-1): + # Indirect overlapping sets - wide start and end + return False + self.events.append((start,end)) + self.events.sort() + return True + + """ + # Logic 3: use better datastructure and sort the ranges in order for better search + + + # Dictionary with schema , to look up faster than list lookup + #self.events = {} + # Or use a bst + + #def __init__(self): + # self.root = Node(0) + + #def book(self, start, end): + """ + + + + + +# Your MyCalendar object will be instantiated and called as such: +# obj = MyCalendar() +# param_1 = obj.book(start,end) diff --git a/ProblemSolving/naryTreePreOrderTraversal/iterative_recursive.py b/ProblemSolving/naryTreePreOrderTraversal/iterative_recursive.py new file mode 100644 index 0000000..51c5516 --- /dev/null +++ b/ProblemSolving/naryTreePreOrderTraversal/iterative_recursive.py @@ -0,0 +1,66 @@ +""" +# Definition for a Node. +class Node(object): + def __init__(self, val, children): + self.val = val + self.children = children +""" +class Solution(object): + + def preorder(self, root): + """ + :type root: Node + :rtype: List[int] + """ + + # Iterative method of preorder traversal - 100 pass - 176ms + + # Stack to keep track of traversal + self.traverse_stack = [root] + + # Result + self.preorder = [] + + # Traverse until self.traverse_stack is empty + while self.traverse_stack: + # PreOrder - get the first node leftmost + current = self.traverse_stack.pop(0) + if current: + # Add to results + self.preorder.append(current.val) + # add children to the front of the array ==> preOrder + if current.children: + self.traverse_stack = current.children + self.traverse_stack + return self.preorder + + # Recursive Method ==> 100% pass - 180ms + """ + # Global list to hold the preorder nodes + self.preorder = [] + + # Recursive function + def traverse(node): + + # Node null check + if not node: + return + + # Append current node to list + self.preorder.append(node.val) + + # if node contains children, recurse all the children (left -> right) + if node.children: + for child in node.children: + traverse(child) + + # function call + traverse(root) + + return self.preorder + """ + + + + + + diff --git a/ProblemSolving/networkTimeDelay/network.py b/ProblemSolving/networkTimeDelay/network.py new file mode 100644 index 0000000..6ec779d --- /dev/null +++ b/ProblemSolving/networkTimeDelay/network.py @@ -0,0 +1,99 @@ +class Solution: + def networkDelayTime(self, times: List[List[int]], N: int, K: int) -> int: + + # Logic 1: Build a graph, populate them as directed and then another loop to solve signal - Time Limit Exceeded..... but works for most of the TCs + """ + + # Find Path from S to E + def signal_flow(graph, src, dst, path, time): + path = [path] + [src] + if src == dst: + return path, time + if src not in graph: + return [], 0 + ts = [] + for node in graph[src]: + nxt, t = node + if nxt not in path: + new_path, new_time = signal_flow(graph, nxt, dst, path, time+t) + if new_path: + ts.append(new_time) + if ts: + return path, min(ts) + else: + return [],0 + + # Graph init + graph = {} + + # Populate the Graph + for time in times: + src, dst, t = time + if src not in graph: + graph[src] = [] + if dst not in graph: + graph[dst] = [] + graph[src].append([dst, t]) + + # Track Signal + if (K not in graph) or (K in graph and graph[K] == []): + return -1 + + if len(graph.keys()) < N: + return -1 + + signal = [None]*N + signal[K-1] = 0 + all_time = 0 + + for dest in graph.keys(): + if dest != K: + p, signal[dest-1] = signal_flow(graph, K, dest, [], 0) + #print(p, signal) + if signal[dest-1] == 0: + return -1 + all_time = max(all_time, signal[dest-1]) + if signal[dest-1] is None: + return -1 + + return all_time + """ + + # Logic 2: Same gist as above with set(), dijikstra algo - 99% + + # Graph Init + graph = {} + + # Graph Build + # Populate the Graph + for time in times: + src, dst, t = time + if src not in graph: + graph[src] = [] + if dst not in graph: + graph[dst] = [] + graph[src].append([t, dst]) + + visited = set() + stack = [(0, K)] + signal_flow = {i:float('inf') for i in range(1, N+1)} + signal_flow[K] = 0 + + while stack: + c_wgt, c_node = heapq.heappop(stack) + if c_node in visited: + continue + visited.add(c_node) + if len(visited) == N: + return c_wgt + for n_wgt, n_node in graph[c_node]: + new_cost = c_wgt + n_wgt + if new_cost < signal_flow[n_node] and n_node not in visited: + signal_flow[n_node] = new_cost + heapq.heappush(stack, (new_cost, n_node)) + return -1 + + + + + diff --git a/ProblemSolving/networkTimeDelay/network2.py b/ProblemSolving/networkTimeDelay/network2.py new file mode 100644 index 0000000..16c733d --- /dev/null +++ b/ProblemSolving/networkTimeDelay/network2.py @@ -0,0 +1,78 @@ +# Logic: naive graph traversal and shortest time calc per node +class Solution: + def networkDelayTime(self, times: List[List[int]], n: int, k: int) -> int: + + self.graph = {} + + # 1. construct graph and compute times + for time in times: + + src = time[0] + dst = time[1] + t = time[2] + + if src not in self.graph: + self.graph[src] = [] + self.graph[src].append((dst, t)) + + #print(self.graph) + + # 2. traverse graph + def traverse(current, time, visited): + + val, t = current + + full_time = time + t + + if self.times[val] == -1: + self.times[val] = full_time + elif full_time < self.times[val]: + self.times[val] = full_time + else: + return + + if val in self.graph: + for nxt in self.graph[val]: + nval, ntime = nxt + + if nval in visited: + continue + if self.times[nval] != -1 and full_time+ntime >= self.times[nval]: + continue + + traverse(nxt, full_time, visited.union({nval})) + else: + return + + return + + # 3. check all paths from k + #if k not in self.graph: + # return -1 + + """ + for i in range(1, n+1): + if k == i: + continue + path_time = traverse((k,0), i, 0, set()) + #print(i, path_time) + if path_time == 0: + return -1 + if path_time > self.max_time: + self.max_time = path_time + """ + + self.times = [-1]*(n+1) + traverse((k,0), 0, set()) + + #print(self.times) + self.times[k] = 0 + self.times = self.times[1:] + + self.max = 0 + for i in self.times: + if i == -1: + return -1 + if i > self.max: + self.max = i + return self.max diff --git a/ProblemSolving/nextGreaterNodeInLinkedList/next.py b/ProblemSolving/nextGreaterNodeInLinkedList/next.py new file mode 100644 index 0000000..410d420 --- /dev/null +++ b/ProblemSolving/nextGreaterNodeInLinkedList/next.py @@ -0,0 +1,56 @@ +# Definition for singly-linked list. +# class ListNode(object): +# def __init__(self, x): +# self.val = x +# self.next = None + +class Solution(object): + def nextLargerNodes(self, head): + """ + :type head: ListNode + :rtype: List[int] + """ + + # 100 pass + # - Evaluated most with some help from reference to finish off + # - https://leetcode.com/problems/next-greater-node-in-linked-list/discuss/265508/JavaC%2B%2BPython-Next-Greater-Element + # Stack to keep track of nodes that are of lesser value ( next greater yet to be found) + stack = [] + # Result to hold nodes whose next greater has been found + result = [] + # traverse length of the list as we traverse + count = 0 + + # Traverse List + while head: + # Next greater is found + while stack and head.val > stack[-1][1]: + result[stack.pop()[0]] = head.val + # Append to stack the index of occurrence and value whose next greater should be found + stack.append([count, head.val]) + # Next greater will eventually be found, else 0 so add 0 by default + result.append(0) + count += 1 + head = head.next + return result + + + """ + print stack, result, count + if stack and head.val < stack[-1]: + stack.append(head.val) + else: + while stack and head.val > stack[0]: + stack.pop(0) + result.append(head.val) + stack.append(head.val) + if not stack: + # if count == len(result): + # result.append(0) + #if result[-1] == head.val: + # result.append(0) + #else: + stack.append(head.val) + head = head.next + count += 1 + """ diff --git a/ProblemSolving/nthTribonacciSeries/nth.py b/ProblemSolving/nthTribonacciSeries/nth.py new file mode 100644 index 0000000..69575ec --- /dev/null +++ b/ProblemSolving/nthTribonacciSeries/nth.py @@ -0,0 +1,77 @@ +class Solution(object): + def tribonacci(self, n): + """ + :type n: int + :rtype: int + """ + + # Logic 1: Simple Iterative by swapping - 100 pass 90% faster + """ + # Declare first three values + T0 = 0 + T1 = 1 + T2 = 1 + + # Iterate to find nth value and swap + for i in range(3,n+1): + Tn = T0 + T1 + T2 + T0 = T1 + T1 = T2 + T2 = Tn + + # Condition when n < 3 + if n == 0: + Tn = T0 + elif n == 1: + Tn = T1 + elif n == 2: + Tn = T2 + + return Tn + """ + + # Logic 2: Iterate using O(N) space - 70 percent faster + + """ + # Init array with initial values + series = [0, 1, 1] + + # Iterate and extend series in the array + for i in range(3, n+1): + series.append(series[-1]+series[-2]+series[-3]) + + return series[n] + """ + + # Logic 3: Recursive - Time limit exceeded obviously and it takes forever. + """ + def recurse_series(n): + # Return first few initial values 0, 1, 2 + if n == 0: + return 0 + elif n == 1: + return 1 + elif n == 2: + return 1 + else: + # Calculate and return other values + return recurse_series(n-1) + recurse_series(n-2) + recurse_series(n-3) + + return recurse_series(n) + """ + + # Logic 4: Recursive with Memoization + + # Memo array with initial values + memo = [0, 1, 1] + def recurse_series(n): + # Return memoized values + if n < len(memo): + return memo[n] + else: + # Calculate and return other values + next_value = recurse_series(n-1) + recurse_series(n-2) + recurse_series(n-3) + memo.append(next_value) + return next_value + + return recurse_series(n) diff --git a/ProblemSolving/nthTribonacciSeries/nth2.py b/ProblemSolving/nthTribonacciSeries/nth2.py new file mode 100644 index 0000000..b056ac8 --- /dev/null +++ b/ProblemSolving/nthTribonacciSeries/nth2.py @@ -0,0 +1,14 @@ +class Solution: + def __init__(self): + self.memo = { + 0: 0, + 1: 1, + 2: 1 + } + + def tribonacci(self, n: int) -> int: + + if n in self.memo: + return self.memo[n] + self.memo[n] = self.tribonacci(n-1) + self.tribonacci(n-2) + self.tribonacci(n-3) + return self.memo[n] diff --git a/ProblemSolving/numOfStudentsDoingHomework/num.py b/ProblemSolving/numOfStudentsDoingHomework/num.py new file mode 100644 index 0000000..0d0458c --- /dev/null +++ b/ProblemSolving/numOfStudentsDoingHomework/num.py @@ -0,0 +1,10 @@ +# Logic 1: Iterate both array together - 94% faster +class Solution: + def busyStudent(self, startTime: List[int], endTime: List[int], queryTime: int) -> int: + student = 0 + count = 0 + while student < len(startTime): + if startTime[student] <= queryTime <= endTime[student]: + count += 1 + student += 1 + return count diff --git a/ProblemSolving/numberOfConnectedComponentsInAnUndirectedGraph/connect.py b/ProblemSolving/numberOfConnectedComponentsInAnUndirectedGraph/connect.py new file mode 100644 index 0000000..5783bba --- /dev/null +++ b/ProblemSolving/numberOfConnectedComponentsInAnUndirectedGraph/connect.py @@ -0,0 +1,47 @@ +class Solution: + def countComponents(self, n: int, edges: List[List[int]]) -> int: + # Logic 1: + # * if there is an edge, add the respective nodes to a separate group as a key in dictionary + """ + connected_groups = {0:set(edges[0])} + g = 1 + for edge in edges: + for group in list(connected_groups.keys()): + if edge[0] in connected_groups[group]: + connected_groups[group].add(edge[0]) + connected_groups[group].add(edge[1]) + elif edge[1] in connected_groups[group]: + connected_groups[group].add(edge[1]) + connected_groups[group].add(edge[0]) + else: + connected_groups[g] = set() + connected_groups[g].add(edge[1]) + connected_groups[g].add(edge[0]) + g += 1 + print(connected_groups) + return len(connected_groups.keys()) + """ + + # Logic 2: proper dfs + + graph = [[] for i in range(n)] + visited = [False for i in range(n)] + connected = 0 + + for edge in edges: + graph[edge[0]].append(edge[1]) + graph[edge[1]].append(edge[0]) + + def dfs(node): + for nei in graph[node]: + if not visited[nei]: + visited[nei] = True + dfs(nei) + + for i in range(n): + if not visited[i]: + visited[i] = True + connected += 1 + dfs(i) + + return connected diff --git a/ProblemSolving/numberOfDiceRollsWithTargetSum/num.py b/ProblemSolving/numberOfDiceRollsWithTargetSum/num.py new file mode 100644 index 0000000..3b81901 --- /dev/null +++ b/ProblemSolving/numberOfDiceRollsWithTargetSum/num.py @@ -0,0 +1,62 @@ +class Solution(object): + def numRollsToTarget(self, d, f, target): + """ + :type d: int + :type f: int + :type target: int + :rtype: int + """ + + # Logic 1: All combinations brute force - Obviously time limit exceeded! Otherwise all test cases passed + """ + dice = [range(1,f+1) for i in range(d)] + #print(dice) + import itertools + times = 0 + n = len(dice)-1 + if n <= 0: + n = 1 + for comb in itertools.product(*dice, repeat=n): + #print(comb) + if sum(comb) == target: + times += 1 + return times + """ + + # Logic 2: We can leverage the sum logic here, once we select one dice value all other dice values are target-selected value + # * also all the subproblems ( each dice roll ) affects the next dice roll's choice - dynamic programming like + # * Lets go recursive with top down approach + # * Time Limit exceeded with 30, 30 , 500 --> We need to memoize or cache values + """ + def roll(next_dice, targt): + print(next_dice, targt) + if next_dice <= d: + for face in dice.keys(): + next_face = targt - face + print(face, next_face) + if next_dice == d and next_face == 0: + self.times += 1 + return + elif next_face > 0: + roll(next_dice+1, next_face) + else: + return + + import collections + dice = collections.Counter(range(1,f+1)) + self.times = 0 + roll(1, target) + return self.times + """ + + # Logic 3: DP with Table for reference + dp = [[0 for i in range(target+1)] for j in range(d+1)] + dp[0][0] = 1 + mod = 10**9 + 7 + for i in range(1,d+1): + for j in range(1,target+1): + k = 1 + while k <= min(j,f): + dp[i][j] = (dp[i][j] + dp[i-1][j-k]) % mod + k += 1 + return dp[d][target] % mod diff --git a/ProblemSolving/numberOfEquivalentDominoPairs/num.py b/ProblemSolving/numberOfEquivalentDominoPairs/num.py new file mode 100644 index 0000000..f7b7373 --- /dev/null +++ b/ProblemSolving/numberOfEquivalentDominoPairs/num.py @@ -0,0 +1,34 @@ +class Solution(object): + def numEquivDominoPairs(self, dominoes): + """ + :type dominoes: List[List[int]] + :rtype: int + """ + + # Logic 2: Use SET/Dictionary of all the pairs as string and check if we have already visited O(N) space O(N) - 95% faster + pairs = {} + count = 0 + for domino in dominoes: + if domino[0] < domino[1]: + key = domino[0]*10 + domino[1] + else: + key = domino[1]*10 + domino[0] + if key in pairs: + pairs[key] += 1 + if key not in pairs: + pairs[key] = 0 + for key, value in pairs.items(): + if pairs[key] > 0: + pairs[key] += 1 + count += (pairs[key]*(pairs[key]-1))//2 + return count + + # Logic 1: Naive O(N2) logic - Time Limit Exceeded + """ + count = 0 + for d in range(len(dominoes)): + for e in range(d+1, len(dominoes)): + if dominoes[d] == dominoes[e] or dominoes[d] == dominoes[e][::-1]: + count += 1 + return count + """ diff --git a/ProblemSolving/numberOfIslands/anotherOne.py b/ProblemSolving/numberOfIslands/anotherOne.py new file mode 100644 index 0000000..33906d7 --- /dev/null +++ b/ProblemSolving/numberOfIslands/anotherOne.py @@ -0,0 +1,30 @@ +class Solution: + def numIslands(self, grid: List[List[str]]) -> int: + + self.islands = [] + + def findIsland(i, j , currIsland, grid): + currIsland.add((i,j)) + for x in [-1,1]: + if -1 < i+x < len(grid) and grid[i+x][j] == "1" and (i+x,j) not in currIsland: + currIsland.update(findIsland(i+x,j,currIsland,grid)) + for y in [-1,1]: + if -1 < j+y < len(grid[0]) and grid[i][j+y] == "1" and (i,j+y) not in currIsland: + currIsland.update(findIsland(i,j+y,currIsland,grid)) + return currIsland + + def isAlreadyAnIsland(x, y): + for island in self.islands: + #print(x,y,island) + if (x,y) in island: + return True + return False + + for i in range(len(grid)): + for j in range(len(grid[0])): + if grid[i][j] == "1" and not isAlreadyAnIsland(i,j): + currIsland = findIsland(i,j,set(),grid) + #print(currIsland) + self.islands.append(currIsland) + + return len(self.islands) diff --git a/ProblemSolving/numberOfIslands/num.py b/ProblemSolving/numberOfIslands/num.py new file mode 100644 index 0000000..c4ff629 --- /dev/null +++ b/ProblemSolving/numberOfIslands/num.py @@ -0,0 +1,66 @@ +class Solution(object): + def numIslands(self, grid): + """ + :type grid: List[List[str]] + :rtype: int + """ + + # Logic 1 -> Naive Iteration and using sets --> Fails for scale cases ( has some pass rate ) + # * Visit islands and perform set union for every set intersection + # * Count the number of such sets + """ + # Set of all the islands in the format ij + islands = [] + + # 2D array iteration + for i in range(len(grid)): # Rows + for j in range(len(grid[0])): # Columns + #print(i,j) + land = set() + if grid[i][j] == "1": # Ignore if water, focus on land + land.add(str(i)+str(j)) + # Row top and bottom + if i-1 >= 0 and grid[i-1][j] == "1": + land.add(str(i-1)+str(j)) + if i+1 < len(grid) and grid[i+1][j] == "1": + land.add(str(i+1)+str(j)) + # Column left and right + if j-1 >= 0 and grid[i][j-1] == "1": + land.add(str(i)+str(j-1)) + if j+1 < len(grid[0]) and grid[i][j+1] == "1": + land.add(str(i)+str(j+1)) + #print(land, islands) + k = 0 + while k < len(islands): + if len(land.intersection(islands[k])) > 0: + land = land.union(islands.pop(k)) + else: + k += 1 + if land: + islands.append(land) + return len(islands) + """ + + # Logic 2 -> Recursive - 100 pass + # * visit all 1s change then to visited "$" or "0" and backtrack to find more linked near to it + + def track_islands(r, c): + #print(r, c) + if r < len(grid) and c < len(grid[0]) and r >= 0 and c >= 0 and grid[r][c] == "1": + grid[r][c] = "$" + track_islands(r-1, c) + track_islands(r+1, c) + track_islands(r, c+1) + track_islands(r, c-1) + return 1 + return 0 + + count = 0 + for i in range(len(grid)): + for j in range(len(grid[0])): + if grid[i][j] == "1": + count += track_islands(i, j) + + return count + + diff --git a/ProblemSolving/numberOfMatchingSubsequence/num.py b/ProblemSolving/numberOfMatchingSubsequence/num.py new file mode 100644 index 0000000..6d3f59f --- /dev/null +++ b/ProblemSolving/numberOfMatchingSubsequence/num.py @@ -0,0 +1,50 @@ +class Solution: + + # Logic 1: store string by index and iterate words for subsequence checks + def numMatchingSubseq(self, s: str, words: List[str]) -> int: + + full = {} + for i in range(len(s)): + if s[i] not in full: + full[s[i]] = [] + full[s[i]].append(i) + + result = [] + + for word in words: + visited = set() + prev = -1 + isSub = True + for w in range(len(word)): + if word[w] not in full: + isSub = False + break + + curr = None + for r in full[word[w]]: + key = word[w]+str(r) + if r > prev and key not in visited: + curr = r + visited.add(key) + break + + if curr == None: + isSub = False + break + + if prev == -1: + prev = curr + elif curr < prev: + isSub = False + break + else: + prev = curr + + #print(word, visited) + if isSub and len(visited) == len(word): + result.append(word) + + print(result) + return len(result) + + diff --git a/ProblemSolving/numberOfProvinces/num.py b/ProblemSolving/numberOfProvinces/num.py new file mode 100644 index 0000000..3255f1c --- /dev/null +++ b/ProblemSolving/numberOfProvinces/num.py @@ -0,0 +1,29 @@ +class Solution: + def findCircleNum(self, isConnected: List[List[int]]) -> int: + + # Init vars + visited = set() + provinces = 0 + + # Contruct a graph + graph = {} + for i in range(len(isConnected[0])): + for j in range(len(isConnected)): + if i not in graph: + graph[i] = [] + if isConnected[i][j] == 1 and i != j: + graph[i].append(j) + + # Traverse graph by not-yet-visited vertices to cover all edges + for k, v in graph.items(): + if k in visited: + continue + stack = v + # cover all edges + for e in stack: + if e not in visited: + visited.add(e) + if e in graph: + stack.extend(graph[e]) + provinces += 1 + return provinces diff --git a/ProblemSolving/numberOfRecentCalls/num.py b/ProblemSolving/numberOfRecentCalls/num.py index e8a1cba..1fff4b0 100644 --- a/ProblemSolving/numberOfRecentCalls/num.py +++ b/ProblemSolving/numberOfRecentCalls/num.py @@ -1,3 +1,31 @@ +# Newer better logic +class RecentCounter(object): + + def __init__(self): + # Initialize class variable to track time of pings + self.ping_at_last_time = [] + + + def ping(self, t): + """ + :type t: int + :rtype: int + """ + + # Add time to ping + self.ping_at_last_time.append(t) + # Iterate the first few ping times comparing with current time to eliminate ping > 3000 + while (t-self.ping_at_last_time[0]) > 3000: + self.ping_at_last_time.pop(0) + # Return all the current pings + return len(self.ping_at_last_time) + + +# Your RecentCounter object will be instantiated and called as such: +# obj = RecentCounter() +# param_1 = obj.ping(t) + +""" class RecentCounter(object): def __init__(self): @@ -40,3 +68,4 @@ def ping(self, t): # Your RecentCounter object will be instantiated and called as such: # obj = RecentCounter() # param_1 = obj.ping(t) +""" diff --git a/ProblemSolving/numberOfStepsToReduceANumberToZero/num.py b/ProblemSolving/numberOfStepsToReduceANumberToZero/num.py new file mode 100644 index 0000000..9d7eac3 --- /dev/null +++ b/ProblemSolving/numberOfStepsToReduceANumberToZero/num.py @@ -0,0 +1,34 @@ +class Solution: + + # Logic 1: Iterative --> Literally following the description - 100 pass + """ + def numberOfSteps (self, num: int) -> int: + step = 0 + while num: + if num%2 == 0: + num = num//2 + else: + num -= 1 + step += 1 + return step + """ + + # Logic 2: Recursive --> same as above - 100 pass + def numberOfSteps (self, num: int) -> int: + + def reduce(num: int, steps: int): + # Exit criteria + if num == 0: + return steps + + # Reduce to subproblems + if num%2 != 0: + num -= 1 + else: + num = num//2 + + # Recurse each sub problem + return reduce(num, steps+1) + + return reduce(num, 0) + \ No newline at end of file diff --git a/ProblemSolving/numberOfUniqueEmails/num.go b/ProblemSolving/numberOfUniqueEmails/num.go new file mode 100644 index 0000000..2423322 --- /dev/null +++ b/ProblemSolving/numberOfUniqueEmails/num.go @@ -0,0 +1,37 @@ +func numUniqueEmails(emails []string) int { + + result := []string{} + + for _, email := range emails { + + // split local and domain name with "@" + e := strings.Split(email, "@") + localname, domainname := e[0], e[1] + + if strings.Contains(localname, ".") { + localname = strings.Replace(localname, ".", "", -1) + } + + if strings.Contains(localname, "+") { + localname = strings.Split(localname, "+")[0] + } + + // Debug + //fmt.Println(localname+"@"+domainname) + filtered_email := localname+"@"+domainname + + existence := 0 + for _, val := range result { + if val == filtered_email { + existence = 1 + } + } + + if existence == 0 { + result = append(result, filtered_email) + } + + } + + return len(result) +} diff --git a/ProblemSolving/numberOfUniqueEmails/num.py b/ProblemSolving/numberOfUniqueEmails/num.py new file mode 100644 index 0000000..c525ec1 --- /dev/null +++ b/ProblemSolving/numberOfUniqueEmails/num.py @@ -0,0 +1,38 @@ +class Solution(object): + def numUniqueEmails(self, emails): + """ + :type emails: List[str] + :rtype: int + """ + + # Understanding + # * Split by @ to get ==> localname and domain name + # * "." => split by "." and join without it or replace "." by "" + # * "+" => split by "+" and take index 0 + # * last 2 rule only applies to localname + + # Iteration over the list + result = [] + for email in emails: + + # Identify names + localname, domainname = email.split("@") + + # Rule 1 about "." + if "." in localname: + localname = localname.replace(".","") + + # Rule 2 about "+" + if "+" in localname: + localname = localname.split("+")[0] + + filtered_email = localname+"@"+domainname + + if filtered_email not in result: + result.append(filtered_email) + + return len(result) + + + + diff --git a/ProblemSolving/occurencesAfterBigram/occur.py b/ProblemSolving/occurencesAfterBigram/occur.py new file mode 100644 index 0000000..8689f85 --- /dev/null +++ b/ProblemSolving/occurencesAfterBigram/occur.py @@ -0,0 +1,24 @@ +class Solution(object): + def findOcurrences(self, text, first, second): + """ + :type text: str + :type first: str + :type second: str + :rtype: List[str] + """ + + # Logic: Iterate and return the third elements - O(N) == 100% faster + result = [] # Result variable + text = text.split(" ") # Split text into words + i = 0 + while i < len(text): + if text[i] == first and (i+1 < len(text) and text[i+1] == second): + if i+2 < len(text): + result.append(text[i+2]) + i = i+1 + i += 1 + return result + + + + diff --git a/ProblemSolving/oneEditDistance/one.py b/ProblemSolving/oneEditDistance/one.py new file mode 100644 index 0000000..c69e21a --- /dev/null +++ b/ProblemSolving/oneEditDistance/one.py @@ -0,0 +1,114 @@ +class Solution(object): + def isOneEditDistance(self, s, t): + """ + :type s: str + :type t: str + :rtype: bool + """ + + # Logic 3: Retain the order and iterate across the same characters, remember we need to --> add in front, remove in back or replace the character one time + # * they will surely match as we iterate else fail out - 100 pass 66% faster + pointer1 = 0 + pointer2 = 0 + diff = 0 + if not s and not t: + return False + while pointer1 < len(s) or pointer2 < len(t): + # 3. Out of index condition - exceeded one of the string + if (pointer1 < len(s) and pointer2 >= len(t)): + diff += 1 + pointer1 += 1 + continue + elif (pointer1 >= len(s) and pointer2 < len(t)): + diff += 1 + pointer2 += 1 + continue + + # 1. Both characters are equal + if s[pointer1] == t[pointer2]: + pointer1 += 1 + pointer2 += 1 + continue + + # When they are not equal + diff += 1 # if not equal they are different + + # 2. Proceedingly they should be equal else fail + if pointer1+1 < len(s) and s[pointer1+1] == t[pointer2]: + pointer1 += 1 + continue + elif pointer2+1 < len(t) and t[pointer2+1] == s[pointer1]: + pointer2 += 1 + continue + else: # They are not equal more than once, FAIL + pointer1 += 1 + pointer2 += 1 + if diff > 1: + return False + continue + + if diff == 1: + return True + else: + return False + + # Logic 1: Does not work when the sorted order are different "ab vs bc" --> FAIL + """ + s = sorted(s) + t = sorted(t) + n = len(s) + m = len(t) + if n > m: + t += "0"*(n-m) + else: + s += "0"*(m-n) + count = 0 + for i, j in zip(s, t): + if i == 0 or j == 0: + count += 1 + elif i != j: + count += 1 + if count > 1: + return False + if count == 1: + return True + else: + return False + """ + + # Logic 2: Find the Intersection + # * finds the different string correctly but replace, add, delete rule fails! --> FAIL + """ + import collections + sc = collections.Counter(s) + tc = collections.Counter(t) + if len(s) > len(t): + for i in range(len(s)): + if s[i] in tc: + sc[s[i]] -= 1 + tc[s[i]] -= 1 + if sc[s[i]] == 0: + del sc[s[i]] + if tc[s[i]] == 0: + del tc[s[i]] + print(sc) + if len(sc.keys()) == 1: + return True + else: + return False + else: + for i in range(len(t)): + if t[i] in sc: + tc[t[i]] -= 1 + sc[t[i]] -= 1 + if tc[t[i]] == 0: + del tc[t[i]] + if sc[t[i]] == 0: + del sc[t[i]] + print(tc) + if len(tc.keys()) == 1: + return True + else: + return False + """ + diff --git a/ProblemSolving/onlineStockPlan/online.py b/ProblemSolving/onlineStockPlan/online.py new file mode 100644 index 0000000..deffad3 --- /dev/null +++ b/ProblemSolving/onlineStockPlan/online.py @@ -0,0 +1,48 @@ +# Pending... +class StockSpanner(object): + + # Logic to literally follow the question and build solution (no specific technique) + + def __init__(self): + + # Just initialize with a data structure + self.prices = [] + self.span = [] + + def next(self, price): + """ + :type price: int + :rtype: int + """ + + self.prices.append(price) + + # Iterate the days to obtain max consecutive days + n = len(self.prices) + + # Track count - account to track max to work for large num of days + max_consecutive = 0 + count_progress = 0 + + # Iteration from the current day backwards + i = n-1 + while i >= 0: + if self.prices[i] <= price: + count_progress += 1 + else: + break + + # Maximum condition + #if count_progress > max_consecutive: + # max_consecutive = count_progress + + i -= 1 + + self.span.append(count_progress) + + return count_progress + + +# Your StockSpanner object will be instantiated and called as such: +# obj = StockSpanner() +# param_1 = obj.next(price) diff --git a/ProblemSolving/optimalPartitionOfString/optimal.py b/ProblemSolving/optimalPartitionOfString/optimal.py new file mode 100644 index 0000000..402a0c6 --- /dev/null +++ b/ProblemSolving/optimalPartitionOfString/optimal.py @@ -0,0 +1,16 @@ +class Solution: + def partitionString(self, s: str) -> int: + + window = {} + partitions = [[]] + for i in range(len(s)): + if s[i] in window: + window = {s[i]:True} + partitions.append([s[i]]) + else: + partitions[-1] += s[i] + window[s[i]] = True + + print(partitions) + return len(partitions) + diff --git a/ProblemSolving/orangesRotting/orange.py b/ProblemSolving/orangesRotting/orange.py new file mode 100644 index 0000000..4935926 --- /dev/null +++ b/ProblemSolving/orangesRotting/orange.py @@ -0,0 +1,63 @@ +class Solution(object): + def orangesRotting(self, grid): + """ + :type grid: List[List[int]] + :rtype: int + """ + + # Logic 1: Use a datastructure to help ( dict or stack ) - lets use stack of rotten to start with + # 1st find the rotten orange + # 2nd recurse or add the adjacent oranges to a bucket + # Continue until no rotten oranges are found + + # Build stack of rotten oranges + stack = [[]] + count_oranges = 0 + for i in range(len(grid)): + for j in range(len(grid[0])): + # Finding the rotten orange + if grid[i][j] == 2: + stack[0].append((i, j)) + if grid[i][j] > 0: + count_oranges += 1 + + minute = 0 + rotten_orange = len(stack[0]) + #print(stack, rotten_orange) + while stack: + current_stack = stack.pop(0) + new_stack = [] + while current_stack: + current_rotten = current_stack.pop(0) + x = current_rotten[0] + y = current_rotten[1] + # build adjacents and check + if x-1 >= 0 and grid[x-1][y] == 1: + grid[x-1][y] += 1 + new_stack.append((x-1,y)) + rotten_orange += 1 + if x+1 < len(grid) and grid[x+1][y] == 1: + grid[x+1][y] += 1 + new_stack.append((x+1,y)) + rotten_orange += 1 + if y-1 >= 0 and grid[x][y-1] == 1: + grid[x][y-1] += 1 + new_stack.append((x,y-1)) + rotten_orange += 1 + if y+1 < len(grid[0]) and grid[x][y+1] == 1: + grid[x][y+1] += 1 + rotten_orange += 1 + new_stack.append((x,y+1)) + if new_stack: + stack.append(new_stack) + minute += 1 + #print(stack) + #print(rotten_orange, count_oranges) + if rotten_orange != count_oranges: + return -1 + return minute + + + + + diff --git a/ProblemSolving/pairsOfSongsWithTotalDurationDivisibleBy60/pairs.py b/ProblemSolving/pairsOfSongsWithTotalDurationDivisibleBy60/pairs.py new file mode 100644 index 0000000..89cdf58 --- /dev/null +++ b/ProblemSolving/pairsOfSongsWithTotalDurationDivisibleBy60/pairs.py @@ -0,0 +1,47 @@ +class Solution(object): + def numPairsDivisibleBy60(self, time): + """ + :type time: List[int] + :rtype: int + """ + + + # Mathematically + # * First Number --> Take modulus of 60 of the first number: t%60 and record the value visited in a counter + # * Second Number --> Subtract the t%60 from 60 and obtain the remainder (resulting modulus) --> Add the values accordingly + + + # using dict + # https://leetcode.com/problems/pairs-of-songs-with-total-durations-divisible-by-60/discuss/256738/JavaC%2B%2BPython-Two-Sum-with-K-60 + import collections + rec = collections.Counter() + result = 0 + for t in time: + result += rec[(60-(t%60))%60] + rec[t%60] += 1 + return result + + + """ + # using array - 100 pass + # referring to the https://leetcode.com/problems/pairs-of-songs-with-total-durations-divisible-by-60/discuss/257629/Python-5-lines-array-solution + modulus = [0]*61 + for t in time: + print t, (60 - t%60) % 60, t%60 + modulus[-1] += modulus[(60 - t%60) % 60] + modulus[t%60] += 1 + return modulus[-1] + """ + + + """ + # Traditional 2 loop method - bruteforce --> time limit exceeded obviously.... + n = len(time) + result = 0 + for i in range(n): + for j in range(i+1, n): + if (time[i] + time[j]) % 60 == 0: + result += 1 + return result + """ + diff --git a/ProblemSolving/palindromeLinkedList/pal2.py b/ProblemSolving/palindromeLinkedList/pal2.py new file mode 100644 index 0000000..a05e085 --- /dev/null +++ b/ProblemSolving/palindromeLinkedList/pal2.py @@ -0,0 +1,49 @@ +# Definition for singly-linked list. +# class ListNode(object): +# def __init__(self, x): +# self.val = x +# self.next = None + +class Solution(object): + def isPalindrome(self, head): + """ + :type head: ListNode + :rtype: bool + """ + + if not head or not head.next: + return True + + first = head # first half of string + other = head.next # Other half of string + first.next = None + + while first and other: + if other.next and first.val == other.next.val: + other = other.next + break + elif first.val == other.val: + break + + temp = first + first = other + other = other.next + first.next = temp + + if not first or not other: + return False + + print(first.val, other.val) + + while first and other: + if first.val == other.val: + pass + else: + return False + first = first.next + other = other.next + + if first or other: + return False + + return True diff --git a/ProblemSolving/palindromePartitioning/palin.py b/ProblemSolving/palindromePartitioning/palin.py new file mode 100644 index 0000000..d66c987 --- /dev/null +++ b/ProblemSolving/palindromePartitioning/palin.py @@ -0,0 +1,33 @@ +# https://leetcode.com/problems/palindrome-partitioning/description/ +class Solution: + def partition(self, s: str) -> List[List[str]]: + + self.allPalins = [] + + def isPalindrome(test): + if not test: + return False + if len(test) == 1: + return True + left = 0 + right = len(test)-1 + while left < right and test[left] == test[right]: + left += 1 + right -= 1 + if right - left > 0: + return False + return True + + def backtrackPalin(remaining, palins): + + if len(remaining) == 0: + self.allPalins.append(palins) + return + + for r in range(1, len(remaining)+1): + if isPalindrome(remaining[:r]): + backtrackPalin(remaining[r:], palins + [remaining[:r]]) + return + + backtrackPalin(s, []) + return self.allPalins diff --git a/ProblemSolving/palindromePermutation/pal.py b/ProblemSolving/palindromePermutation/pal.py new file mode 100644 index 0000000..531a00a --- /dev/null +++ b/ProblemSolving/palindromePermutation/pal.py @@ -0,0 +1,26 @@ +class Solution(object): + def canPermutePalindrome(self, s): + """ + :type s: str + :rtype: bool + """ + + # Logic 1: Using the COUNTER test + # * Even length string: palindrome exists only when all the char are divisible by 2 + # * Odd length string: palindrome exists only when there is one odd and other even chars + import collections + c = collections.Counter(s) + n = len(s) + even = 0 + odd = 0 + for a in c.keys(): + if c[a]%2 == 0: + even += 1 + else: + odd += 1 + if n%2 == 0 and odd == 0 and even >= 0: + return True + elif n%2 != 0 and odd == 1 and even >= 0: + return True + else: + return False diff --git a/ProblemSolving/pancakeSorting/pan.py b/ProblemSolving/pancakeSorting/pan.py new file mode 100644 index 0000000..75ac379 --- /dev/null +++ b/ProblemSolving/pancakeSorting/pan.py @@ -0,0 +1,30 @@ +class Solution(object): + def pancakeSort(self, A): + """ + :type A: List[int] + :rtype: List[int] + """ + + # Logic 1: Recursive Traverse all the inputs + + def recurse(array, chosen, result, itera): + print(array, chosen) + if array == self.s: + #self.mini = min(self.mini, itera) + if itera < self.mini: + self.mini = itera + self.ans = chosen + result.append(chosen) + return + elif itera > self.mini: + return + else: + for i in range(2, len(array)+1): + recurse(array[:i][::-1]+array[i:], chosen+[i], result, itera+1) + + self.s = sorted(A) + self.mini = len(A)+1 + self.ans = [] + result = [] + recurse(A, [], result, 0) + return self.ans diff --git a/ProblemSolving/partitionArrayIntoThreePartsEqualSum/part.py b/ProblemSolving/partitionArrayIntoThreePartsEqualSum/part.py new file mode 100644 index 0000000..3fd3df8 --- /dev/null +++ b/ProblemSolving/partitionArrayIntoThreePartsEqualSum/part.py @@ -0,0 +1,56 @@ +class Solution(object): + def canThreePartsEqualSum(self, A): + """ + :type A: List[int] + :rtype: bool + """ + + # Logic 2: + # * Assumption is the array order should be maintained!!!! + # * Almost all the logic in discussion follow total_sum + average method... + # * This sounds interesting: https://leetcode.com/problems/partition-array-into-three-parts-with-equal-sum/discuss/262153/C%2B%2B-beat-98-68ms + + + # Total sum + total_sum = sum(A) + + # If the total cannot be divided into 3 exit + if total_sum%3 != 0: + return False + + # Average per section + average = total_sum//3 + + # Easy thing is there should be no change in order of the array - which I could not anticipate from the problem + + # Iterate to find the sum to average + temp_sum = 0 + count = 0 + for i in A: + temp_sum += i + if temp_sum == average: + count += 1 + temp_sum = 0 + if count > 3: + return False + + # Only true if divided into 3 parts + return count == 3 + + # Logic1: Finding cube root to calculate - Wrong + """ + # Total sum + total_sum = sum(A) + + # Is total a perfect cube root? + # power to 1/3 + temp = abs(total_sum) + temp = temp**(1./3.) + + print total_sum, temp + + if temp: + return True + else: + return False + """ diff --git a/ProblemSolving/partitionLabels/partNaive.py b/ProblemSolving/partitionLabels/partNaive.py new file mode 100644 index 0000000..8ca0223 --- /dev/null +++ b/ProblemSolving/partitionLabels/partNaive.py @@ -0,0 +1,18 @@ + # O(N) over the string with the character counts + # * We want at most one occurrence of any character, which means we need the character occuring in only one of the word + + import collections + counts = collections.Counter(S) + visited = [] + result = [] + start = 0 + for i in range(len(S)): + counts[S[i]] -= 1 + if counts[S[i]] == 0: + visited.append(S[i]) + print(set(visited), set(S[start:i+1]), S[start:i+1]) + if visited and set(S[start:i+1]) == set(visited): + result.append(len(S[start:i+1])) + visited = [] + start = i+1 + return result diff --git a/ProblemSolving/pascalTriangle/pascal2.py b/ProblemSolving/pascalTriangle/pascal2.py new file mode 100644 index 0000000..836f2dd --- /dev/null +++ b/ProblemSolving/pascalTriangle/pascal2.py @@ -0,0 +1,26 @@ + +class Solution(object): + def generate(self, numRows): + """ + :type numRows: int + :rtype: List[List[int]] + """ + + if numRows == 0: + return [] + + pascal_triangle = [[1], [1,1]] # Constant values which are common for any pascal triangle + + row = 2 + while row < numRows: + previous = pascal_triangle[-1] + current = [] + for i in range(len(previous)+1): + if i-1 < 0 or i+1 > len(previous): + current.append(1) + else: + current.append(previous[i]+previous[i-1]) + pascal_triangle.append(current) + row += 1 + + return pascal_triangle[:numRows] diff --git a/ProblemSolving/pascalTriangleII/pascal2.py b/ProblemSolving/pascalTriangleII/pascal2.py new file mode 100644 index 0000000..96670cf --- /dev/null +++ b/ProblemSolving/pascalTriangleII/pascal2.py @@ -0,0 +1,19 @@ +class Solution: + def getCurrentRow(self, row: int, triangle) -> List[int]: + # Iterate Row + r = [] + for j in range(row): + # Base case + if j == 0 or j == row-1: + r.append(1) + else: + r.append(triangle[row-1][j-1] + triangle[row-1][j]) + return r + + def getRow(self, rowIndex: int) -> List[int]: + triangle = [] + for i in range(rowIndex+2): + triangle.append(self.getCurrentRow(i, triangle)) + print(triangle) + return triangle[rowIndex+1] + diff --git a/ProblemSolving/pascalTriangleII/pascal3.py b/ProblemSolving/pascalTriangleII/pascal3.py new file mode 100644 index 0000000..95a8e12 --- /dev/null +++ b/ProblemSolving/pascalTriangleII/pascal3.py @@ -0,0 +1,13 @@ +class Solution: + def getRow(self, rowIndex: int) -> List[int]: + + prev_row = [] + cur_row = [1] + for i in range(1, rowIndex+1): + cur_row = [1]*(i+1) + if len(cur_row) > 2: + for i in range(1, len(cur_row)-1): + cur_row[i] = prev_row[i-1] + prev_row[i] + prev_row = cur_row + + return cur_row diff --git a/ProblemSolving/pathCrossing/pathCrossing.py b/ProblemSolving/pathCrossing/pathCrossing.py new file mode 100644 index 0000000..7c08c08 --- /dev/null +++ b/ProblemSolving/pathCrossing/pathCrossing.py @@ -0,0 +1,21 @@ +class Solution: + def isPathCrossing(self, path: str) -> bool: + steps = {"[0, 0]"} + step = [0,0] + for p in path: + if p == "N": + step[1] += 1 + elif p == "S": + step[1] -= 1 + elif p == "E": + step[0] += 1 + else: + step[0] -= 1 + #print(step, steps) + if str(step) in steps: + return True + steps.add(str(step)) + return False + +s = Solution() +print(s.isPathCrossing("NESW")) diff --git a/ProblemSolving/pathInZigZagLabelBST/path.py b/ProblemSolving/pathInZigZagLabelBST/path.py new file mode 100644 index 0000000..cda8f59 --- /dev/null +++ b/ProblemSolving/pathInZigZagLabelBST/path.py @@ -0,0 +1,225 @@ +# Node class to hold each node of the tree +class Node(object): + def __init__(self, val): + self.value = val + self.left = None + self.right = None + # Include a new path for the path from root + self.path = [] + +class Solution(object): + def pathInZigZagTree(self, label): + """ + :type label: int + :rtype: List[int] + """ + + """ + # Logic 1: A normal method of constructing a tree + # Al passed but scale test case time Limit exceeded - Improvise? + + ## Logic + # 1.Finding the path + # * We just need a depth first traversal until node.val == label + + # 2.Constructing a tree + # * with labels until the given input label is exceeded + # * do something like a breath first traversal to figure out the node values + + ## Idea + # 1. Using loop to construct tree and traverse is worse + # 2. Using oath variable in Node and constructing a tree is robust but still leads to time limit exceeded + + self.current_label = 0 + + self.result = [] + + def construct_tree(nodes, current_level): + + # Hold all the children at the current level + children = [] + + # Next level should be even if current level is odd + if current_level%2 != 0: + # We go on reverse order if the next level is even + start = self.current_label+len(nodes)*2+1 + self.current_label = start-1 + for node in nodes: + print(node.value) + start -= 1 + node.left = Node(start) + node.left.path = node.path+[start] + if start == label: + #print node.value, node.left.path + self.result = node.left.path + return + start -= 1 + node.right = Node(start) + node.right.path = node.path+[start] + if start == label: + #print node.value, node.right.path + self.result = node.right.path + return + children.extend([node.left, node.right]) + else: + for node in nodes: + print(node.value) + self.current_label += 1 + node.left = Node(self.current_label) + node.left.path = node.path+[self.current_label] + if self.current_label == label: + #print node.value, node.left.path + self.result = node.left.path + return + self.current_label += 1 + node.right = Node(self.current_label) + node.right.path = node.path+[self.current_label] + if self.current_label == label: + #print node.value, node.right.path + self.result = node.right.path + return + children.extend([node.left, node.right]) + + + if self.current_label < label: + construct_tree(children, current_level+1) + else: + return + + def traverse(node, path): + + if node.value == label: + self.result = path+[node.value] + return + + if node.left: + traverse(node.left, path+[node.value]) + if node.right: + traverse(node.right, path+[node.value]) + + self.current_label += 1 + root = Node(self.current_label) + root.path.append(root.value) + self.result = root.path + construct_tree([root], 1) + #traverse(root, []) + return self.result + """ + + + # Best answer is at https://leetcode.com/problems/path-in-zigzag-labelled-binary-tree/discuss/324011/Python-optimized-O(logn)-time-and-space-with-readable-code-and-step-by-step-explanation + # This uses the BST property that + # * in a normal bst, every parent is the HALF of the children + # - (selected_label)//2 == parent + # * in a zigzag bst or even inverted row bst the property is + # - at that level, + # - (highest label + minimum_label - selected_label)//2 == parent + + self.result = [] + + # First level + level = 1 + num_of_nodes = 1 + + # Property + # * Also, as the level increase by 1 the num of nodes increase by multiples of 2 + + # Find exactly at which level you have the selected label or the answer + while label >= num_of_nodes*2: + level += 1 + num_of_nodes *= 2 + + # Iterate backwards finding the max, min and parent at the current level and apply formula + # * At each level, there are 2 power n nodes, so the maximum at that node is level power 2 minus 1 + while level > 0: + self.result.append(label) + maximum = (2**level)-1 # maximum at the current level + minimum = 2**(level-1) # max of last level is min for current + label = (maximum + minimum - label)//2 # parent + level -= 1 + + return self.result[::-1] + + + + + """ + # Logic 1: A bit confused so rewriting above.... + + # Finding the path + # * We just need a depth first traversal until node.val == label + + # Constructing a tree + # * with labels until the given input label is exceeded + # * do something like a breath first traversal to figure out the node values + + + # Result to hold all the node labels as we traverse + self.result = [] + + # Construct a tree + + self.next_label = 1 + + def construct_tree(nodes, level): + + # Initialize the next level which is children + children = [] + + # Level being even or odd + # Even: we reverse the nodes for reverse order values + + if level%2 != 0: + nodes = nodes[::-1] + for n in nodes: + self.next_label += 1 + n.right = Node(self.next_label) + self.next_label += 1 + n.left = Node(self.next_label) + children.extend([n.left, n.right]) + else: + for n in nodes: + self.next_label += 1 + n.left = Node(self.next_label) + self.next_label += 1 + n.right = Node(self.next_label) + children.extend([n.left, n.right]) + + if self.next_label < label: + construct_tree(children, level+1) + else: + return + + def traverse(node, path): + + #result.append(node.value) + + if node.value == label: + #print path+[node.value] + self.result = path+[node.value] + return + + print(node.value) + if node.left: + print(node.left.value) + if node.right: + print(node.right.value) + #print path + + if node.left: + traverse(node.left, path+[node.value]) + if node.right: + traverse(node.right, path+[node.value]) + + + root = Node(self.next_label) + self.next_label += 1 + root.right = Node(self.next_label) + self.next_label += 1 + root.left = Node(self.next_label) + construct_tree([root.left, root.right], 2) + traverse(root, []) + return self.result + """ + + diff --git a/ProblemSolving/peekingIterator/peek1.py b/ProblemSolving/peekingIterator/peek1.py new file mode 100644 index 0000000..19df493 --- /dev/null +++ b/ProblemSolving/peekingIterator/peek1.py @@ -0,0 +1,79 @@ +# Build custom DS and implement + +class ListNode: + + def __init__(self, val): + self.value = val + self.next = None + + +class PeekingIterator: + + def __init__(self, iterator): + """ + Initialize your data structure here. + :type iterator: Iterator + """ + + self.pointer = None + self.listDS = None + self.start = None + + while iterator.hasNext(): + i = iterator.next() + current = ListNode(i) + if self.listDS == None: + self.listDS = current + self.pointer = current + else: + self.listDS.next = current + self.listDS = self.listDS.next + + def peek(self): + """ + Returns the next element in the iteration without advancing the iterator. + :rtype: int + """ + + if self.start == None: + return self.pointer.value + + if self.pointer.next: + return self.pointer.next.value + else: + return None + + def next(self): + """ + :rtype: int + """ + + if self.start == None: + self.start = True + return self.pointer.value + + if self.pointer.next: + self.pointer = self.pointer.next + return self.pointer.value + else: + return None + + def hasNext(self): + """ + :rtype: bool + """ + + if self.start == None: + return True + + if self.pointer.next: + return True + else: + return False + + +# Your PeekingIterator object will be instantiated and called as such: +# iter = PeekingIterator(Iterator(nums)) +# while iter.hasNext(): +# val = iter.peek() # Get the next element but not advance the iterator. +# iter.next() # Should return the same value as [val]. diff --git a/ProblemSolving/peekingIterator/peek2.py b/ProblemSolving/peekingIterator/peek2.py new file mode 100644 index 0000000..400523b --- /dev/null +++ b/ProblemSolving/peekingIterator/peek2.py @@ -0,0 +1,67 @@ +# Reuse iterator to implement + +# Below is the interface for Iterator, which is already defined for you. +# +# class Iterator: +# def __init__(self, nums): +# """ +# Initializes an iterator object to the beginning of a list. +# :type nums: List[int] +# """ +# +# def hasNext(self): +# """ +# Returns true if the iteration has more elements. +# :rtype: bool +# """ +# +# def next(self): +# """ +# Returns the next element in the iteration. +# :rtype: int +# """ + +class PeekingIterator: + def __init__(self, iterator): + """ + Initialize your data structure here. + :type iterator: Iterator + """ + self.visited = [] + self.iterator = iterator + + + def peek(self): + """ + Returns the next element in the iteration without advancing the iterator. + :rtype: int + """ + if self.visited: + return self.visited[0] + else: + nxt = self.iterator.next() + self.visited.append(nxt) + return self.visited[0] + + def next(self): + """ + :rtype: int + """ + if self.visited: + return self.visited.pop(0) + else: + return self.iterator.next() + + def hasNext(self): + """ + :rtype: bool + """ + if self.visited: + return True + return self.iterator.hasNext() + +# Your PeekingIterator object will be instantiated and called as such: +# iter = PeekingIterator(Iterator(nums)) +# while iter.hasNext(): +# val = iter.peek() # Get the next element but not advance the iterator. +# iter.next() # Should return the same value as [val]. diff --git a/ProblemSolving/permutationInString/permutations.py b/ProblemSolving/permutationInString/permutations.py new file mode 100644 index 0000000..00be0c9 --- /dev/null +++ b/ProblemSolving/permutationInString/permutations.py @@ -0,0 +1,82 @@ +# Pending +class Solution(object): + def checkInclusion(self, s1, s2): + """ + :type s1: str + :type s2: str + :rtype: bool + """ + + # Logic 1: Hacky way of using itertools - Time Limit Exceeded Obviously + """ + import itertools + for substring in itertools.permutations(s1, r=len(s1)): + if "".join(substring) in s2: + return True + return False + """ + + # Logic 2: O(N) Iteration with dictionary copies of substring - Time Limit Exceeded + """ + i = 0 + import collections + c = collections.Counter(list(s1)) + temp = c.copy() + start = None + while i < len(s2): + if s2[i] in temp and temp[s2[i]] > 0: + temp[s2[i]] -= 1 + if start == None: + start = i + else: + temp = c.copy() + if start != None: + i = start + start = None + if len(set(temp.values())) == 1 and list(set(temp.values()))[0] == 0: + return True + i += 1 + return False + """ + + # Logic 3: O(N) iterate, select index plus length and check equality - Time Limit Exceeded + """ + s1 = sorted(s1) + for i in range(len(s2)): + #print(s1, sorted(s2[i:i+len(s1)])) + if i+len(s1)-1 < len(s2) and sorted(s2[i:i+len(s1)]) == s1: + return True + return False + """ + + + import collections + c1 = collections.Counter(s1) + i = 0 + while i < len(s2): + #print(s1, sorted(s2[i:i+len(s1)])) + if s2[i] in c1: + if i+len(s1)-1 < len(s2) and collections.Counter(s2[i:i+len(s1)]) == c1: + return True + else: + i += len(s1) + else: + i += 1 + s2 = s2[::-1] + while i < len(s2): + #print(s1, sorted(s2[i:i+len(s1)])) + if s2[i] in c1: + if i+len(s1)-1 < len(s2) and collections.Counter(s2[i:i+len(s1)]) == c1: + return True + else: + i += len(s1) + else: + i += 1 + return False + + """ + # Logic 3: 2 Pointer Method + left = None + right = None + for i in range(len(s2)): + """ diff --git a/ProblemSolving/permutationSequence/permu.py b/ProblemSolving/permutationSequence/permu.py new file mode 100644 index 0000000..19d93ee --- /dev/null +++ b/ProblemSolving/permutationSequence/permu.py @@ -0,0 +1,22 @@ +class Solution(object): + def getPermutation(self, n, k): + """ + :type n: int + :type k: int + :rtype: str + """ + + # Logic:1 using itertools python (as usual itertools goes through huge iterations) - just 5% faster + import itertools + result = [] + + # Iterate all permutation in range of n list [1,2,...n] for length 3 + for permutation in itertools.permutations(range(1,n+1), r=n): + result.append(permutation) + + # Return kth permutation - convert int to string before join + return "".join([str(i) for i in result[k-1]]) + + + + diff --git a/ProblemSolving/permutationsII/perms.py b/ProblemSolving/permutationsII/perms.py new file mode 100644 index 0000000..6551a4e --- /dev/null +++ b/ProblemSolving/permutationsII/perms.py @@ -0,0 +1,32 @@ +class Solution: + def permuteUnique(self, nums: List[int]) -> List[List[int]]: + + # Logic 1: using itertools + """ + perms = [] + visited = set() + for i in itertools.permutations(nums, r=len(nums)): + if i not in visited: + perms.append(i) + visited.add(i) + return perms + """ + + # Logic 2: backtrack + self.perms = [] + self.visited = set() + + def backtrack(nxts, current, curr_int): + if not nxts: + if curr_int not in self.visited: + self.perms.append(current) + self.visited.add(curr_int) + + for i in range(len(nxts)): + others = nxts[:i] + if i+1 < len(nxts): + others += nxts[i+1:] + backtrack(others, current + [nxts[i]], nxts[i] + 10*curr_int) + + backtrack(nums, [], 0) + return self.perms diff --git a/ProblemSolving/playWithChips/play.py b/ProblemSolving/playWithChips/play.py new file mode 100644 index 0000000..1e67598 --- /dev/null +++ b/ProblemSolving/playWithChips/play.py @@ -0,0 +1,33 @@ +class Solution(object): + def minCostToMoveChips(self, chips): + """ + :type chips: List[int] + :rtype: int + """ + + # Logic 1: Brute Force Logic: Test cost at every index + # * There should be a math involved here - Count all the even and odd spaces on both the sides + # * For a even index --> Ignore all even as the cost is 0, consider only ODD + # * For a odd index --> Ignore all odd as the cost is 0, consider only EVEN + # * at any index until 0 --> num of odd is equal to num of even + i = 0 + n = len(chips) + # At i == 0 + left = 0 + n -= 1 # loose the current index number + if n%2 == 0: + right = n//2 + else: + right = n//2+1 + min_cost = left + right + i += 1 + while i < n: + print(i ,left, right) + # LEFT SIDE OF INDEX + left += 1 + # RIGHT SIDE OF INDEX + right -= 1 + if left + right < min_cost: + min_cost = left + right + i += 1 + return min_cost diff --git a/ProblemSolving/plusOne/plus2.py b/ProblemSolving/plusOne/plus2.py new file mode 100644 index 0000000..36561da --- /dev/null +++ b/ProblemSolving/plusOne/plus2.py @@ -0,0 +1,18 @@ +class Solution(object): + def plusOne(self, digits): + """ + :type digits: List[int] + :rtype: List[int] + """ + + i = len(digits)-1 + carry = 1 + while i >= 0 and carry: + add = digits[i] + carry + digits[i] = add%10 + carry = add//10 + i -= 1 + if carry: + digits = [carry] + digits + return digits + diff --git a/ProblemSolving/populatingNextRightPointersInEachNodeII/populate.py b/ProblemSolving/populatingNextRightPointersInEachNodeII/populate.py new file mode 100644 index 0000000..8bfc5e5 --- /dev/null +++ b/ProblemSolving/populatingNextRightPointersInEachNodeII/populate.py @@ -0,0 +1,80 @@ +""" +# Definition for a Node. +class Node: + def __init__(self, val: int = 0, left: 'Node' = None, right: 'Node' = None, next: 'Node' = None): + self.val = val + self.left = left + self.right = right + self.next = next +""" + +class Solution: + def levelOrderTraverseIterative(self, node): + + # 0. null check + if not node: + return + + # 1. iterative level order traverse + stack = [node] + + # full iteration + while stack: + + # per level setting and iteration + n = len(stack) + nxt_lvl = [] + + # per level iteration + while n: + current = stack.pop(0) + + # next logic + if stack: + current.next = stack[0] + else: + current.next = None + + # iterative traversal + if current.left: + nxt_lvl.append(current.left) + if current.right: + nxt_lvl.append(current.right) + + n -= 1 + + # new level continue + stack = nxt_lvl + + return + + + def levelOrderTraverseRecursive(self, node, level): + + # 0. record node by level + if level not in self.levels: + self.levels[level] = [] + + # 1. check for existing left nodes and add right node + if self.levels[level]: + self.levels[level][-1].next = node + + # 2. update the levels dictionary with current node + self.levels[level].append(node) + + if not node: + return + + # 4. recursive level order traverse + if node.left: + self.levelOrderTraverseRecursive(node.left, level+1) + if node.right: + self.levelOrderTraverseRecursive(node.right, level+1) + + return + + def connect(self, root: 'Node') -> 'Node': + self.levels = {} + #self.levelOrderTraverseIterative(root) + self.levelOrderTraverseRecursive(root, 0) + return root diff --git a/ProblemSolving/powerOf2/powerOf2.py b/ProblemSolving/powerOf2/powerOf2.py index 8c8d1bf..1f92a4f 100644 --- a/ProblemSolving/powerOf2/powerOf2.py +++ b/ProblemSolving/powerOf2/powerOf2.py @@ -31,5 +31,23 @@ def main(): main() - +""" +class Solution(object): + def isPowerOfTwo(self, n): + """ + :type n: int + :rtype: bool + """ + + if n>1 and n%2 != 0: + return False + else: + target = 1 + while target < n: + target *= 2 + if target == n: + return True + else: + return False +""" diff --git a/ProblemSolving/powerOfN/n.py b/ProblemSolving/powerOfN/n.py new file mode 100644 index 0000000..9ee9a1b --- /dev/null +++ b/ProblemSolving/powerOfN/n.py @@ -0,0 +1,43 @@ +# Logic 1: Recurse by reducing one by one --> Leads to recursion depth reached as it reduced by one +""" +class Solution: + def myPow(self, x: float, n: int) -> float: + # Tail recursion + print(x, n) + + # Calculator power recursively ( handle negative power ) + if n < -1: + return self.myPow(x, n+1)*1/x + elif n > 1: + return self.myPow(x, n-1)*x + + # Condition to return when n == 1 + if n < 0: + return 1/x + elif n > 0: + return x + else: + return 1 +""" + +# Logic 2: Use different technique to speed up and reduce number of recursion +class Solution: + def fastPow(self, x: float, n:int) -> float: + # Return 1 when n is 0 + if n == 0: + return 1 + # Recurse + half = self.fastPow(x, n//2) + # Handle even odd nums + if n%2 == 0: + return half*half + else: + return half*half*x + + def myPow(self, x: float, n: int) -> float: + # Handle negative power case + if n < 0: + x = 1/x + n = -n + # Recurse + return self.fastPow(x, n) diff --git a/ProblemSolving/powerfulIntegers/power.py b/ProblemSolving/powerfulIntegers/power.py new file mode 100644 index 0000000..750b2d1 --- /dev/null +++ b/ProblemSolving/powerfulIntegers/power.py @@ -0,0 +1,34 @@ +class Solution(object): + def powerfulIntegers(self, x, y, bound): + """ + :type x: int + :type y: int + :type bound: int + :rtype: List[int] + """ + + # Logic 1: Brute force with 2 for loops O(N**2) + + result = [] + + # Iterate all i and j values + for i in range(0,bound): + for j in range(0, bound): + + # Calculate powerful integer + powerful = x**i + y**j + + # Debug + #print powerful,i, j + + # Result append only when result < bound, else break and increment i + if powerful <= bound: + result.append(powerful) + else: + break + + # When power of i itself causes to exceed bound stop. + if j == 0 and powerful > bound: + break + + return list(set(result)) diff --git a/ProblemSolving/predictTheWinner/predict.py b/ProblemSolving/predictTheWinner/predict.py new file mode 100644 index 0000000..b38f6b8 --- /dev/null +++ b/ProblemSolving/predictTheWinner/predict.py @@ -0,0 +1,113 @@ +# Pending... +class Solution(object): + def PredictTheWinner(self, nums): + """ + :type nums: List[int] + :rtype: bool + """ + + # Maximizing the Total Score + # Known facts: + # * no player can skip turns + # * once a player takes a score no one else can take it + # * taking is only possible from beginning or the end... + # * Consider the next score to play and make a decision + + def gameOn(scores, p1, p2): + + # The decision when all the scores has expired + if not scores: + if p1 > p2: + return True + else: + return False + + """ + # Player 1s choice + # * Even condition of array: try to maximize the score + if len(scores)%2 == 0: + next_chance_0 = + next_chance_final = + + else: + # Odd condition when there is no choice: If there is no possibility of maximum in the next turn choose the current maximum + if scores[0] > scores[-1]: + p1 += scores[0] + scores = scores[1:] + else: + p1 += scores[-1] + scores = scores[:-1] + + print scores + + # Player 2nd choice can go both ways... + if scores: + return (gameOn(scores[:][1:], p1, p2+scores[:][0])) or (gameOn(scores[:][:-1], p1, p2+scores[:][-1])) + else: + return gameOn(scores, p1, p2) + """ + """ + if scores: + # Both taking from the beginning of the array + # Both taking from the end of the array + # One takes beginning and one at the end + print scores + if len(scores)%2 != 0: + return (gameOn(scores[:][2:], p1+scores[:][0], p2+scores[:][1])) or (gameOn(scores[:][:-2]+scores[:][-1], p1, p2+scores[:][-2])) + elif len(scores) == 1: + if len(nums)%2 == 0: + return gameOn([], p1, p2+scores[0]) + else: + return gameOn([], p1+scores[0], p2) + else: + return (gameOn(scores[:][1:-1], p1+scores[:][0], p2+scores[:][-1])) or (gameOn(scores[:][1:-1], p1+scores[:][-1], p2+scores[:][0])) + else: + return gameOn(scores, p1, p2) + + # Start with initial scores + return gameOn(nums, 0, 0) + """ + + """ + # Greedy for the max score in each step (0 or -1) will not work as the player work to maximize their total score. We need to consider the total score, a player might take lower score in current turn to anticipate to snatch a better score next turn -- implement this.... + + # Logic: Player 1 is Greedy always! + # * Lets assume player 1 always greedy and goes for the maximum element either at the start or the end + # * For player 2, lets assume he is also greedy always + + # Conditions Faced: + # * when there are even number of scores, having player 1 and player 2 play back to back with recursive works + # * when there is odd number of scores, it doesnt. think of something! + + def gameOn(scores, p1, p2): + + # The decision when all the scores has expired + if not scores: + if p1 > p2: + return True + else: + return False + + # Player 1s choice + if scores[0] > scores[-1]: + p1 += scores[0] + scores = scores[1:] + else: + p1 += scores[-1] + scores = scores[:-1] + + print scores + + # Player 2nd choice + if scores: + if scores[0] > scores[-1]: + return gameOn(scores[:][1:], p1, p2+scores[:][0]) + else: + return gameOn(scores[:][:-1], p1, p2+scores[:][-1]) + else: + return gameOn(scores, p1, p2) + + # Start with initial scores + return gameOn(nums, 0, 0) + """ + diff --git a/ProblemSolving/primeArrangements/prime.py b/ProblemSolving/primeArrangements/prime.py new file mode 100644 index 0000000..5505a39 --- /dev/null +++ b/ProblemSolving/primeArrangements/prime.py @@ -0,0 +1,142 @@ +class Solution(object): + def numPrimeArrangements(self, n): + """ + :type n: int + :rtype: int + """ + + """ + + Logic 1: BruteForce technique - use all the permutation of arrangement and solve + + # Memoize + primes = {1:False, 2:True} + + # Is a prime number? + def is_prime(number): + if number in primes: + return primes[number] + else: + count = 0 + import math + for i in range(2, int(math.sqrt(number))+1):#number//2+1): + if number%i == 0: + count += 1 + if count >= 1: + primes[number] = False + return False + primes[number] = True + return True + + # Find if all Prime indices are with Prime Numbers? + def are_prime_in_prime_index(array): + + # Logic: Iterating all of the array - worst case --> time limit exceeded + for i, item in enumerate(array): + index = i+1 + prime_index = False + prime_value = False + # memoize for prime + prime_index = is_prime(index) + prime_value = is_prime(item) + if not prime_index and not prime_value: + pass + elif prime_index and prime_value: + pass + else: + return False + return True + + def are_prime_in_prime_index2(array): + + # Modified version of above logic + # Logic 2: Taking into account some prime intelligence on array arrangement ( visit only prime index) --> time limit exceeded + + # Only even prime is 2 + #print(array) + prime_index = is_prime(2) + prime_value = is_prime(array[1]) + if prime_index and prime_value: + pass + else: + return False + # Array indexed one so every even index is odd index actually ( jump on even indexes from 2 which will be 3, 5, 7 ) + for i in range(2, len(array), 2): + index = i+1 + item = array[i] + #print(index, item) + prime_index = False + prime_value = False + # memoize for prime + prime_index = is_prime(index) + prime_value = is_prime(item) + if not prime_index and not prime_value: + pass + elif prime_index and prime_value: + pass + else: + return False + return True + + integers = range(1, n+1) + + # Main program using the above functions - both fail with time limit exceeded + # Get permutations + import itertools + count = 0 + for perms in itertools.permutations(integers): + if are_prime_in_prime_index(perms): + count += 1 + return count%((10**9)+7) + + + # Logic 2 --> Completely different logic + # * Visualize the properities and then solve + # * Calculate the number of primes in N numbers and non primes + # * for n=5, assume the indices and numbers are 1, 2, 3, 4, 5 + # * In this case, permutation would be 2 x 3 x 2 x 1 x 1 ( Reduce the primes=3 and non-primes=2, as you go over the positions + # Which summarizes into factorial(3) * factorial(2) + + # Logic 3: 83% faster and 100% space + + # Memoize primes and factorials to support recursion + primes = {1:False, 2:True} + factorials = {0:1, 1:1} + + # Is a prime number? + def is_prime(number): + if number in primes: + return primes[number] + else: + count = 0 + import math + for i in range(2, int(math.sqrt(number))+1):#number//2+1): + if number%i == 0: + count += 1 + if count >= 1: + primes[number] = False + return False + primes[number] = True + return True + + # Factorial? + def fact(number): + if number not in factorials: + factorials[number] = number * fact(number-1) + return factorials[number] + + # Logic 3 + # * Count the number of primes in the range + # * Know the indexes that are prime + # * One iteration is enough for this case as the indexes and numbers are consecutive + # * Use permutation problem --> 2 x 3 x 2 x 1 x 1 + + primes_within_range = [] + for i in range(2, n+1): + if is_prime(i): + primes_within_range.append(i) + prime = len(primes_within_range) + non_prime = 1+len(range(1,n))-prime + print(prime, non_prime, fact(prime), fact(non_prime), primes_within_range) + return (fact(prime)*fact(non_prime))%(10**9+7) + diff --git a/ProblemSolving/primePalindrome/prime.py b/ProblemSolving/primePalindrome/prime.py new file mode 100644 index 0000000..9fcb5ff --- /dev/null +++ b/ProblemSolving/primePalindrome/prime.py @@ -0,0 +1,38 @@ +# LT Hard --> Pending... +# Time limit exceeded... +class Solution(object): + def primePalindrome(self, N): + """ + :type N: int + :rtype: int + """ + + def isPrime(num): + import math + count = 0 + if num == 1: + return False + for i in range(3, int(math.ceil(math.sqrt(num)+1)), 2): + if num%i == 0: + count += 1 + if count > 0: + return False + return True + + def isPalindrome(num): + if str(num) == str(num)[::-1]: + return True + else: + return False + + while 1: + if (N > 2 and N%2 != 0) or N <= 2: + if isPalindrome(N): + if isPrime(N): + return N + if N < 2 or N%2 == 0: + N += 1 + else: + N += 2 + + diff --git a/ProblemSolving/printFooBarAlternatively/print.py b/ProblemSolving/printFooBarAlternatively/print.py new file mode 100644 index 0000000..8accd61 --- /dev/null +++ b/ProblemSolving/printFooBarAlternatively/print.py @@ -0,0 +1,63 @@ +# Logic 2: Threading Events - 100 pass 71% faster + +from threading import Event + +class FooBar(object): + def __init__(self, n): + self.n = n + self.trigger_bar = Event() + self.trigger_foo = Event() + self.trigger_foo.set() + + + def foo(self, printFoo): + for i in xrange(self.n): + self.trigger_foo.wait() + self.trigger_foo.clear() + printFoo() + self.trigger_bar.set() + + + def bar(self, printBar): + for i in xrange(self.n): + self.trigger_bar.wait() + self.trigger_bar.clear() + printBar() + self.trigger_foo.set() + + +# Logic 1: While loop with state variable ( both using one and two state variables ) +# * This logic works with proper output but does not pass when submit ( not sure why? ) +""" +class FooBar(object): + def __init__(self, n): + self.n = n + #self.trigger_bar = False + #self.trigger_foo = True + self.trigger = True + + + def foo(self, printFoo): + for i in xrange(self.n): + #while not self.trigger_foo: + # pass + while not self.trigger: + pass + printFoo() + self.trigger = False + #self.trigger_foo = False + #self.trigger_bar = True + + + def bar(self, printBar): + for i in xrange(self.n): + #while not self.trigger_bar: + # pass + while self.trigger: + pass + printBar() + self.trigger = True + #self.trigger_bar = False + #self.trigger_foo = True +""" + diff --git a/ProblemSolving/printImmutableLinkedListInReverse/print.py b/ProblemSolving/printImmutableLinkedListInReverse/print.py new file mode 100644 index 0000000..999d07d --- /dev/null +++ b/ProblemSolving/printImmutableLinkedListInReverse/print.py @@ -0,0 +1,62 @@ +# """ +# This is the ImmutableListNode's API interface. +# You should not implement it, or speculate about its implementation. +# """ +# class ImmutableListNode(object): +# def printValue(self): # print the value of this node. +# . """ +# :rtype None +# """ +# +# def getNext(self): # return the next node. +# . """ +# :rtype ImmutableListNode +# """ + +class Solution(object): + def printLinkedListInReverse(self, head): + """ + :type head: ImmutableListNode + :rtype: None + """ + + # Logic 1: Naive iteration logic --> Solving with Space ( Improve to const space complexity ) - 100 pass 52% faster but we are using O(N) SPACE Complexity + # * usually we can make -> to <- for reversing a list but we want to do this in immutable fashion + """ + visited = [] + next_node = head + while next_node: + visited.append(next_node) + next_node = next_node.getNext() + while visited: + visited.pop().printValue() + """ + + # Logic 2: Follow up to use constant space and linear time complexity - 25% faster - 100 pass + # RECURSIVE/Divide&Conquer APPROACH + # ref: https://leetcode.com/problems/print-immutable-linked-list-in-reverse/discuss/445408/Python-4-solutions-space-complexity-O(n)-O(n(1t))-O(lgn)-O(1) + def length_of_list(node): + length = 0 + while node: + length += 1 + node = node.getNext() + return length + + def print_in_reverse(node, n): + if n > 1: + mid = node + for i in range(n//2): + mid = mid.getNext() + print_in_reverse(mid, n-n//2) + print_in_reverse(node, n//2) + elif n > 0: # Remaining node that is the last in subset + node.printValue() + + n = length_of_list(head) + print_in_reverse(head, n) + + + # Thoughts + # * slow/fast pointer logic + # * n*O(N) iterations? + # * o(n//2) space? diff --git a/ProblemSolving/printInOrder/print.py b/ProblemSolving/printInOrder/print.py new file mode 100644 index 0000000..2ed7627 --- /dev/null +++ b/ProblemSolving/printInOrder/print.py @@ -0,0 +1,78 @@ +# Logic 1: 100 pass 5% faster +# * Create state variables to maintain the order of execution +# * As the execution can be on any order, we make a blocking call by using while loops for the state variables +# * Only after the blocking call breaks the execution will happen thereby maintaining the order +""" +class Foo(object): + def __init__(self): + self.first_done = False + self.second_done = False + pass + + + def first(self, printFirst): + + # printFirst() outputs "first". Do not change or remove this line. + printFirst() + self.first_done = True + + + def second(self, printSecond): + + while not self.first_done: + pass + # printSecond() outputs "second". Do not change or remove this line. + printSecond() + self.second_done = True + + + def third(self, printThird): + + while not self.second_done: + pass + # printThird() outputs "third". Do not change or remove this line. + printThird() +""" + +# Logic 2: Using Locks --> Events for trigerring ==> 70% faster +# * Create events based on the order of execution and use them + +from threading import Event + +class Foo(object): + def __init__(self): + self.first_done = Event() + self.second_done = Event() + + + def first(self, printFirst): + """ + :type printFirst: method + :rtype: void + """ + + printFirst() + self.first_done.set() + + + def second(self, printSecond): + """ + :type printSecond: method + :rtype: void + """ + self.first_done.wait() + printSecond() + self.second_done.set() + self.first_done.clear() + + + def third(self, printThird): + """ + :type printThird: method + :rtype: void + """ + self.second_done.wait() + printThird() + self.second_done.clear() + + diff --git a/ProblemSolving/prisonAfterNDays/prison.py b/ProblemSolving/prisonAfterNDays/prison.py new file mode 100644 index 0000000..4805e1c --- /dev/null +++ b/ProblemSolving/prisonAfterNDays/prison.py @@ -0,0 +1,38 @@ +class Solution(object): + def prisonAfterNDays(self, cells, N): + """ + :type cells: List[int] + :type N: int + :rtype: List[int] + """ + + # Naive Method of iteration - with pattern identification + # Lesson Learned: + # * Identify any pattern to reduce iterations + + # Identify pattern --> every 14th iteration has same values --> So mod 14 and then bruteforce + if N > 14: + N = N%14 + if N == 0: + N = 14 + + # Brute force for the answer - Only brute force from the beginning will fail the challenge with 1000000000 input --> will lead to time limit exceeded + day = 0 + new = cells[:] + while day < N: + print(day, new) + for i in range(1, len(cells)-1): + if cells[i-1] == cells[i+1]: + new[i] = 1 + else: + new[i] = 0 + new[0] = 0 + new[len(cells)-1] = 0 + cells = new[:] + day += 1 + return cells + + + + + diff --git a/ProblemSolving/prisonAfterNDays/solve.py b/ProblemSolving/prisonAfterNDays/solve.py new file mode 100644 index 0000000..64ee09d --- /dev/null +++ b/ProblemSolving/prisonAfterNDays/solve.py @@ -0,0 +1,51 @@ +class Solution: + def prisonAfterNDays(self, cells: List[int], N: int) -> List[int]: + # Logic 1: Naive Iterate N times for N days - All pass except scale case - TIME LIMIT EXCEEDED + """ + n = len(cells) + while N: + #print(cells) + nxt_day = cells[:] + for i in range(1, n-1): + left = cells[i+1] + right = cells[i-1] + if left == right: + nxt_day[i] = 1 + else: + nxt_day[i] = 0 + nxt_day[0] = 0 + nxt_day[n-1] = 0 + cells = nxt_day + N -= 1 + return cells + """ + + # Logic 2: + # * There are only a finite number of combinations or arrangement possible, after that it would rotate to follow the same pattern. We just find out how much combination is possible and divide that by N to just return what would be after the N days. + # * we iterate until we find the loop and with math we can return the expected + n = len(cells) + visited = [] + nxt_day = None + while not visited or visited[0] != nxt_day: + if nxt_day: + visited.append(nxt_day) + nxt_day = cells[:] + for i in range(1, n-1): + left = cells[i+1] + right = cells[i-1] + if left == right: + nxt_day[i] = 1 + else: + nxt_day[i] = 0 + nxt_day[0] = 0 + nxt_day[n-1] = 0 + print(visited, nxt_day) + if visited and nxt_day == visited[0]: + break + cells = nxt_day + N -= 1 + print(len(visited)) + N = N%len(visited) + print(N, visited[N-1]) + return visited[N-1] + diff --git a/ProblemSolving/productExceptSelf/prod2.py b/ProblemSolving/productExceptSelf/prod2.py new file mode 100644 index 0000000..211b15b --- /dev/null +++ b/ProblemSolving/productExceptSelf/prod2.py @@ -0,0 +1,16 @@ +class Solution(object): + def productExceptSelf(self, nums): + """ + :type nums: List[int] + :rtype: List[int] + """ + def product(nums): + product = 1 + for element in nums: + product *= element + return product + + new = [1]*len(nums) + for i in range(len(nums)): + new[i] = product(nums[:i]+nums[i+1:]) + return new diff --git a/ProblemSolving/pushDominoes/push.py b/ProblemSolving/pushDominoes/push.py new file mode 100644 index 0000000..8940a53 --- /dev/null +++ b/ProblemSolving/pushDominoes/push.py @@ -0,0 +1,87 @@ +class Solution: + def pushDominoes(self, dominoes: str) -> str: + + # Logic 2: finding boundaries + + start = end = None + prev_end = None + for i in range(len(dominoes)): + + # Mark start and end of pushes + if dominoes[i] == "R": + if start != None and end == None: # already visited a start + #print(start, i, i-start+1) + dominoes = dominoes[:start] + "R"*(i-start+1) + dominoes[i+1:] + #print(dominoes) + start = i + elif dominoes[i] == "L": + end = i + + # Update once you find boundaries + if start != None and end != None: + #print(start, end) + equal_force = (end-start+1)//2 + no_force = (end-start+1)%2 + total_sub = "R"*equal_force + if no_force: + total_sub += "." + total_sub += "L"*equal_force + #print(start, end, total_sub, equal_force, no_force) + dominoes = dominoes[:start] + total_sub + dominoes[end+1:] + prev_end = end + start = end = None + elif end != None and start == None: + if prev_end == None: + prev_end = 0 + #print("h", prev_end, end) + dominoes = dominoes[:prev_end] + (end-prev_end)*"L" + dominoes[end:] + #print(dominoes) + prev_end = end + end = None + elif i == len(dominoes)-1 and start != None and end == None: + dominoes = dominoes[:start] + "R"*(len(dominoes)-start) + start = None + + + return dominoes + + + # Things tried... + + # Logic 1: 2*O(N) == O(N) + # * one for right + # * other for left + + """ + ds = list(dominoes) # string cannot be mutated, convert to list + push = False + + # execute right + for i in range(len(ds)): + if ds[i] == "R": + push = True + elif ds[i] == "L": + push = False + else: # for dot + if (i+1 < len(ds) and ds[i+1] == "."): + if push: # is already pushed + ds[i] = "R" + + print(ds) + + # execute left + push = False + for i in range(len(ds)-1, -1, -1): + if ds[i] == "L": + push = True + elif ds[i] == "R": + push = False + else: # for dot + if (i-1 >= 0 and ds[i-1] == "."): # is already pushed + ds[i] = "L" + i -= 1 + + return "".join(ds) + """ + + # Logic 2: 2 pointer diff --git a/ProblemSolving/pushDominoes/push2.py b/ProblemSolving/pushDominoes/push2.py new file mode 100644 index 0000000..e3c77c0 --- /dev/null +++ b/ProblemSolving/pushDominoes/push2.py @@ -0,0 +1,60 @@ +class Solution: + def pushDominoes(self, dominoes: str) -> str: + + + # 2*O(N) iteration to consider L and R separately with calculating force + dominoes = list(dominoes) + forces = [0]*len(dominoes) + + rightPush = False + curr_f = 0 + for i in range(len(dominoes)): + + if rightPush: + curr_f += 1 + + if dominoes[i] == "R": + rightPush = True + curr_f = 0 + continue + + if rightPush and dominoes[i] == ".": + dominoes[i] = "R" + else: + rightPush = False + curr_f = 0 + + forces[i] = curr_f + + print(dominoes, forces) + + leftPush = False + curr_f = 0 + for i in range(len(dominoes)-1,-1,-1): + + if leftPush: + curr_f += 1 + + if dominoes[i] == "L": + leftPush = True + curr_f = 0 + continue + + if leftPush: + if forces[i] == curr_f and dominoes[i] == "R": + leftPush = False + dominoes[i] = "." + elif forces[i] < curr_f and dominoes[i] == "R": + leftPush = False + elif forces[i] > curr_f and dominoes[i] == "R": + dominoes[i] = "L" + forces[i] = curr_f + elif dominoes[i] == "." and leftPush: + dominoes[i] = "L" + forces[i] = curr_f + + print(dominoes, forces) + + return "".join(dominoes) + + diff --git a/ProblemSolving/queensThatCanAttackTheKing/queens.py b/ProblemSolving/queensThatCanAttackTheKing/queens.py new file mode 100644 index 0000000..091da77 --- /dev/null +++ b/ProblemSolving/queensThatCanAttackTheKing/queens.py @@ -0,0 +1,102 @@ +class Solution(object): + def queensAttacktheKing(self, queens, king): + """ + :type queens: List[List[int]] + :type king: List[int] + :rtype: List[List[int]] + """ + + # Logic 1: 6% Faster - 100 pass + # * Naive iteration on a chess board of 8x8 - vertical, horizontal, diagnal + xk = king[0] + yk = king[1] + attack = [] + + for queen in queens: + xq = queen[0] + yq = queen[1] + attacks = False + # Vertical Attack + y = yq + while not attacks and y < 8: + if [xq, y] != [xq, yq]: + if [xq,y] in queens: + break + elif [xq, y] == king: + attacks = True + attack.append(queen) + y += 1 + y = yq + while not attacks and y >= 0: + if [xq, y] != [xq, yq]: + if [xq,y] in queens: + break + elif [xq, y] == king: + attacks = True + attack.append(queen) + y -= 1 + # Horizontal Attack + x = xq + while not attacks and x < 8: + if [x, yq] != [xq, yq]: + if [x,yq] in queens: + break + elif [x, yq] == king: + attacks = True + attack.append(queen) + x += 1 + x = xq + while not attacks and x >= 0: + if [x, yq] != [xq, yq]: + if [x,yq] in queens: + break + elif [x, yq] == king: + attacks = True + attack.append(queen) + x -= 1 + # Diagnal Attack + x = xq + y = yq + while not attacks and x < 8 and y < 8: + if [x, y] != [xq, yq]: + if [x,y] in queens: + break + elif [x, y] == king: + attacks = True + attack.append(queen) + x += 1 + y += 1 + x = xq + y = yq + while not attacks and x >= 0 and y >= 0: + if [x, y] != [xq, yq]: + if [x,y] in queens: + break + elif [x, y] == king: + attacks = True + attack.append(queen) + x -= 1 + y -= 1 + x = xq + y = yq + while not attacks and x >= 0 and y < 8: + if [x, y] != [xq, yq]: + if [x,y] in queens: + break + elif [x, y] == king: + attacks = True + attack.append(queen) + x -= 1 + y += 1 + x = xq + y = yq + while not attacks and x < 8 and y >= 0: + if [x, y] != [xq, yq]: + if [x,y] in queens: + break + elif [x, y] == king: + attacks = True + attack.append(queen) + x += 1 + y -= 1 + return attack diff --git a/ProblemSolving/randomPickWithWeight/random.py b/ProblemSolving/randomPickWithWeight/random.py new file mode 100644 index 0000000..b2b8300 --- /dev/null +++ b/ProblemSolving/randomPickWithWeight/random.py @@ -0,0 +1,36 @@ +# Logic 1: create dictionaries ( be space lenient ) and calculate the probability as you pick values and asses what to send next - 22% faster +class Solution: + + def __init__(self, w: List[int]): + self.weights = {} # to access the weights + self.log = {} # to know what we have picked before + self.total_sent = 0 + self.max_weight = 0 + self.high_candidate = 0 + self.n = sum(w) + self.len = len(w) + self.w = w + for i in range(len(w)): + self.weights[i] = w[i]/self.n + if self.weights[i] > self.max_weight: + self.max_weight = self.weights[i] + self.high_candidate = i + self.log[i] = 0 + + def pickIndex(self) -> int: + #print(self.total_sent, self.len//2, self.weights) + if self.total_sent <= self.len//2: + self.total_sent += 1 + return self.high_candidate + for k, v in self.log.items(): + #print(k, v, k/self.total_sent, self.weights[k]) + if v/self.total_sent <= self.weights[k]: + self.total_sent += 1 + self.log[k] += 1 + return k + return -1 + + +# Your Solution object will be instantiated and called as such: +# obj = Solution(w) +# param_1 = obj.pickIndex() diff --git a/ProblemSolving/rangeAdditionII/range.py b/ProblemSolving/rangeAdditionII/range.py new file mode 100644 index 0000000..17beb52 --- /dev/null +++ b/ProblemSolving/rangeAdditionII/range.py @@ -0,0 +1,60 @@ +class Solution(object): + def maxCount(self, m, n, ops): + """ + :type m: int + :type n: int + :type ops: List[List[int]] + :rtype: int + """ + + # Logic 2: 98% faster logic and 100% space + + # * Obviously we dont need to go through every element again and again + # * We need to find the intersection of the range ( max intersection ), or the elements that will be included in most of the ranges + # * Question claims all the opertion ranges starts with 0 -> a or 0->b + # --> To find the maximum: + # * That means the common index for all ranges would for sure be 0,0 which will be the maximum element incurring changes on each operation + # * The value of 0,0 will be the number of operation or length of operation + + # Scribble To find the maximum: + """ + # If no operation is performed all elements are max which is 0 + if not ops: + return m*n + # If operation is performed, (0,0) will incur changes on all operation and be the max value + return len(ops) + """ + + # We need to find how much element has this max --> Find all the intersections and leave the rest + # * If no operation is performed all elements are max which is 0 + # * The most minimum range is the one that went through all other ranges that were greater than itself so that is the answer + # * Using sorted only looks at x in x,y + + if not ops: + return m*n + row = m + column = n + for op in ops: + row = min(row, op[0]) + column = min(column, op[1]) + return row*column + + # Logic 1: Very Naive Method with for loops - Literally following counter logic without any shortcuts or property usage + """ + count = m*n + if not ops: + return count + matrix = [[0 for i in range(n)] for j in range(m)] + maxi = -float('inf') + for op in ops: + for i in range(op[0]): + for j in range(op[1]): + matrix[i][j] += 1 + if matrix[i][j] > maxi: + maxi = matrix[i][j] + count = 1 + elif matrix[i][j] == maxi: + count += 1 + return count + """ + diff --git a/ProblemSolving/rangeSumOf1dArray/range.py b/ProblemSolving/rangeSumOf1dArray/range.py new file mode 100644 index 0000000..1d1cad6 --- /dev/null +++ b/ProblemSolving/rangeSumOf1dArray/range.py @@ -0,0 +1,7 @@ +class Solution: + def runningSum(self, nums: List[int]) -> List[int]: + output = [0 for i in range(len(nums))] + for n in range(len(nums)): + num = nums[n] + output[n] = output[n-1]+num + return output diff --git a/ProblemSolving/rangeSumOfBst/range.py b/ProblemSolving/rangeSumOfBst/range.py new file mode 100644 index 0000000..98ec664 --- /dev/null +++ b/ProblemSolving/rangeSumOfBst/range.py @@ -0,0 +1,55 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def rangeSumBST(self, root, L, R): + """ + :type root: TreeNode + :type L: int + :type R: int + :rtype: int + """ + + # Null check + if not root: + return 0 + + # global sum + self.sum = 0 + + # Brute force - traverse all nodes to look at their value + def traverse(node): + + if node.val >= L and node.val <= R: + self.sum += node.val + + if node.left: + traverse(node.left) + + if node.right: + traverse(node.right) + + # Function utilizing BST property - a little faster (avoiding unwanted traversals) + def traverse2(node): + + print node.val + + if node.val >= L and node.val <= R: + self.sum += node.val + + # Traverse left only when node value is greater than Left + if node.val > L and node.left: + traverse(node.left) + + if node.val < R and node.right: + traverse(node.right) + + + traverse2(root) + + return self.sum + diff --git a/ProblemSolving/rangeSumQueryImmutable2D/range.py b/ProblemSolving/rangeSumQueryImmutable2D/range.py new file mode 100644 index 0000000..e59d16d --- /dev/null +++ b/ProblemSolving/rangeSumQueryImmutable2D/range.py @@ -0,0 +1,16 @@ +class NumMatrix: + + def __init__(self, matrix: List[List[int]]): + self.matrix = matrix + + def sumRegion(self, row1: int, col1: int, row2: int, col2: int) -> int: + sumi = 0 + for r in range(row1, row2+1): + for c in range(col1, col2+1): + sumi += self.matrix[r][c] + return sumi + + +# Your NumMatrix object will be instantiated and called as such: +# obj = NumMatrix(matrix) +# param_1 = obj.sumRegion(row1,col1,row2,col2) diff --git a/ProblemSolving/rankTransformOfAnArray/rank.py b/ProblemSolving/rankTransformOfAnArray/rank.py new file mode 100644 index 0000000..0565621 --- /dev/null +++ b/ProblemSolving/rankTransformOfAnArray/rank.py @@ -0,0 +1,30 @@ +class Solution: + def arrayRankTransform(self, arr: List[int]) -> List[int]: + + + # Logic 1: O(N) using dictionary to store sorted indexes - 100 pass - 70% faster + + # Sort to get ranks + ranks = sorted(arr) + + # Create dict and add indexes, handle duplicates! + indexes = {} + prev = 0 + for i in range(len(ranks)): + if ranks[i] not in indexes: + prev += 1 + indexes[ranks[i]] = prev + else: + pass + + # Final iteration to replace with ranks + for i in range(len(arr)): + arr[i] = indexes[arr[i]] + return arr + + + # Logic 2: Hacky Way - Works for few cases but eventually time limit exceeded for scale cases + """ + ranks = set(arr) + return map(lambda x: ranks.index(x)+1, arr) + """ diff --git a/ProblemSolving/reOrderDataInLogFiles/reorder.py b/ProblemSolving/reOrderDataInLogFiles/reorder.py new file mode 100644 index 0000000..1bf708d --- /dev/null +++ b/ProblemSolving/reOrderDataInLogFiles/reorder.py @@ -0,0 +1,32 @@ +class Solution(object): + def reorderLogFiles(self, logs): + """ + :type logs: List[str] + :rtype: List[str] + """ + + # Logic 1: Using dictionary datastructure to handle data and output + l = {} + digit = [] + + for log in logs: + lsplit = log.split(" ") + # Strip identifer for key + ident = lsplit[0] + # Content of log + content = " ".join(lsplit[1:]) + # Create DB entry + if content not in l: + l[content] = set() + # Find out if it is digit log/ letter log + if "".join(lsplit[1:]).isdigit(): + digit.append(log) + else: + l[content].add(ident) + + result = [] + for cont in sorted(l.keys()): + for c in l[cont]: + result.append(c + " " + cont) + result += digit + return result diff --git a/ProblemSolving/reOrderDataInLogFiles/reorder2.py b/ProblemSolving/reOrderDataInLogFiles/reorder2.py new file mode 100644 index 0000000..40dff27 --- /dev/null +++ b/ProblemSolving/reOrderDataInLogFiles/reorder2.py @@ -0,0 +1,39 @@ +class Solution: + def reorderLogFiles(self, logs: List[str]) -> List[str]: + + digit_logs = [] + letter_logs = [] + + while logs: + curr = logs.pop(0) + content = curr.split(" ") + + if content[1].isdigit(): + digit_logs.append(curr) + continue + else: + itera = len(letter_logs)-1 + iid = content[0] + content = " ".join(content[1:]) + + if itera == -1: + letter_logs.append(curr) + continue + + while itera >= 0: + target = letter_logs[itera].split(" ") + if content == " ".join(target[1:]): + if iid > target[0]: + break + elif content > " ".join(target[1:]): + break + itera -= 1 + + print(itera, len(letter_logs)-1) + if itera == len(letter_logs)-1: + letter_logs.append(curr) + else: + itera += 1 + letter_logs = letter_logs[:itera] + [curr] + letter_logs[itera:] + + return letter_logs + digit_logs diff --git a/ProblemSolving/reachNumber/reach.py b/ProblemSolving/reachNumber/reach.py new file mode 100644 index 0000000..7bb7c99 --- /dev/null +++ b/ProblemSolving/reachNumber/reach.py @@ -0,0 +1,78 @@ +class Solution(object): + def reachNumber(self, target): + """ + :type target: int + :rtype: int + """ + + """ + # Logic 1: Own greedy approach (pending... not complete) + # This does not give minimum number of steps... + + # target == 0 condition + if target == 0: + return 0 + + # Initial starting point set to 0 + start = 0 + + # This can go 2 ways + # * At every step or number, we could go -n or +n and further like that (it tapers down as a tree and the best path (min) should be selected.) + # --> Greedy or Dynamic Prog? + # Let's do greedy + # * Every time we move towards the targets which would be the closest to the target + # * We avoid the steps which would make use greater than target + step = 0 + target = abs(target) + while start != target: + step += 1 + if start+step > target: + start -= step + else: + start += step + print start, step + return step + """ + + + # 100 pass - 100 ms runtime 19.02 faster + # Mathematical solution + # Based on https://leetcode.com/problems/reach-a-number/discuss/112968/Short-JAVA-Solution-with-Explanation + + # Always move towards the target (Right) + # * If the sum exceeds target + # - Exceed until the difference is even (this makes sure there can be some left motions to succeed) + + step = 0 + start = 0 + + # Number line is identical on both sides. Lets consider one side always and calculate the result + + target = abs(target) + + # Move right side until target is equaled or just exceeded + while start < target: + step += 1 + start += step + + while (start - target) % 2 != 0: + step += 1 + start += step + + return step + + + + + + + + + + + + + + + + diff --git a/ProblemSolving/readNCharactersGivenRead4/read.py b/ProblemSolving/readNCharactersGivenRead4/read.py new file mode 100644 index 0000000..85ea162 --- /dev/null +++ b/ProblemSolving/readNCharactersGivenRead4/read.py @@ -0,0 +1,41 @@ +""" +The read4 API is already defined for you. + + @param buf4, a list of characters + @return an integer + def read4(buf4): + +# Below is an example of how the read4 API can be called. +file = File("abcdefghijk") # File is "abcdefghijk", initially file pointer (fp) points to 'a' +buf4 = [' '] * 4 # Create buffer with enough space to store characters +read4(buf4) # read4 returns 4. Now buf = ['a','b','c','d'], fp points to 'e' +read4(buf4) # read4 returns 4. Now buf = ['e','f','g','h'], fp points to 'i' +read4(buf4) # read4 returns 3. Now buf = ['i','j','k',...], fp points to end of file +""" + +class Solution: + def read(self, buf, n): + pointer = 0 + start = end = 0 + while n: + start = pointer + current_buf = [0]*4 + current_read = read4(current_buf) + if current_read == 0: + break + next_end = end + current_read + print(start,end,n) + j = 0 + for i in range(start,next_end): + buf[i] = current_buf[j] + j += 1 + n -= 1 + end += 1 + if n == 0: + return end + end = next_end + pointer = next_end + print(n,start,end,buf) + return end + + diff --git a/ProblemSolving/rearrangeSpacesBetweenWords/rearrange.py b/ProblemSolving/rearrangeSpacesBetweenWords/rearrange.py new file mode 100644 index 0000000..d6b6023 --- /dev/null +++ b/ProblemSolving/rearrangeSpacesBetweenWords/rearrange.py @@ -0,0 +1,26 @@ +# Logic 1: Iterate to find words, space + compute to answer: 100 pass 86.30% faster +class Solution: + def reorderSpaces(self, text: str) -> str: + # Count spaces and Obtain all words + words = [] + spaces = 0 + current_word = "" + for i in range(len(text)): + if text[i] == " ": + spaces += 1 + if current_word: + words.append(current_word) + current_word = "" + else: + current_word += text[i] + if current_word: + words.append(current_word) + if spaces == 0: + return text + if len(words) <= 1: + return words[0] + " "*spaces + equal_spaces = spaces//(len(words)-1) + remaining = spaces%(len(words)-1) + #remaining = spaces - equal_spaces*len(words) + #print(spaces, len(words), equal_spaces, remaining) + return (" "*equal_spaces).join(words) + " "*remaining diff --git a/ProblemSolving/recoverBinarySearchTree/recover.py b/ProblemSolving/recoverBinarySearchTree/recover.py new file mode 100644 index 0000000..0caf253 --- /dev/null +++ b/ProblemSolving/recoverBinarySearchTree/recover.py @@ -0,0 +1,37 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right +class Solution: + def recoverTree(self, root: Optional[TreeNode]) -> None: + """ + Do not return anything, modify root in-place instead. + """ + + + def inOrder(node ,ordering): + + if node.left: + inOrder(node.left, ordering) + + if ordering: + #print(node.val, ordering[-1].val, ordering) + if node.val < ordering[-1].val: + for i in range(len(ordering)): + if i == 0 and ordering[i].val > node.val: + ordering[i].val, node.val = node.val, ordering[i].val + elif i == len(ordering)-1 and ordering[i].val > node.val: + ordering[i].val, node.val = node.val, ordering[i].val + elif ordering[i-1].val < node.val < ordering[i].val: + ordering[i].val, node.val = node.val, ordering[i].val + + ordering += [node] + + if node.right: + inOrder(node.right, ordering) + + return ordering + + order = inOrder(root, []) diff --git a/ProblemSolving/rectangleOverlap/rect.py b/ProblemSolving/rectangleOverlap/rect.py new file mode 100644 index 0000000..d83a889 --- /dev/null +++ b/ProblemSolving/rectangleOverlap/rect.py @@ -0,0 +1,11 @@ +class Solution(object): + def isRectangleOverlap(self, rec1, rec2): + """ + :type rec1: List[int] + :type rec2: List[int] + :rtype: bool + """ + + # reference: https://leetcode.com/problems/rectangle-overlap/discuss/132340/C%2B%2BJavaPython-1-line-Solution-1D-to-2D + # Well Explained: Compare it a 1D interval overlap and apply it to 2D + return rec1[0] < rec2[2] and rec2[0] < rec1[2] and rec1[1] < rec2[3] and rec2[1] < rec1[3] diff --git a/ProblemSolving/reformatDate/reformat.py b/ProblemSolving/reformatDate/reformat.py new file mode 100644 index 0000000..6baab56 --- /dev/null +++ b/ProblemSolving/reformatDate/reformat.py @@ -0,0 +1,28 @@ +class Solution: + def reformatDate(self, date: str) -> str: + + # Logic 1: Hacky way to accomplish - 100 pass - 93.56% faster + + # Holder for months to count 1->12 + months = ["", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] + #months = {"Jan": "1", "Feb":"2", "Mar":"3", "Apr":"4", "May":"5", "Jun":"6", "Jul":"7", "Aug":"8", "Sep":"9", "Oct":"10", "Nov":"11", "Dec":"12"} + + dateList = date.split(" ") + + # Calculate day + day = "" + i = 0 + while dateList[0][i].isdigit(): + day += dateList[0][i] + i += 1 + + # Calculate month --> Use a dictionary for being faster + month = str(months.index(dateList[1])) + #month = months[dateList[1]] + + # Year + year = dateList[2] + + # Return with formatting 2 digits + return year + "-" + month.zfill(2) + "-" + day.zfill(2) + diff --git a/ProblemSolving/relativeSortArray/relative.py b/ProblemSolving/relativeSortArray/relative.py new file mode 100644 index 0000000..2904244 --- /dev/null +++ b/ProblemSolving/relativeSortArray/relative.py @@ -0,0 +1,64 @@ +class Solution(object): + def relativeSortArray(self, arr1, arr2): + """ + :type arr1: List[int] + :type arr2: List[int] + :rtype: List[int] + """ + + # Logic 1: Using extra space, a dictionary to hold repeated elements of the array - 100 pass 68 % faster + """ + import collections + counter = collections.Counter(arr1) + result = [] + for element in arr2: + result.extend([element]*counter[element]) + del counter[element] + for element in sorted(counter.keys()): + result.extend([element]*counter[element]) + return result + """ + + # Logic 2: Using sorted with custom function - 100 pass 28 % faster + # * Custom function == relative ordering of array 2 else maximum element plus the element to arrange them in ascending after the arr2 elements + return sorted(arr1, key=lambda x: arr2.index(x) if x in arr2 else max(arr2)+x) + + # Logic 3: Naive Methid with some trick - Using sets - 43 % faster + # * We already know that array 2 is the correct order + # * Assume result to be array 2 itself. We just have to arrange the elements that are not in array2 in ascending order + result = arr2 + return result + sorted(set(arr2) ^ set(arr1)) + + +""" +class Solution(object): + def relativeSortArray(self, arr1, arr2): + """ + :type arr1: List[int] + :type arr2: List[int] + :rtype: List[int] + """ + + """ + def arrange(num): + if num in arr2: + return arr2.index(num) + else: + if arr1[-1] not in arr2: + return num < arr1[-1] + else: + return float('inf') + + return sorted(arr1, key=lambda x: arrange(x)) + """ + + import collections + counts = collections.Counter(arr1) + result = [] + reserve = [] + for i in range(len(arr2)): + if arr2[i] in counts: + result += [arr2[i]]*counts[arr2[i]] + del counts[arr2[i]] + return result+sorted(counts.elements()) +""" diff --git a/ProblemSolving/removeAllAdjacentDuplicates/remove.py b/ProblemSolving/removeAllAdjacentDuplicates/remove.py new file mode 100644 index 0000000..07661a0 --- /dev/null +++ b/ProblemSolving/removeAllAdjacentDuplicates/remove.py @@ -0,0 +1,18 @@ +class Solution(object): + def removeDuplicates(self, S): + """ + :type S: str + :rtype: str + """ + + # Stack logic: Pop until the values are same else push + stack = [] + + for element in S: + if not stack: + stack.append(element) + elif stack[-1] != element: + stack.append(element) + else: + stack.pop() + return "".join(stack) diff --git a/ProblemSolving/removeAllOccurrencesOfSubstring/att1.py b/ProblemSolving/removeAllOccurrencesOfSubstring/att1.py new file mode 100644 index 0000000..2e96091 --- /dev/null +++ b/ProblemSolving/removeAllOccurrencesOfSubstring/att1.py @@ -0,0 +1,32 @@ +class Solution: + def removeOccurrences(self, s: str, part: str) -> str: + + result = [s] + + while result: + s = result.pop(0) + remaining = "" + i = 0 + while i < len(s): + if len(s[i:]) < len(part): + remaining += s[i] + i += 1 + continue + if s[i:i+len(part)] != part: + remaining += s[i] + i += 1 + continue + print(s, remaining, s[i:i+len(part)], i) + s = remaining + s[i+len(part):] + remaining = "" + i = 0 + + if not result: + result.append(remaining) + else: + result[0].append(remaining) + + if s == result[0]: + return s + + return result diff --git a/ProblemSolving/removeAllOccurrencesOfSubstring/att2.py b/ProblemSolving/removeAllOccurrencesOfSubstring/att2.py new file mode 100644 index 0000000..6ea626f --- /dev/null +++ b/ProblemSolving/removeAllOccurrencesOfSubstring/att2.py @@ -0,0 +1,31 @@ +class Solution: + def removeOccurrences(self, s: str, part: str) -> str: + + if len(s) == len(part) and s == part: + return "" + + if len(part) > len(s): + return s + + if part == "": + return s + + if s == "": + return s + + if len(s) == 1 and s[0] == part[0]: + return "" + + stack = "" + i = 0 + while i < len(s): + if i+len(part) <= len(s) and s[i:i+len(part)] == part: + s = stack + s[i+len(part):] + stack = "" + i = 0 + continue + stack += s[i] + i += 1 + + return stack + diff --git a/ProblemSolving/removeDuplicates/dupe.py b/ProblemSolving/removeDuplicates/dupe.py new file mode 100644 index 0000000..1b27d1c --- /dev/null +++ b/ProblemSolving/removeDuplicates/dupe.py @@ -0,0 +1,120 @@ +class Solution: + def removeDuplicates(self, s: str, k: int) -> str: + + # use stack to store the count --> ref sol --> works 100% + countStack = [] + + i = 0 + while i < len(s): + + #print(s, countStack, i) + if i == 0 or s[i-1] != s[i]: + countStack.append(1) + else: + countStack[-1] += 1 + + if countStack[-1] == k: + countStack.pop() + s = s[:i-k+1] + s[i+1:] + i -= k + + i += 1 + + return s + + + """ + # Iteration iterally following the problem statement - 1 --> all pass but time limit exceeded on scale case + + hasDups = True + + while hasDups: + + hasDups = False + + current_char = "" + current_set = 0 + + i = 0 + while i < len(s)-1: + + j = i+1 + current_char = s[i] + current_set = 1 + + while j < len(s) and s[j] == current_char: + current_set += 1 + j += 1 + + if current_set == k: + hasDups = True + s = s[:i] + s[j:] + + #print(i, current_char, current_set, hasDups, s) + i += 1 + + #print("1: ", current_char, current_set, hasDups, s) + + return s + """ + + """ + # Iteration iterally following the problem statement - 2 (with set and skipping iteration) --> all pass but time limit exceeded on scale case + + hasDups = True + + while hasDups: + + hasDups = False + + current_char = "" + current_set = 0 + + i = 0 + while i < len(s)-1: + + #print(i, k) + if i+k <= len(s) and len(set(s[i:i+k])) == 1: + hasDups = True + s = s[:i] + s[i+k:] + break + + i += 1 + + print(s) + #print("1: ", current_char, current_set, hasDups, s) + + return s + """ + + + # Sliding window --> brainstorm + """ + self.window = {} + + def create_sliding_window(window): + + for w in window: + if w not in self.window: + self.window[w] = 0 + self.window[w] += 1 + + + + for i in range(0, len(s), k): + + if not self.window: + create_sliding_window(s[i:i+k]) + + if len(self.window) > 2: + continue + elif len(self.window) == 2: + else: + """ + + + + + + + diff --git a/ProblemSolving/removeDuplicatesFromSortedListII/list.py b/ProblemSolving/removeDuplicatesFromSortedListII/list.py new file mode 100644 index 0000000..3617ca3 --- /dev/null +++ b/ProblemSolving/removeDuplicatesFromSortedListII/list.py @@ -0,0 +1,45 @@ +# Definition for singly-linked list. +# class ListNode(object): +# def __init__(self, x): +# self.val = x +# self.next = None + +class Solution(object): + def deleteDuplicates(self, head): + """ + :type head: ListNode + :rtype: ListNode + """ + + # Init variables + front = head + parent = None + duplicate = None + + while head and head.next: + if parent: + print(parent.val, head.val, head.next.val) + + # Find Duplicates + while head and head.next and head.val == head.next.val: + if not duplicate: + duplicate = head + head = head.next + + # Strip duplicate nodes + if duplicate and head.val == duplicate.val: + if parent: + parent.next = head.next + head = head.next + else: + temp = head + head = head.next + front = head + temp.next = None + duplicate = False + else: + # Next Iteration Vars + parent = head + head = head.next + + return front diff --git a/ProblemSolving/removeDuplicatesSortedArray/rem2.py b/ProblemSolving/removeDuplicatesSortedArray/rem2.py new file mode 100644 index 0000000..db1a0cc --- /dev/null +++ b/ProblemSolving/removeDuplicatesSortedArray/rem2.py @@ -0,0 +1,21 @@ +class Solution(object): + def removeDuplicates(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + + temp = None + i = 0 + while i < len(nums): + if temp == None: + temp = nums[i] + i += 1 + elif temp == nums[i]: + #print(nums, nums[i]) + nums.pop(i) + #print(nums, nums[i]) + else: + temp = nums[i] + i += 1 + return len(nums) diff --git a/ProblemSolving/removeElement/rem2.py b/ProblemSolving/removeElement/rem2.py new file mode 100644 index 0000000..f226ba6 --- /dev/null +++ b/ProblemSolving/removeElement/rem2.py @@ -0,0 +1,17 @@ +class Solution(object): + def removeElement(self, nums, val): + """ + :type nums: List[int] + :type val: int + :rtype: int + """ + + i = 0 + while i < len(nums): + if nums[i] == val: + nums.pop(i) + else: + i += 1 + return len(nums) + + diff --git a/ProblemSolving/removeElement/rem3.py b/ProblemSolving/removeElement/rem3.py new file mode 100644 index 0000000..c355f15 --- /dev/null +++ b/ProblemSolving/removeElement/rem3.py @@ -0,0 +1,19 @@ +class Solution: + def removeElement(self, nums: List[int], val: int) -> int: + + + firstVal = None + for i in range(len(nums)): + + if nums[i] == val: + if firstVal == None: + firstVal = i + else: + if firstVal != None: + nums[i], nums[firstVal] = nums[firstVal], nums[i] + firstVal += 1 + + #print(nums) + return firstVal + + diff --git a/ProblemSolving/removeKDigits/rem2.py b/ProblemSolving/removeKDigits/rem2.py new file mode 100644 index 0000000..ce4f880 --- /dev/null +++ b/ProblemSolving/removeKDigits/rem2.py @@ -0,0 +1,41 @@ +class Solution(object): + def removeKdigits(self, num, k): + """ + :type num: str + :type k: int + :rtype: str + """ + + # Logic 1: + # * At every element delete, K elements and append the remaining string + # * this logic doesnt work when consecutive number is the answer like [5,3,3,4], 2 ==> answer is 33 + """ + mini = float('inf') + + if k == len(num): + return "0" + elif len(num) == 1: + return num + + if len(num[1:-1]) == len(num)-k and int(num[1:-1]) < mini: + mini = int(num[1:-1]) + + for i in range(len(num)): + print(num[i], num[:i]+num[i+k:], mini) + if num[:i]+num[i+k:] != "" and int(num[:i]+num[i+k:]) < mini: + mini = int(num[:i]+num[i+k:]) + + return str(mini) + """ + + # Logic 2: Lets go greedy --> At every iteration if the number is larger than the current element we remove it + stack = [] + if len(num) == k: + return '0' + for i in range(len(num)): + while k and stack and stack[-1] > num[i]: + stack.pop() + k -= 1 + stack.append(num[i]) + print(stack) + return str(int("".join(stack[:-k or None]))) diff --git a/ProblemSolving/removeNthFromEnd/remove.py b/ProblemSolving/removeNthFromEnd/remove.py new file mode 100644 index 0000000..afda7ac --- /dev/null +++ b/ProblemSolving/removeNthFromEnd/remove.py @@ -0,0 +1,35 @@ +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next +class Solution: + def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]: + + # 2 iteration mode 2*O(n) = O(n) + + # 1. find length of list + l = head + length = 1 + while l: + length += 1 + l = l.next + + # 2. find nth node to replace + i = head + ind = 1 + left = None + while i: + pos = length-ind + if pos == n: + if not left: + head = i.next + elif left and i.next: + left.next = i.next + else: + left.next = None + ind += 1 + left = i + i = i.next + + return head diff --git a/ProblemSolving/removeOutermostParanthesis/remove.py b/ProblemSolving/removeOutermostParanthesis/remove.py new file mode 100644 index 0000000..76f0a81 --- /dev/null +++ b/ProblemSolving/removeOutermostParanthesis/remove.py @@ -0,0 +1,95 @@ +class Solution(object): + + # Logic 1: 100 pass - Balanced brackets check/validation + Paranthesis removal + # * Only 5 percent faster as the balance check runs every time + """ + def balanced_or_not(self, exp): + s = [] + while exp: + current = exp.pop(0) + if current == "(": + s.append(current) + else: + if s and s[-1] == "(": + s.pop() + else: + return False + if len(s) == 0: + return True + else: + return False + + def removeOuterParentheses(self, S): + stack = [] + result = "" + while S: + current = S[0] + S = S[1:] + stack.append(current) + #print stack + if self.balanced_or_not(stack[:]): + #if stack[1:-1] != "": + temp = stack[1:-1] + result += "".join(temp) + stack = [] + #print stack + return result + """ + + """ + # Logic 2: 100 pass - Hybrid attempt for the above logic + def removeOuterParentheses(self, S): + stack = [] + result = "" + balanced = False + temp = "" + while S: + current = S[0] + S = S[1:] + temp += current + + if current == "(": + stack.append(current) + else: + if stack and stack[-1] == "(": + stack.pop() + else: + return False + + if not stack: + balanced = True + else: + balanced = False + + if balanced == True: + result += temp[1:-1] + stack = [] + temp = "" + return result + """ + + # Logic 3: 100 pass - 94 - For this problem we are dealing with just the () brackets only and removing just outermost --> Just count the braces + def removeOuterParentheses(self, S): + balanced_braces = 0 + result = "" + temp = "" + for i in S: + temp += i + if i == "(": + balanced_braces += 1 + else: + balanced_braces -= 1 + #print temp + if balanced_braces == 0: + result += temp[1:-1] + temp = "" + return result + + # Counting separate open vs closed braces for a more simpler logic already implemented at https://leetcode.com/problems/remove-outermost-parentheses/discuss/270226/Python-easy-100-solution-with-commentary + + + + + + + diff --git a/ProblemSolving/removePalindromeSubsequence/rem.py b/ProblemSolving/removePalindromeSubsequence/rem.py new file mode 100644 index 0000000..e0a5b74 --- /dev/null +++ b/ProblemSolving/removePalindromeSubsequence/rem.py @@ -0,0 +1,8 @@ +class Solution: + # Logic 1: check for empty and palindrome all other cases it will becomes palindrome when removing 2 elements + def removePalindromeSub(self, s: str) -> int: + if s == "": + return 0 + if s == s[::-1]: + return 1 + return 2 diff --git a/ProblemSolving/removeVowelsFromAString/remove.py b/ProblemSolving/removeVowelsFromAString/remove.py new file mode 100644 index 0000000..c94767f --- /dev/null +++ b/ProblemSolving/removeVowelsFromAString/remove.py @@ -0,0 +1,35 @@ +class Solution: + def removeVowels(self, S: str) -> str: + + # Logic 1: Define vowels as set for O(1) check and iterate string to remove vowels + # 1. we can remove the vowels --> 88% faster + """ + vowels = {'a', 'e', 'i', 'o', 'u'} + i = 0 + while i < len(S): + if S[i] in vowels: + S = S[:i]+S[i+1:] + else: + i += 1 + return S + """ + + # 2. we can also create a new string if they are not vowels --> 95 % faster + + vowels = {'a', 'e', 'i', 'o', 'u'} + result = "" + i = 0 + while i < len(S): + if S[i] not in vowels: + result += S[i] + i += 1 + return result + + + # 3. we can use string replace or regex functions --> 95 % faster + """ + import re + return re.sub("a|e|i|o|u", "", S) + """ + + diff --git a/ProblemSolving/reorder_log_files/reorder.py b/ProblemSolving/reorder_log_files/reorder.py new file mode 100644 index 0000000..09dc0d3 --- /dev/null +++ b/ProblemSolving/reorder_log_files/reorder.py @@ -0,0 +1,138 @@ +class Solution(object): + # 100 pass logic with the tie checker implemented + def reorderLogFiles(self, logs): + """ + :type logs: List[str] + :rtype: List[str] + """ + + # A log ==> "yy xx xx xx" + # yy == id + # xx xx xx == log + + # Dictionary to hold all the entries + # * Digit, store as list to maintain the order + # * Letters, store as dictionary of id as value, so it is easy to sort the logs vs ids + dictionary = { + "letter":{}, + "digit":[] + } + + # Result list + result = [] + + # iterate through the logs to fill the dictionary + # * Digit logs - store with index + # * Letter logs - store only identifier as keys + + for log in logs: + current_log = log.split(" ") + # Digit logic - if log contains digit + if ("".join(current_log[1:])).isdigit(): + dictionary["digit"].append(log) + else: + # Store logs as key and id as value + # Tie checker + if " ".join(current_log[1:]) not in dictionary["letter"]: + dictionary["letter"][" ".join(current_log[1:])] = current_log[0] + else: + # Tie occurred + dictionary["letter"][" ".join(current_log[1:])] = [dictionary["letter"][" ".join(current_log[1:])]] + dictionary["letter"][" ".join(current_log[1:])].append(current_log[0]) + + # lexi sort the letter logs without ids + letter_logs = sorted(dictionary["letter"].keys()) + + # Logic works without the underlying block - this block checks sorting in the case of a tie and sorts + # Append letter logs + for letter in letter_logs: + # Handle tie condition + if type(dictionary["letter"][letter]) is list: + identifiers = sorted(dictionary["letter"][letter]) + for i in identifiers: + result.append(i+" "+letter) + + else: + result.append(dictionary["letter"][letter]+" "+letter) + + # Append the digit logs in the same order + result.extend(dictionary["digit"]) + + return result + + # Another Logic ---> + # This logic is 100 pass for this problem without the tie checker implemented.... + def reorderLogFilesWithoutTieCheck(self, logs): + """ + :type logs: List[str] + :rtype: List[str] + """ + + # Dictionary to hold all the entries + dictionary = { + "letter":{}, + "digit":[] + } + + result = [] + + # iterate through the logs to fill the dictionary + # * Digit logs - store with index + # * Letter logs - store only identifier as keys + + for log in logs: + current_log = log.split(" ") + # Digit logic + if ("".join(current_log[1:])).isdigit(): + dictionary["digit"].append(log) + else: + dictionary["letter"][" ".join(current_log[1:])] = current_log[0] + + # lexi sort + letter_logs = sorted(dictionary["letter"].keys()) + + for letter in letter_logs: + result.append(dictionary["letter"][letter]+" "+letter) + + result.extend(dictionary["digit"]) + + return result + +""" +class Solution(object): + def reorderLogFiles(self, logs): + """ + :type logs: List[str] + :rtype: List[str] + """ + + def compare(item1, item2): + keys1 = item1.split(" ") + keys2 = item2.split(" ") + k1 = keys1[0] + v1 = " ".join(keys1[1:]) + k2 = keys2[0] + v2 = " ".join(keys2[1:]) + if v1 < v2: + return -1 + elif v1 > v2: + return 1 + else: + if k1 < k2: + return -1 + else: + return 1 + + letter_log = [] + digit_log = [] + for line in logs: + keys = line.split(" ") + if keys[1].isdigit(): + digit_log.append(line) + else: + letter_log.append(line) + result = [] + result.extend(sorted(letter_log, cmp=compare)) + result.extend(digit_log) + return result +""" diff --git a/ProblemSolving/reorganizeString/reorg.py b/ProblemSolving/reorganizeString/reorg.py new file mode 100644 index 0000000..e02e231 --- /dev/null +++ b/ProblemSolving/reorganizeString/reorg.py @@ -0,0 +1,53 @@ +class Solution: + def reorganizeString(self, s: str) -> str: + + # Logic 1: counting the num of chars, contructing a non overlap string from highest frequency + + freqs = {} + for i in range(len(s)): + if s[i] not in freqs: + freqs[s[i]] = 0 + freqs[s[i]] += 1 + + result = "" + i = 0 + order = sorted(freqs.keys(), key=lambda x: freqs[x], reverse=True) + + while i < len(order) and len(order) > 1: + prev = order + o = order[i] + if o not in freqs: + i += 1 + continue + if not result: + result += o + freqs[o] -= 1 + i += 1 + elif result[-1] != o: + result += o + freqs[o] -= 1 + i = 0 + else: + print(i, o, result) + i += 1 + if freqs[o] == 0: + del freqs[o] + order.pop(i) + i = 0 + order = sorted(freqs.keys(), key=lambda x: freqs[x], reverse=True) + if prev[i] != order[i]: + i = 0 + + if freqs and len(freqs) != 1: + return "" + if freqs and len(freqs) == 1: + for k,v in freqs.items(): + if v == 1: + if result and k != result[-1]: + return result+k + else: + return k + else: + return "" + + return result diff --git a/ProblemSolving/restoreIpAddresses/restore.py b/ProblemSolving/restoreIpAddresses/restore.py new file mode 100644 index 0000000..6dcb1e7 --- /dev/null +++ b/ProblemSolving/restoreIpAddresses/restore.py @@ -0,0 +1,27 @@ +class Solution(object): + def restoreIpAddresses(self, s): + """ + :type s: str + :rtype: List[str] + """ + + def buildIPs(remaining, current, subnets): + + if not remaining and current and subnets == 4: + self.ips.append(current[1:]) + + if remaining and subnets != 4: + for i in range(3): + #print(i, remaining, current, subnets) + if i == 0: + buildIPs(remaining[:-1], "." + remaining[-1:] + current, subnets +1 ) + if i == 1 and len(remaining) > 1 and remaining[-2] != "0": + buildIPs(remaining[:-2], "." + remaining[-2:] + current, subnets +1 ) + if i == 2 and len(remaining) > 2 and remaining[-3] in {"1","2"} and int(remaining[-3:]) <= 255: + buildIPs(remaining[:-3], "." + remaining[-3:] + current, subnets +1 ) + + self.ips = [] + buildIPs(s, "", 0) + return self.ips + + diff --git a/ProblemSolving/reverseInteger/rev2.py b/ProblemSolving/reverseInteger/rev2.py new file mode 100644 index 0000000..177863f --- /dev/null +++ b/ProblemSolving/reverseInteger/rev2.py @@ -0,0 +1,19 @@ +class Solution(object): + def reverse(self, x): + """ + :type x: int + :rtype: int + """ + + reverse = "" + limit = 2**31 + if x < 0: + reverse += "-" + x = abs(x) + reverse += "0" + while x: + reverse += str(x%10) + x = x/10 + if int(reverse) > limit-1 or int(reverse) < -(limit): + return 0 + return int(reverse) diff --git a/ProblemSolving/reverseInteger/rev3.py b/ProblemSolving/reverseInteger/rev3.py new file mode 100644 index 0000000..f0779a0 --- /dev/null +++ b/ProblemSolving/reverseInteger/rev3.py @@ -0,0 +1,21 @@ +class Solution(object): + def reverse(self, x): + """ + :type x: int + :rtype: int + """ + + result = 0 + neg = False + if x < 0: + x = abs(x) + neg = True + maxi = 2**31 + while x > 0: + result = result*10 + x%10 + x = x/10 + if result > maxi or result < -maxi: + return 0 + if neg: + result = -(result) + return result diff --git a/ProblemSolving/reverseInteger/rev4.py b/ProblemSolving/reverseInteger/rev4.py new file mode 100644 index 0000000..abc3d9f --- /dev/null +++ b/ProblemSolving/reverseInteger/rev4.py @@ -0,0 +1,40 @@ +class Solution: + def reverse(self, x: int) -> int: + + n = 2**31 + + result = 0 + negate = False + if x < 0: + negate = True + x = abs(x) + + y = x + places = 1 + while y >= 10: + places = places * 10 + y = y//10 + + print(places) + + while x: + temp = x%10 + x = x//10 + print(temp, x, places) + if temp == 0: + places = places//10 + if places == 0: + places = 1 + continue + result += temp * places + print(result) + places = places//10 + + if negate: + result = -result + + if result < -n or result > n: + return 0 + + return result + diff --git a/ProblemSolving/reverseOnlyLetters/rev.py b/ProblemSolving/reverseOnlyLetters/rev.py new file mode 100644 index 0000000..e6e7586 --- /dev/null +++ b/ProblemSolving/reverseOnlyLetters/rev.py @@ -0,0 +1,27 @@ +class Solution(object): + def reverseOnlyLetters(self, S): + """ + :type S: str + :rtype: str + """ + + # Logic: 100 pass 40 ms + # * Remove characters which are not alphabets from the string + # * Reverse the string + # * Place respective non-alphabet characters were they were before + + # result string + result = "" + + # Lets use isalpha to check for alphabets + only_letters = [i for i in S if i.isalpha()][::-1] + + # Run through the original name to find non alphabets and place them + for char in S: + if not char.isalpha(): + result += char + else: + result += only_letters.pop(0) + + return result + diff --git a/ProblemSolving/reverseOnlyLetters/rev_mock.py b/ProblemSolving/reverseOnlyLetters/rev_mock.py new file mode 100644 index 0000000..106686f --- /dev/null +++ b/ProblemSolving/reverseOnlyLetters/rev_mock.py @@ -0,0 +1,31 @@ +class Solution(object): + def reverseOnlyLetters(self, S): + """ + :type S: str + :rtype: str + """ + + # Logic 1: + reverse = list(S[::-1]) + result = "" + for i in range(len(S)): + #print(result, S, reverse) + if S[i].isalpha(): + while reverse and not reverse[0].isalpha(): + reverse.pop(0) + result += reverse.pop(0) + else: + result += S[i] + return result + + # Just Reverse + #return S[::-1] + + # Reverse the substring alone + """ + for i in range(len(S)): + if not S[i].isalpha(): + S = S[:i][::-1]+S[i:] + i += 1 + return S + """ diff --git a/ProblemSolving/reverseString/recursive.py b/ProblemSolving/reverseString/recursive.py new file mode 100644 index 0000000..a5b04b7 --- /dev/null +++ b/ProblemSolving/reverseString/recursive.py @@ -0,0 +1,13 @@ +class Solution(object): + def reverseString(self, s, i=0, j=-1): + """ + :type s: List[str] + :rtype: None Do not return anything, modify s in-place instead. + """ + + if i >= len(s)//2: + return + s[i], s[j] = s[j], s[i] + #print(s, i, j) + self.reverseString(s, i+1, j-1) + diff --git a/ProblemSolving/reverseString/rev2.py b/ProblemSolving/reverseString/rev2.py new file mode 100644 index 0000000..c2c99ab --- /dev/null +++ b/ProblemSolving/reverseString/rev2.py @@ -0,0 +1,16 @@ +class Solution(object): + def reverseString(self, s): + """ + :type s: List[str] + :rtype: None Do not return anything, modify s in-place instead. + """ + + #s[:] = s[::-1] + + left = 0 + right = len(s)-1 + while left <= right: + s[left], s[right] = s[right], s[left] + left += 1 + right -= 1 + print(s) diff --git a/ProblemSolving/reverseStringII/rev2.py b/ProblemSolving/reverseStringII/rev2.py new file mode 100644 index 0000000..162dda1 --- /dev/null +++ b/ProblemSolving/reverseStringII/rev2.py @@ -0,0 +1,22 @@ +class Solution(object): + def reverseStr(self, s, k): + """ + :type s: str + :type k: int + :rtype: str + """ + + # Logic 1: O(N) Iteration + countK = 1 + index = 0 + for i in range(len(s)): + if i-index == k: + if countK%2 != 0: + s = s[:index] + s[index:i][::-1] + s[i:] + else: + s = s[:index] + s[index:i] + s[i:] + index = i + countK += 1 + if countK%2 != 0: + s = s[:index] + s[index:][::-1] + return s diff --git a/ProblemSolving/reverseVowelsOfAString/rev.py b/ProblemSolving/reverseVowelsOfAString/rev.py new file mode 100644 index 0000000..328e551 --- /dev/null +++ b/ProblemSolving/reverseVowelsOfAString/rev.py @@ -0,0 +1,17 @@ +class Solution: + def reverseVowels(self, s: str) -> str: + + vowels = { "a", "e", "i", "o", "u" } + + vs = [] + + for i in range(len(s)): + if s[i].lower() in vowels: + vs.append(i) + + while len(vs) > 1: + left = vs.pop(0) + right = vs.pop() + s = s[:left] + s[right] + s[left+1:right] + s[left] + s[right+1:] + + return s diff --git a/ProblemSolving/reverseWordsInAString/rev.py b/ProblemSolving/reverseWordsInAString/rev.py new file mode 100644 index 0000000..b194e93 --- /dev/null +++ b/ProblemSolving/reverseWordsInAString/rev.py @@ -0,0 +1,15 @@ +class Solution: + def reverseWords(self, s: str) -> str: + + # 1. stack push and pop with 2*O(N) iteration for chars or for words split instead of one iteration + + process = s.split(" ") + stack = [] + + for i in range(len(process)): + s = process[i].strip() + if not s: + continue + stack = [s] + stack + + return " ".join(stack) diff --git a/ProblemSolving/richestCustomerWealth/rich.py b/ProblemSolving/richestCustomerWealth/rich.py new file mode 100644 index 0000000..8d26d6d --- /dev/null +++ b/ProblemSolving/richestCustomerWealth/rich.py @@ -0,0 +1,11 @@ +# Logic 1: Naive matrix row iteration and sum - 100 pass - 72% faster +class Solution: + def maximumWealth(self, accounts: List[List[int]]) -> int: + wealthy = 0 + wealthy_cust = -1 + for customer in range(len(accounts)): + current_cust_wealth = sum(accounts[customer]) + if current_cust_wealth > wealthy: + wealthy = current_cust_wealth + wealthy_cust = customer + return wealthy diff --git a/ProblemSolving/ringsAndRods/rings.py b/ProblemSolving/ringsAndRods/rings.py new file mode 100644 index 0000000..ec41004 --- /dev/null +++ b/ProblemSolving/ringsAndRods/rings.py @@ -0,0 +1,25 @@ +class Solution: + # Logic 1: maintain rod as dicts and update counts - 85% faster + + def countPoints(self, rings: str) -> int: + + rods = [{} for i in range(11)] # maintain rods as list of dicts for easier lookup + rod_with_all_colors = 0 + + for r in range(0, len(rings), 2): + + color = rings[r] + rod = int(rings[r+1]) + + if color not in rods[rod]: + rods[rod][color] = 0 + + # check for all colors presence in a row + if len(rods[rod]) == 3: + rod_with_all_colors += 1 + + # this is not asked, but good to track how many color rings are there per row + rods[rod][color] += 1 + + return rod_with_all_colors + diff --git a/ProblemSolving/robotBoundedInCircle/robot.py b/ProblemSolving/robotBoundedInCircle/robot.py new file mode 100644 index 0000000..74b6974 --- /dev/null +++ b/ProblemSolving/robotBoundedInCircle/robot.py @@ -0,0 +1,62 @@ +class Solution(object): + def isRobotBounded(self, instructions): + """ + :type instructions: str + :rtype: bool + """ + + # Logic 1: O(4n) + # * Execute the directions in order and check if origin is reached + # * Increment the number of times to execute the instructions. Got pass in 4 + # * Reference: https://leetcode.com/problems/robot-bounded-in-circle/discuss/300372/python-4*instructions-O(n) + + # Convert Instructions to some number of times until reaches the origin, this can be infinite or some even count + instructions += instructions*3 + + # Directions + # * based on the face -> L,R of each + directions = { + "N": ['W', 'E'], + "S": ['E', 'W'], + "E": ['N', 'S'], + "W": ['S', 'N'] + } + + # Facing direction + face = "N" + + # Current co-ordinate + x, y = 0, 0 + + # One Full Loop of the Instructions + + # Intructions iteration + for ins in instructions: + # Set face based on the directions + if ins == "L": + face = directions[face][0] + elif ins == "R": + face = directions[face][1] + else: + # G --> movement in the particular direction of face + if face == "N": + y += 1 + elif face == "S": + y -= 1 + elif face == "E": + x += 1 + else: + x -= 1 + + if x == 0 and y == 0: + return True + else: + return False + + + + + + + + diff --git a/ProblemSolving/rodCutting/rods.py b/ProblemSolving/rodCutting/rods.py new file mode 100644 index 0000000..de2bdb4 --- /dev/null +++ b/ProblemSolving/rodCutting/rods.py @@ -0,0 +1,44 @@ +# Logic1 +# * Recursion + +def cut_rods(prices, n): + if n <= 0: + return 0 + + maxi = float('-inf') + + for i in range(n): + maxi = max(maxi, prices[i] + cut_rods(prices, n-i-1)) + + return maxi + +# Logic2 +# * Memoization +def cut_rods2(prices, n): + memo = [0]*(n+1) + for i in range(1, n+1): + maxi = float('-inf') + for j in range(i): + maxi = max(maxi, prices[j] + memo[i-j-1]) + memo[i] = maxi + return memo[n] + + +# Logic3: +# * Memoization + Recursion? +def cut_rods3(prices, n, memo): + maxi = float('-inf') + for i in range(n, 1, -1): + maxi = max(maxi, prices[i] + cut_rods3(prices, n-1, memo)) + print(memo) + memo[i] = maxi + +# Driver +def main(): + arr = [1, 5, 8, 9, 10, 17, 17, 20] + size = len(arr) + print(cut_rods(arr, size)) + print(cut_rods2(arr, size)) + print(cut_rods3(arr, size, [0]*size)) + +main() diff --git a/ProblemSolving/romanToNumeral/roman2.py b/ProblemSolving/romanToNumeral/roman2.py new file mode 100644 index 0000000..6fb867c --- /dev/null +++ b/ProblemSolving/romanToNumeral/roman2.py @@ -0,0 +1,26 @@ +class Solution: + def romanToInt(self, s: str) -> int: + + integer = 0 + + roman = { + "": 0, + "I": 1, + "V": 5, + "X": 10, + "L": 50, + "C": 100, + "D": 500, + "M": 1000 + } + + while s: + curr = s[0] + if len(s) > 1 and roman[curr] < roman[s[1]]: + integer += roman[s[1]]-roman[curr] + s = s[2:] + else: + integer += roman[curr] + s = s[1:] + + return integer diff --git a/ProblemSolving/rotateString/rot2.py b/ProblemSolving/rotateString/rot2.py new file mode 100644 index 0000000..275952e --- /dev/null +++ b/ProblemSolving/rotateString/rot2.py @@ -0,0 +1,37 @@ +class Solution(object): + def rotateString(self, A, B): + """ + :type A: str + :type B: str + :rtype: bool + """ + + if not A and not B: + return True + + for i in range(len(A)): + if A[i:]+A[:i] == B: + return True + return False + +""" +class Solution(object): + def rotateString(self, A, B): + """ + :type A: str + :type B: str + :rtype: bool + """ + + # Naive Rotate and Check + A = list(A) + B = list(B) + if A == B: + return True + for i in range(len(A)): + A.insert(len(A)-1, A.pop(0)) + print(A, B) + if A == B: + return True + return False +""" diff --git a/ProblemSolving/rotatedDigits/rot.py b/ProblemSolving/rotatedDigits/rot.py index fd98236..e710110 100644 --- a/ProblemSolving/rotatedDigits/rot.py +++ b/ProblemSolving/rotatedDigits/rot.py @@ -31,4 +31,41 @@ def rotatedDigits(self, N): result.append(n) return len(result) +""" +class Solution(object): + def rotatedDigits(self, N): + """ + :type N: int + :rtype: int + """ + rot = { + 0: 0, + 1: 1, + 2: 5, + 5: 2, + 6: 9, + 8: 8, + 9: 6 + } + + def good_number(num): + result = "" + for i in str(num): + if int(i) not in rot: + return False + else: + result += str(rot[int(i)]) + #print(num , result) + if int(result) != num: + return True + else: + return False + + ans = [] + for i in range(1, N+1): + if good_number(i): + ans.append(i) + print(ans) + return len(ans) +""" diff --git a/ProblemSolving/rottenOranges/rot.py b/ProblemSolving/rottenOranges/rot.py new file mode 100644 index 0000000..456fc1a --- /dev/null +++ b/ProblemSolving/rottenOranges/rot.py @@ -0,0 +1,34 @@ +class Solution(object): + def orangesRotting(self, grid): + """ + :type grid: List[List[int]] + :rtype: int + """ + + rotten = 0 + minute = 0 + old_rotten = 1 + + while old_rotten != rotten: + for i in range(3): + for j in range(3): + old_rotten = rotten + if grid[i][j] == 2: + if i-1 > 0 and grid[i-1][j] != 2: + grid[i-1][j] = 2 + rotten += 1 + if i+1 < 3 and grid[i+1][j] != 2: + grid[i+1][j] = 2 + rotten += 1 + if j-1 > 0 and grid[i][j-1] != 2: + grid[i][j-1] = 2 + rotten += 1 + if j+1 < 3 and grid[i][j+1] != 2: + grid[i][j+1] = 2 + rotten += 1 + print i, j + if rotten != old_rotten: + minute += 1 + return minute + + diff --git a/ProblemSolving/runningSumOf1dArray/run.py b/ProblemSolving/runningSumOf1dArray/run.py new file mode 100644 index 0000000..b9db24a --- /dev/null +++ b/ProblemSolving/runningSumOf1dArray/run.py @@ -0,0 +1,30 @@ +# Logic 0: Naive iteration: O(1) space in-place updates with o(n) time +class Solution(object): + def runningSum(self, nums): + """ + :type nums: List[int] + :rtype: List[int] + """ + + # Naive iteration: O(1) space in-place updates with o(n) time + last_sum = 0 + for i in range(len(nums)): + nums[i] = last_sum + nums[i] + last_sum = nums[i] + return nums + +# Logic 1: O(N) iteration in finding sum and save with separate O(N) array - 92% faster +class Solution: + def runningSum(self, nums: List[int]) -> List[int]: + current_sum = 0 + run_sum = [] + for i in nums: + current_sum += i + run_sum.append(current_sum) + return run_sum + +# Logic 2: Itertools way +class Solution: + def runningSum(self, nums: List[int]) -> List[int]: + from itertools import accumulate + return accumulate(nums) diff --git a/ProblemSolving/sameTree/same2.py b/ProblemSolving/sameTree/same2.py new file mode 100644 index 0000000..5f7e798 --- /dev/null +++ b/ProblemSolving/sameTree/same2.py @@ -0,0 +1,106 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def isSameTree(self, p, q): + """ + :type p: TreeNode + :type q: TreeNode + :rtype: bool + """ + + # Recursive method ( any traversal pre/post/in or bfs can be used ) + + # 1. Go through the full recursion of both the trees separately and then decide - 100 pass + """ + def preOrder(node, order): + if node: + order.append(node.val) + if node.left: + preOrder(node.left, order) + else: + order.append(None) + if node.right: + preOrder(node.right, order) + else: + order.append(None) + return order + + return preOrder(p, []) == preOrder(q, []) + """ + + # 2. Go through both the trees together in single iteration, as soon as there is a mismatch exit - 100 pass + """ + def traverse(node1, node2): + + # one of the nodes is null + current = False + if not node1 and not node2: # both are null + current = True + elif node1 and node2: # both are not null + + # Current node + if node1.val != node2.val: + current = False + else: + current = True + + # Left Node + if node1.left and node2.left: + current &= traverse(node1.left, node2.left) + elif not node1.left and not node2.left: + current &= True + else: + current &= False + + # Right Node + if node1.right and node2.right: + current &= traverse(node1.right, node2.right) + elif not node1.right and not node2.right: + current &= True + else: + current &= False + + return current + + return traverse(p, q) + """ + + # Iterative Method - 100 pass + + # Create 2 stacks to track the nodes in both the trees + tree1 = [p] + tree2 = [q] + + # Iterate until both the nodes in trees expire together... + while tree1 and tree2: + + # Current Node check + t1 = tree1.pop(0) + t2 = tree2.pop(0) + if t1 and t2: + if t1.val != t2.val: + return False + + # Add left and right of both the trees + tree1.append(t1.left) if t1.left else tree1.append(None) + tree1.append(t1.right) if t1.right else tree1.append(None) + tree2.append(t2.left) if t2.left else tree2.append(None) + tree2.append(t2.right) if t2.right else tree2.append(None) + elif not t1 and not t2: # Continue if both are None + pass + else: # Fail if one of them is None + return False + + # If one tree still remains then False + if tree1 or tree2: + return False + else: + return True + + + diff --git a/ProblemSolving/satisfiabilityOfEqualityEquations/equations.py b/ProblemSolving/satisfiabilityOfEqualityEquations/equations.py new file mode 100644 index 0000000..0c8eedb --- /dev/null +++ b/ProblemSolving/satisfiabilityOfEqualityEquations/equations.py @@ -0,0 +1,50 @@ +class Solution: + def equationsPossible(self, equations: List[str]) -> bool: + + # Logic1: 2*O(n) iteration to cover equal cases first and then non-equal ones + + equal = "==" + inequal = "!=" + + graph = {} + + def travG(curr, target, visited): + if curr == target: + return True + + found = False + if curr not in visited: + for nxt in graph[curr]: + found = found or travG(nxt, target, visited|set(curr)) + + return found + + for i in range(len(equations)): + curr = equations[i] + + op = curr.split(equal) + + if len(op) > 1: + if op[0] not in graph: + graph[op[0]] = [] + if op[1] not in graph: + graph[op[1]] = [] + graph[op[0]].append(op[1]) + graph[op[1]].append(op[0]) + + print(graph) + + for i in range(len(equations)): + curr = equations[i] + + op = curr.split(inequal) + + if len(op) > 1: + if op[0] not in graph: + graph[op[0]] = [] + if op[1] not in graph: + graph[op[1]] = [] + if travG(op[0], op[1], set()): + return False + + return True diff --git a/ProblemSolving/searchInBinarySearchTree/bst.py b/ProblemSolving/searchInBinarySearchTree/bst.py new file mode 100644 index 0000000..a554e20 --- /dev/null +++ b/ProblemSolving/searchInBinarySearchTree/bst.py @@ -0,0 +1,94 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def searchBST(self, root, val): + """ + :type root: TreeNode + :type val: int + :rtype: TreeNode + """ + # 100 pass + # traverse level order using a list + stack = [root] + + # Bool to find a match + match = 0 + + # result tree + self.result = [] + + # Traverse by popping as we move + while stack: + # Current element from front of the list + current = stack.pop(0) + # Null check + if current: + # Match!, then update stack and match var + if current.val == val: + stack = [] + self.result = [] + match = 1 + + # If match happened then append to result + if match == 1: + self.result.append(current.val) + + # Traversing update for left and right of current node + stack.append(current.left) + stack.append(current.right) + else: + # Result expects addition of null for nodes that are null + self.result.append(None) + + # Eradicate nulls present at the end + while self.result and self.result[-1] == None: + self.result.pop() + + return self.result + + """ + # Expected answer in level order traversal + self.selected = None + self.subtree = [] + + # Recursive + def recurse(node): + + if not node: + #self.subtree.append(None) + return + + self.subtree.append(node.val) + + if node.val == val: + self.selected = node + + if not node.left and not node.right: + return + + if node.left: + recurse(node.left) + else: + self.subtree.append(None) + + if node.right: + recurse(node.right) + else: + self.subtree.append(None) + + recurse(root) + + if self.selected: + self.subtree = [] + recurse(self.selected) + return self.subtree + else: + return None + """ + + diff --git a/ProblemSolving/searchMatrix/search.py b/ProblemSolving/searchMatrix/search.py new file mode 100644 index 0000000..f1b9d6d --- /dev/null +++ b/ProblemSolving/searchMatrix/search.py @@ -0,0 +1,32 @@ +class Solution: + # Logic 1: O(N) + O(M) + O(NM) iterations to fix the row and col indexes and then do restricted search with breaks + def searchMatrix(self, matrix: List[List[int]], target: int) -> bool: + + + rid = 0 + cid = 0 + + for i in range(len(matrix)): + if matrix[i][0] <= target: + rid += 1 + + for j in range(len(matrix[0])): + if matrix[0][j] <= target: + cid += 1 + + if rid == 0 and cid == 0 and matrix[0][0] == target: + return True + if not matrix: + return False + + for r in range(rid): + for c in range(cid): + print(r,c,matrix[r][c]) + if matrix[r][c] == target: + return True + elif matrix[r][c] > target: + break + else: + continue + + return False diff --git a/ProblemSolving/searchMatrix/search_prev.py b/ProblemSolving/searchMatrix/search_prev.py new file mode 100644 index 0000000..d4027d5 --- /dev/null +++ b/ProblemSolving/searchMatrix/search_prev.py @@ -0,0 +1,30 @@ +class Solution(object): + def searchMatrix(self, matrix, target): + """ + :type matrix: List[List[int]] + :type target: int + :rtype: bool + """ + selected_col = 0 + selected = False + row = 0 + for col in range(len(matrix[0])): + if matrix[row][col] > target: + selected_col = col-1 + selected = True + break + elif matrix[row][col] == target: + return True + #print(col) + if not selected: + selected_col = col + print(selected_col) + while selected_col >= 0: + for row in range(len(matrix)): + print(matrix[row][selected_col], selected_col) + if matrix[row][selected_col] == target: + return True + #elif matrix[row][selected_col] > target: + # return False + selected_col -= 1 + return False diff --git a/ProblemSolving/sentenceSimilarity/sen.py b/ProblemSolving/sentenceSimilarity/sen.py new file mode 100644 index 0000000..8814209 --- /dev/null +++ b/ProblemSolving/sentenceSimilarity/sen.py @@ -0,0 +1,37 @@ +class Solution(object): + def areSentencesSimilar(self, words1, words2, pairs): + """ + :type words1: List[str] + :type words2: List[str] + :type pairs: List[List[str]] + :rtype: bool + """ + + # Logic 1: Create relationship pairs and compare - 81% faster + + # Rule3: Same Length Words + if len(words1) != len(words2): + return False + + # Contruct relationship + pair = {} + for p in pairs: + if p[0] not in pair: + pair[p[0]] = set() + pair[p[0]].add(p[1]) + if p[1] not in pair: + pair[p[1]] = set() + pair[p[1]].add(p[0]) + + # Rule1,2: Iterate for Similarity + for p in range(len(words1)): + if not pair and words1[p] == words2[p]: + continue + elif (words1[p] in pair and words2[p] in pair[words1[p]]) or (words2[p] in pair and words1[p] in pair[words2[p]]): + continue + elif words1[p] == words2[p]: + continue + else: + print(p, words1[p], words2[p]) + return False + return True diff --git a/ProblemSolving/serializeAndDeserializeBST/serial.py b/ProblemSolving/serializeAndDeserializeBST/serial.py new file mode 100644 index 0000000..71a4e29 --- /dev/null +++ b/ProblemSolving/serializeAndDeserializeBST/serial.py @@ -0,0 +1,93 @@ +# Pending... + +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +# Logic: +# * Given a root,Lets use any one traversal technique (pre, post or in order) or level order and obtain a string (or any technique to traverse) +# * Given a string, Lets reverse the corresponding order we select and reconstruct the tree +# * Remember we do it state less so we dont store any variables + +class Codec: + + def serialize(self, root): + """Encodes a tree to a single string. + + :type root: TreeNode + :rtype: str + """ + + def pre_order_traverse(node, encode): + + if not node: + return + + if node.left and node.right: + encode += "/"+ str(node.val) + "L" + str(node.left.val) + "R" + str(node.right.val) + elif node.left: + encode += "/"+ str(node.val) + "L" + str(node.left.val) + elif node.right: + encode += "/"+ str(node.val) + "R" + str(node.right.val) + elif node: + encode += "/"+str(node.val) + + pre_order_traverse(node.left, encode) + pre_order_traverse(node.right, encode) + + return encode + + return pre_order_traverse(root, "") + + + def deserialize(self, data): + """Decodes your encoded data to tree. + + :type data: str + :rtype: TreeNode + """ + + def reverse_traversal_to_bst(node, sequence, root): + + if sequence and node == "": + subtree = list(sequence.pop(0)) + root = node = TreeNode(int(subtree.pop(0))) + if subtree and subtree[0] == "L": + subtree.pop(0) + node.left = TreeNode(int(subtree.pop(0))) + if subtree and subtree[0] == "R": + subtree.pop(0) + node.right= TreeNode(int(subtree.pop(0))) + + elif sequence and node.val == sequence[0]: + subtree = list(sequence.pop(0)) + subtree.pop(0) + if subtree and subtree[0] == "L": + subtree.pop(0) + node.left = TreeNode(int(subtree.pop(0))) + if subtree and subtree[0] == "R": + subtree.pop(0) + node.right= TreeNode(int(subtree.pop(0))) + + if node.left: + reverse_traversal_to_bst(node.left, sequence, root) + if node.right: + reverse_traversal_to_bst(node.right, sequence, root) + + return root + + if not data: + return [] + print data + return reverse_traversal_to_bst("", data.split("/")[1:], "") + + + + +# Your Codec object will be instantiated and called as such: +# codec = Codec() +# print codec.serialize(root) +# codec.deserialize(codec.serialize(root)) diff --git a/ProblemSolving/shortEncodingOfWords/short.py b/ProblemSolving/shortEncodingOfWords/short.py new file mode 100644 index 0000000..de590db --- /dev/null +++ b/ProblemSolving/shortEncodingOfWords/short.py @@ -0,0 +1,30 @@ +class Solution(object): + def minimumLengthEncoding(self, words): + """ + :type words: List[str] + :rtype: int + """ + + encoded_string = "" + + for word in sorted(words, key=lambda x: len(x), reverse=True): + # One other thing to check is, if the substring is such that # occurs rather than ...# (which is not correct)! + if word+"#" not in encoded_string: + encoded_string += word + "#" + + return len(encoded_string) + + """ + # Logic to satisfy literally the indexes and encoded string, as the length is only required - no need to calculate the indexes + encoded_string = "" + indexes = [] + + # Sort array with length in the decreasing order + for word in sorted(words, key=lambda x: len(x), reverse=True): + if word+"#" in encoded_string: + indexes.append(encoded_string.index(word)) + else: + encoded_string += word + "#" + + return len(encoded_string) + """ diff --git a/ProblemSolving/shortEncodingOfWords/short2.py b/ProblemSolving/shortEncodingOfWords/short2.py new file mode 100644 index 0000000..fa4d138 --- /dev/null +++ b/ProblemSolving/shortEncodingOfWords/short2.py @@ -0,0 +1,24 @@ +class Solution: + def minimumLengthEncoding(self, words: List[str]) -> int: + + # Logic 1: 2 O(len(words)) iteration with O(sum(words)) iteration to create substrings - 88% faster + substrings = {} + encoded = 0 + + # Iteration 1 to store substrings + for w in words: + i = 1 # avoid adding full word for now + while i < len(w): + curr_subs = w[i:] + substrings[w[i:]] = True + i += 1 + + # Iteration 2 to check intersection (substring) + for w in words: + if w not in substrings: + encoded += len(w) + 1 + substrings[w] = True # update with full word + + return encoded + + diff --git a/ProblemSolving/shortestCompletingWord/short.py b/ProblemSolving/shortestCompletingWord/short.py new file mode 100644 index 0000000..da6df9b --- /dev/null +++ b/ProblemSolving/shortestCompletingWord/short.py @@ -0,0 +1,86 @@ +class Solution(object): + def shortestCompletingWord(self, licensePlate, words): + """ + :type licensePlate: str + :type words: List[str] + :rtype: str + """ + + # Logic 3: + # * Dictionary compare + + import collections + + license = collections.Counter([str(i.lower()) for i in licensePlate if not i.isdigit() and i != " "]) + result = "" + + for word in words: + word_count = collections.Counter(word.lower()) + decide = 0 + for character in license.keys(): + if character not in word_count or license[character] > word_count[character]: + decide = 1 + #print character, license[character], word_count[character], decide + if decide == 0: + if result == "": + result = word + else: + if len(word) < len(result): + result = word + return result + + # Logic 2: Sorted Match Logic: But fails when the characters not present in one of the string sort becomes wrong + """ + # Sanitize licensePlate + # * Lowercase + # * not digit + # * sorted order to match + license = str("".join(sorted([str(char.lower()) for char in licensePlate if not char.isdigit() and char != " "]))) + + result = "" + + # iterate through words for a substring match + for word in words: + current = str("".join(sorted(word.lower()))) + if license in current: + if result == "": + result = word + else: + if len(word) < len(result): + result = word + return result + """ + + # Logic1: O(NM) - to iterate on both licenseplate and words + # * One full iteration of the array to find the minimum length that contains all the letters + #### CRAP............ + """ + result = [] + result_mini = "" + + # Iterate the words + for word in words: + + # Lowercase the word as per instructons + current = list(word.lower()) + temp = list(licensePlate.lower()) + + # Iterate licensePlate to match all characters of the word + for i in range(len(temp)): + for j in range(len(current)): + if not temp[i].isdigit() and temp[i] == current[j]: + if (i, j) not in result: + result.append((i,j)) + + # LicensePlate match + if not temp: + if result_mini == "": + result_mini = len(current) + else: + result_mini = min(result_mini, len(current)) + + return result_mini + """ + + + diff --git a/ProblemSolving/shortestPathInBinaryMatrix/short.py b/ProblemSolving/shortestPathInBinaryMatrix/short.py new file mode 100644 index 0000000..1f73127 --- /dev/null +++ b/ProblemSolving/shortestPathInBinaryMatrix/short.py @@ -0,0 +1,44 @@ +class Solution: + def shortestPathBinaryMatrix(self, grid: List[List[int]]) -> int: + + + def backtrack(current, path, visited): + #print(path) + + i, j = current + + if self.min != float('inf') and path > self.min: + return + + if i == self.max_row-1 and j == self.max_col-1: + if self.min > path: + self.min = path + return + + for m in self.dirs: + for n in self.dirs: + a = i+m + b = j+n + if (m==0 and n==0): + continue + if a >= self.max_row or a < 0: + continue + if b >= self.max_col or b < 0: + continue + if grid[a][b] == 0 and (a,b) not in visited: + backtrack((a,b), path+1, visited.union({(a,b)})) + return + + + if grid[0][0] != 0 or grid[-1][-1] != 0: + return -1 + + self.min = float('inf') + self.max_row = len(grid) + self.max_col = len(grid[0]) + self.dirs = [-1, 0, 1] + #backtrack((0,0), [(0,0)], set((0,0))) + backtrack((0,0), 1, set((0,0))) + if self.min == float('inf'): + return -1 + return self.min diff --git a/ProblemSolving/shortestWordDistance/short.go b/ProblemSolving/shortestWordDistance/short.go new file mode 100644 index 0000000..6b5f503 --- /dev/null +++ b/ProblemSolving/shortestWordDistance/short.go @@ -0,0 +1,26 @@ +func shortestDistance(words []string, word1 string, word2 string) int { + // Logic 1: Naive O(N) - 100% fast + n := len(words) + var index1 int + var index2 int + shortest := 65535 + for i:=0;i 0 && index2 > 0 { + if index1-index2 > 0 && index1-index2 < shortest { + shortest = index1 - index2 + } + if index2-index1 > 0 && index2-index1 < shortest { + shortest = index2 -index1 + } + } + } + return shortest +} diff --git a/ProblemSolving/shortestWordDistance/short.py b/ProblemSolving/shortestWordDistance/short.py new file mode 100644 index 0000000..424ee34 --- /dev/null +++ b/ProblemSolving/shortestWordDistance/short.py @@ -0,0 +1,22 @@ +class Solution: + def shortestDistance(self, wordsDict: List[str], word1: str, word2: str) -> int: + + last_seen_1 = None + last_seen_2 = None + + mini = len(wordsDict) + + for i in range(len(wordsDict)): + + if wordsDict[i] == word1: + last_seen_1 = i + + if wordsDict[i] == word2: + last_seen_2 = i + + if last_seen_1 != None and last_seen_2 != None: + if abs(last_seen_1-last_seen_2) < mini: + mini = abs(last_seen_1-last_seen_2) + + return mini + diff --git a/ProblemSolving/shuffleAnArray/shuffle2.py b/ProblemSolving/shuffleAnArray/shuffle2.py new file mode 100644 index 0000000..dc51992 --- /dev/null +++ b/ProblemSolving/shuffleAnArray/shuffle2.py @@ -0,0 +1,21 @@ +import random +class Solution: + + def __init__(self, nums: List[int]): + self.n = nums[:] + self.comb = nums[:] + + def reset(self) -> List[int]: + return self.n + + def shuffle(self) -> List[int]: + i = random.randint(0, len(self.n)-1) + j = random.randint(0, len(self.n)-1) + self.comb[i], self.comb[j] = self.comb[j], self.comb[i] + return self.comb + + +# Your Solution object will be instantiated and called as such: +# obj = Solution(nums) +# param_1 = obj.reset() +# param_2 = obj.shuffle() diff --git a/ProblemSolving/shuffleString/str.py b/ProblemSolving/shuffleString/str.py new file mode 100644 index 0000000..a2ddc8e --- /dev/null +++ b/ProblemSolving/shuffleString/str.py @@ -0,0 +1,20 @@ +# Logic 1: convert indices::char to dictionary and iterate once --> 100 pass 20% faster +class Solution: + def restoreString(self, s: str, indices: List[int]) -> str: + + mapIndexToChar = {} + x = 0 + n = len(indices) + result = "" + + while x < n: + mapIndexToChar[indices[x]] = s[x] + x += 1 + + x = 0 + while x < n: + #print(x, mapIndexToChar[x]) + result += mapIndexToChar[x] + x += 1 + + return result diff --git a/ProblemSolving/shuffleTheArray/shuffle.py b/ProblemSolving/shuffleTheArray/shuffle.py new file mode 100644 index 0000000..67ecafd --- /dev/null +++ b/ProblemSolving/shuffleTheArray/shuffle.py @@ -0,0 +1,25 @@ +# Logic 1: 2 pointers - 72% +""" +class Solution: + def shuffle(self, nums: List[int], n: int) -> List[int]: + i = 0 + j = n # or len(nums)//2 + result = [] + while i < n and j < len(nums): + result.append(nums[i]) + result.append(nums[j]) + i += 1 + j += 1 + return result +""" + +# Logic 2: Same logic above, Reducing to one var +class Solution: + def shuffle(self, nums: List[int], n: int) -> List[int]: + i = 0 + result = [] + while i < n: + result.append(nums[i]) + result.append(nums[n+i]) + i += 1 + return result diff --git a/ProblemSolving/simplifyPath/sim2.go b/ProblemSolving/simplifyPath/sim2.go new file mode 100644 index 0000000..ca74bfa --- /dev/null +++ b/ProblemSolving/simplifyPath/sim2.go @@ -0,0 +1,60 @@ +// Logic 2: Repeated same python logic here - 100% faster +import ( + "fmt" + "strings" +) +func simplifyPath(path string) string { + stack := []string{} + elements := strings.Split(path, "/") // Neglect all slahes and add them later + for _, val := range elements { + if val == ".." { // Double .. case + if len(stack) > 0 { + stack = stack[:len(stack)-1] + } + } else if (val == "." || val == "") { + continue + } else { + stack = append(stack, string(val)) + } + } + fmt.Println(stack) + return "/" + strings.Join(stack, "/") +} + +/* +// Fail - this does not work - some confusion with the problem statement +import ( + "fmt" +) +func simplifyPath(path string) string { + var stack string + for index, value := range path { + if (len(stack) > 0 && value == '/' && stack[len(stack)-1] == '/') { // Eradicate multiple consecutive slashes + continue + } else if ( value == '.' && index+1 < len(path) && path[index+1] == '.') { // Double dot case, pop the last directory + if (len(stack) > 0 && stack[len(stack)-1] == '/') { + stack = stack[:len(stack)-1] // remove slash if any + } + if len(stack) > 0 { + stack = stack[:len(stack)-1] // remove the last directory + } + index += 1 + } else { // Append everything else that passed allowlist + if value == '.' { + + } else { + stack = stack + string(value) + } + } + } + if (len(stack) > 1) { + for stack[len(stack)-1] == '/' { + stack = stack[:len(stack)-1] + } + } + if len(stack) == 0 { + stack = string('/') + } + return stack +} +*/ diff --git a/ProblemSolving/simplifyPath/sim2.py b/ProblemSolving/simplifyPath/sim2.py new file mode 100644 index 0000000..fb1be06 --- /dev/null +++ b/ProblemSolving/simplifyPath/sim2.py @@ -0,0 +1,13 @@ +# Logic 1: 100 pass - 81% faster - Straighforward without considering a number of complex cases makes this pass. Just take care of .. or . alone. Considering /... kind of confuses the situation +class Solution: + def simplifyPath(self, path: str) -> str: + stack = [] # Container to hold the answer, should start with / + no_entries = set(["", "..", "."]) # No entries in result with respect to these values + elements = path.split("/") # Split by hashes to remove single or multiple hash + for ele in elements: + if stack and ele == "..": # indicates we should go back on dir + stack.pop() + elif ele not in no_entries: + stack.append(ele) + stack = "/" + "/".join(stack) + return stack diff --git a/ProblemSolving/simplifyPath/sim3.py b/ProblemSolving/simplifyPath/sim3.py new file mode 100644 index 0000000..2092041 --- /dev/null +++ b/ProblemSolving/simplifyPath/sim3.py @@ -0,0 +1,22 @@ +class Solution: + def simplifyPath(self, path: str) -> str: + + stack = [] + + dirSeparator = "/" + moveUpDir = ".." + currentDir = "." + + pathDirs = path.split(dirSeparator) + + for i in range(len(pathDirs)): + if pathDirs[i] == dirSeparator or pathDirs[i] == currentDir: + pass + elif pathDirs[i] == moveUpDir: + if stack: + stack.pop() + else: + if pathDirs[i]: + stack.append(pathDirs[i]) + + return dirSeparator + dirSeparator.join(stack) diff --git a/ProblemSolving/singleNumber/single2.py b/ProblemSolving/singleNumber/single2.py new file mode 100644 index 0000000..e963e92 --- /dev/null +++ b/ProblemSolving/singleNumber/single2.py @@ -0,0 +1,27 @@ + def singleNumber(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + + # No Space + nums.sort() + freq = 1 + for i in range(len(nums)): + if i+1 < len(nums) and nums[i+1] == nums[i]: + freq += 1 + else: + print(nums[i], freq) + if freq == 1: + return nums[i] + freq = 1 + return False + + # Extra Space + """ + import collections + for k,v in collections.Counter(nums).items(): + if v == 1: + return k + return False + """ diff --git a/ProblemSolving/singleNumberII/single.py b/ProblemSolving/singleNumberII/single.py new file mode 100644 index 0000000..4083034 --- /dev/null +++ b/ProblemSolving/singleNumberII/single.py @@ -0,0 +1,11 @@ +class Solution(object): + def singleNumber(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + + # Sum method + return (3*sum((set(nums))) - sum(nums))//2 + + # diff --git a/ProblemSolving/singleNumberIII/single.py b/ProblemSolving/singleNumberIII/single.py new file mode 100644 index 0000000..2b9e1b8 --- /dev/null +++ b/ProblemSolving/singleNumberIII/single.py @@ -0,0 +1,33 @@ +class Solution(object): + def singleNumber(self, nums): + """ + :type nums: List[int] + :rtype: List[int] + """ + + ### List method - O(N) but the look up for count in a list might increase the iteration + # 100 pass but runs for 2796ms faster than 1.5% + return [i for i in nums if nums.count(i) == 1] + # -------------------------------------------------------------------------------------- + + ### Double Remove method + # * For each element, remove the element from the list and also remove the same element from the list again, if not it is unique + # * Remove element operation would take more than a linear iteration... + # -------------------------------------------------------------------------------------- + + ### Dictionary method + # - uses extra space - would always pass but that is not what we want! + # -------------------------------------------------------------------------------------- + + ### Exor Method + # * Iterate through numbers, continuously exor + # - Exor one by one, check for value change before and after + # - If the amount added is the amount removed, then + + + + + + + + diff --git a/ProblemSolving/singleRowKeyboard/single.py b/ProblemSolving/singleRowKeyboard/single.py new file mode 100644 index 0000000..818f748 --- /dev/null +++ b/ProblemSolving/singleRowKeyboard/single.py @@ -0,0 +1,56 @@ +class Solution: + def calculateTime(self, keyboard: str, word: str) -> int: + + # Logic 1: Create a dictionary to store the indexes of characters and then calculate the distance after hitting first character 99% faster + + # * Create a dictionary + alpha = {} + for i in range(len(keyboard)): + alpha[keyboard[i]] = i + + # * Iterate a find time + time = 0 + last_index = 0 + for char in word: + time += abs(alpha[char]-last_index) + last_index = alpha[char] + + return time + + + # Logic 2: Using in built index functionf or list --> 70% faster + """ + time = 0 + last_index = 0 + for char in word: + index = keyboard.index(char) + time += abs(index-last_index) + last_index = index + return time + """ + + # Logic 3: the alphabets are contiguous A..Z use this to your own idea --> assumption was wrong.... it is not contiguous + """ + + # Keyboard has contiguous characters with some shift or any charac of start --> Know the shift first + + shift = ord(keyboard[0]) # This would be the start index or start characters ascii value, use this as index 0 for the array + + def num_to_char(num): + while num >= 26: + num -= 26 + return chr(num) + + time = 0 + last_index = 0 + for char in word: + char_ord = ord(char)-shift + #print(char_ord, ord(char), shift) + if char_ord < 0: + char_ord = 26+char_ord + time += abs(char_ord-last_index) + last_index = char_ord + #if char != keyboard[last_index]: + print(keyboard[last_index], char, last_index) + return time + """ diff --git a/ProblemSolving/slowestKey/slow.py b/ProblemSolving/slowestKey/slow.py new file mode 100644 index 0000000..aff8f3b --- /dev/null +++ b/ProblemSolving/slowestKey/slow.py @@ -0,0 +1,22 @@ +# Logic 1: Naive method of O(N) iteration on releastTimes + sort --> 89% faster +class Solution: + def slowestKey(self, releaseTimes: List[int], keysPressed: str) -> str: + longest_duration = 0 + keys = [] + + for r in range(len(releaseTimes)): + # Calc duration + if r-1 < 0: + duration = releaseTimes[r] + else: + duration = releaseTimes[r] - releaseTimes[r-1] + + # Assess longest duration + if duration > longest_duration: + longest_duration = duration + keys = [keysPressed[r]] + elif duration == longest_duration: + keys.append(keysPressed[r]) + + keys.sort() + return keys[-1] diff --git a/ProblemSolving/smallestStringStartingFromLeaf/small.py b/ProblemSolving/smallestStringStartingFromLeaf/small.py new file mode 100644 index 0000000..b65ed61 --- /dev/null +++ b/ProblemSolving/smallestStringStartingFromLeaf/small.py @@ -0,0 +1,72 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def smallestFromLeaf(self, root): + """ + :type root: TreeNode + :rtype: str + """ + + # Logic1: Recursive with No Extra space - 1 --> as of now 100% faster and less than 100% memory + + # Function to convert the number into alphabet + def number_to_alphabet(num): + # lowercase a ==> ord('a') = 97, so iterate from there + return chr(97+num) + + # Recursively traverse until the leaf nodes + def traverse(node, string): + + # At the leaf node, add the string from the lead to root to the strings list + # * Reverse string constructed to reverse order from root -> leaf and add the leaf character beginning + if node: + if not node.left and not node.right: + return number_to_alphabet(node.val)+string[::-1] + else: + # Compare left and right for minimum lexico, else return left or right + left = traverse(node.left, string+number_to_alphabet(node.val)) + right = traverse(node.right, string+number_to_alphabet(node.val)) + if left and right: + return min(left, right) + elif left: + return left + else: + return right + + + # Logic2: Recursive with Extra space to hold the strings - as of now 100% faster and less than 100% memory + # * Sort the list to obtain the answer finally + + # Recursively traverse until the leaf nodes + def traverse2(node, string): + + # At the leaf node, add the string from the lead to root to the strings list + # * Reverse string constructed to reverse order from root -> leaf and add the leaf character beginning + if node: + if not node.left and not node.right: + self.strings.append(number_to_alphabet(node.val)+string[::-1]) + else: + traverse(node.left, string+number_to_alphabet(node.val)) + traverse(node.right, string+number_to_alphabet(node.val)) + + + # ** Logic1: + # Trigger + return traverse(root, "") + + # ** Logic2: + + # List to hold all strings + #self.strings = [] + + # Trigger it + #traverse2(root, "") + + # Sort and return the first + #return sorted(self.strings)[0] + diff --git a/ProblemSolving/snapshotArray/snap.py b/ProblemSolving/snapshotArray/snap.py new file mode 100644 index 0000000..028ee64 --- /dev/null +++ b/ProblemSolving/snapshotArray/snap.py @@ -0,0 +1,109 @@ +# Logic 1: naive method of utilizing memory to store copies of arrays +""" +class SnapshotArray: + + def __init__(self, length: int): + self.array = [0]*length + self.snaps = [] + + def set(self, index: int, val: int) -> None: + self.array[index] = val + return + + def snap(self) -> int: + self.snaps.append(self.array[:]) + return len(self.snaps)-1 + + def get(self, index: int, snap_id: int) -> int: + if snap_id >= len(self.snaps): + return 0 + return self.snaps[snap_id][index] + + +# Your SnapshotArray object will be instantiated and called as such: +# obj = SnapshotArray(length) +# obj.set(index,val) +# param_2 = obj.snap() +# param_3 = obj.get(index,snap_id) +""" + +# Logic 2: save snapshot of changes everytime - time limit exceeded +""" +class SnapshotArray: + + def __init__(self, length: int): + self.array = [0]*length + self.snaps = [] + self.changes = {} + + def set(self, index: int, val: int) -> None: + self.changes[index] = val + self.array[index] = val + return + + def snap(self) -> int: + # save only the difference + # compute difference + self.snaps.append(self.changes.copy()) + self.changes = {} + return len(self.snaps) - 1 + + def get(self, index: int, snap_id: int) -> int: + if snap_id >= len(self.snaps): + return 0 + initial = 0 + for i in range(snap_id+1): + if index not in self.snaps[i]: + continue + initial = self.snaps[i][index] + return initial + + +# Your SnapshotArray object will be instantiated and called as such: +# obj = SnapshotArray(length) +# obj.set(index,val) +# param_2 = obj.snap() +# param_3 = obj.get(index,snap_id) +""" + +# Logic 3: for each element at index track the changes through the snaps +class SnapshotArray: + + def __init__(self, length: int): + self.changes = {} + self.snaps_of_elements = {} + self.snaps = 0 + + def set(self, index: int, val: int) -> None: + self.changes[index] = val + return + + def snap(self) -> int: + for ind, val in self.changes.items(): + if ind not in self.snaps_of_elements: + self.snaps_of_elements[ind] = [] + self.snaps_of_elements[ind].append([self.snaps, val]) + self.changes = {} + self.snaps += 1 + return self.snaps - 1 + + def get(self, index: int, snap_id: int) -> int: + if index not in self.snaps_of_elements: + return 0 + last_val = 0 + #print(self.snaps_of_elements, snap_id) + for snaps in self.snaps_of_elements[index]: + snap, val = snaps + if snap > snap_id: + return last_val + elif snap == snap_id: + return val + last_val = val + return last_val + + +# Your SnapshotArray object will be instantiated and called as such: +# obj = SnapshotArray(length) +# obj.set(index,val) +# param_2 = obj.snap() +# param_3 = obj.get(index,snap_id) diff --git a/ProblemSolving/sortAnArray/sort.py b/ProblemSolving/sortAnArray/sort.py new file mode 100644 index 0000000..33faddf --- /dev/null +++ b/ProblemSolving/sortAnArray/sort.py @@ -0,0 +1,68 @@ +class Solution(object): + def sortArray(self, nums): + """ + :type nums: List[int] + :rtype: List[int] + """ + + # Inbuilt function + ## return sorted(nums) + + # Quick sort + def quickSort(array): + less = [] + equal = [] + greater = [] + if len(array) > 1: + pivot = array[0] + for i in array: + if i < pivot: + less.append(i) + elif i == pivot: + equal.append(i) + else: + greater.append(i) + return quickSort(less)+equal+quickSort(greater) + else: + return array + return quickSort(nums) + + # Merge sort way + """ + def mergeSort(array): + if len(array) > 1: + n = len(array)//2 + left = array[:n] + right = array[n:] + + mergeSort(left) + mergeSort(right) + + i = j = k = 0 + + while i < len(left) and j < len(right): + if left[i] < right[j]: + array[k] = left[i] + i += 1 + else: + array[k] = right[j] + j += 1 + k += 1 + + while i < len(left): + array[k] = left[i] + i += 1 + k += 1 + + while j < len(right): + array[k] = right[j] + j += 1 + k += 1 + + return array + + mergeSort(nums) + return nums + """ + + diff --git a/ProblemSolving/sortArrayByParity/parity2.py b/ProblemSolving/sortArrayByParity/parity2.py new file mode 100644 index 0000000..42b421f --- /dev/null +++ b/ProblemSolving/sortArrayByParity/parity2.py @@ -0,0 +1,20 @@ +class Solution: + def sortArrayByParity(self, nums: List[int]) -> List[int]: + + + last_odd = None + + for i in range(len(nums)): + + if nums[i]%2 != 0: + if last_odd == None: + last_odd = i + else: + print(last_odd, i) + if last_odd == None: + continue + nums[i], nums[last_odd] = nums[last_odd], nums[i] + last_odd += 1 + + return nums + diff --git a/ProblemSolving/sortColors/sort.py b/ProblemSolving/sortColors/sort.py new file mode 100644 index 0000000..cc34b56 --- /dev/null +++ b/ProblemSolving/sortColors/sort.py @@ -0,0 +1,51 @@ +class Solution(object): + def sortColors(self, nums): + """ + :type nums: List[int] + :rtype: None Do not return anything, modify nums in-place instead. + """ + + # O(2N) + + temp = None + for i in range(len(nums)): + if nums[i] == 0: + if temp != None: + nums[i], nums[temp] = nums[temp], nums[i] + temp += 1 + else: + if temp == None: + temp = i + + print(nums) + temp1 = None + for i in range(len(nums)): + if nums[i] == 1:# and nums[temp1] != 0: + if temp1 != None and nums[temp1] != 0: + nums[i], nums[temp1] = nums[temp1], nums[i] + temp1 += 1 + elif nums[i] == 2: + if temp1 == None: + temp1 = i + + return nums + + """ + temp = 0 + temp1 = 0 + + for i in range(len(nums)): + if nums[i] == 0: + nums[i], nums[temp] = nums[temp], nums[i] + temp += 1 + temp1 += 1 + elif nums[i] == 1: + nums[i], nums[temp1] = nums[temp1], nums[i] + temp1 = temp + 1 + else: + if temp == 0: + temp = i + temp1 = temp + 1 + print nums + return nums + """ diff --git a/ProblemSolving/specialArray/special.py b/ProblemSolving/specialArray/special.py new file mode 100644 index 0000000..67d7778 --- /dev/null +++ b/ProblemSolving/specialArray/special.py @@ -0,0 +1,21 @@ +class Solution(object): + def isArraySpecial(self, nums): + """ + :type nums: List[int] + :rtype: bool + """ + + def getParity(num): + if num%2 == 0: + return True + return False + + if len(nums) == 1: + return True + + for i in range(1, len(nums)): + if getParity(nums[i-1]) == getParity(nums[i]): + return False + return True + + diff --git a/ProblemSolving/spiralMatrix1/spiral.py b/ProblemSolving/spiralMatrix1/spiral.py new file mode 100644 index 0000000..61cef0e --- /dev/null +++ b/ProblemSolving/spiralMatrix1/spiral.py @@ -0,0 +1,53 @@ +class Solution(object): + def spiralOrder(self, matrix): + + # Logic 1: Naive Iteration into Spiral mode + # Ref here: https://leetcode.com/problems/spiral-matrix/discuss/20599/Super-Simple-and-Easy-to-Understand-Solution nice logic + + if len(matrix) == 0: + return [] + + # Row start & end + rowStart = 0 + rowEnd = len(matrix)-1 + + # Column start & end + columnStart = 0 + columnEnd = len(matrix[0])-1 + + result = [] + + while (rowStart <= rowEnd) and (columnStart <= columnEnd): + + # Traverse right columns 00 -> 0n + for i in range(columnStart, columnEnd+1): + result.append(matrix[rowStart][i]) + + # Corner elements are visited twice handle them + rowStart += 1 + + # Traverse down rows 0n -> nn + for i in range(rowStart, rowEnd+1): + result.append(matrix[i][columnEnd]) + + # Corner elements are visited twice handle them + columnEnd -= 1 + + if rowStart <= rowEnd: + # Traverse left columns nn -> n0 + for i in range(columnEnd, columnStart-1, -1): + result.append(matrix[rowEnd][i]) + + # Corner elements are visited twice handle them + rowEnd -= 1 + + if columnStart <= columnEnd: + # Traverse up row n0 -> 00 (but 10) + for i in range(rowEnd, rowStart-1, -1): + result.append(matrix[i][columnStart]) + + # Corner elements are visited twice handle them + columnStart += 1 + + return result + diff --git a/ProblemSolving/spiralMatrix2/spiral.py b/ProblemSolving/spiralMatrix2/spiral.py new file mode 100644 index 0000000..3e195c5 --- /dev/null +++ b/ProblemSolving/spiralMatrix2/spiral.py @@ -0,0 +1,162 @@ +class Solution(object): + def generateMatrix(self, n): + """ + :type n: int + :rtype: List[List[int]] + """ + + # Logic 1: Create a nxn matrix and use the same logic to traverse as in the spiral matrix 1 + + # create a nxn matrix + matrix = [[0 for i in range(n)] for j in range(n)] + + # Row start & end + rowStart = 0 + rowEnd = len(matrix)-1 + + # Column start & end + columnStart = 0 + columnEnd = len(matrix[0])-1 + count = 0 + + while (rowStart <= rowEnd) and (columnStart <= columnEnd): + + # Traverse right columns 00 -> 0n + for i in range(columnStart, columnEnd+1): + count += 1 + matrix[rowStart][i] = count + + # Corner elements are visited twice handle them + rowStart += 1 + + # Traverse down rows 0n -> nn + for i in range(rowStart, rowEnd+1): + count += 1 + matrix[i][columnEnd] = count + + # Corner elements are visited twice handle them + columnEnd -= 1 + + if rowStart <= rowEnd: + # Traverse left columns nn -> n0 + for i in range(columnEnd, columnStart-1, -1): + count += 1 + matrix[rowEnd][i] = count + + # Corner elements are visited twice handle them + rowEnd -= 1 + + if columnStart <= columnEnd: + # Traverse up row n0 -> 00 (but 10) + for i in range(rowEnd, rowStart-1, -1): + count += 1 + matrix[i][columnStart] = count + + # Corner elements are visited twice handle them + columnStart += 1 + + return matrix +""" +# My Old contest logic that did not work + grid = [[0 for i in range(n)] for i in range(n)] + + # 0,0 -> 0,1 -> 0,2 -> 1,2 -> 2,2 -> 2,1 -> 2,0 + + i = j = 0 + + # I's turn is True and J's turn is False + turn = False + + # to control loop + count = 0 + value = 0 + grid[0][0] = value + time = 1 + + while count < n**2: + + print(i,j,time) + if time%2 != 0: + for x in range(j, n): + if grid[i][x] == 0: + value += 1 + print(i,x, value) + grid[i][x] = value + count += 1 + else: + j = x + break + + if j == 0: + j = n-1 + i += 1 + + for y in range(i, n): + if grid[y][j] == 0: + value += 1 + print(y, j, value) + grid[y][j] = value + count += 1 + else: + i = y + break + if i == 0: + print("adsada") + i = n-1 + j -= 1 + else: + print("hi", i, j ) + for x in range(j, -1, -1): + if grid[i][x] == 0: + value += 1 + print(i, x, value) + grid[i][x] = value + count += 1 + else: + j = x + break + i -= 1 + for y in range(i, -1, -1): + if grid[y][j] == 0: + value += 1 + print(y, j, value) + grid[y][j]= value + count += 1 + else: + i = y + break + time += 1 + print(grid) + + """ + if j == n-1 and i == n-1: + turn = False + elif j == n-1: + turn = True + elif j == 0: + turn = True + else: + turn = False + + if turn == False: + if i == n-1: + j -= 1 + else: + j += 1 + else: + if j == 0: + i -= 1 + else: + i += 1 + + value += 1 + print(i,j, value) + grid[i][j] = value -1 + + count += 1 + """ + + return grid + + +""" diff --git a/ProblemSolving/splitListToParts/split.py b/ProblemSolving/splitListToParts/split.py new file mode 100644 index 0000000..d46ef03 --- /dev/null +++ b/ProblemSolving/splitListToParts/split.py @@ -0,0 +1,44 @@ +class Solution(object): + def splitListToParts(self, root, k): + """ + :type root: ListNode + :type k: int + :rtype: List[ListNode] + """ + + nodes = [] + + # Linked list traversal + while root: + nodes.append(root.val) + root = root.next + + n = len(nodes) + + result = [] + + if n == 0: + return [[]*(k)] + + # Equal parts + if n%k == 0: + divide = n//k + while nodes: + result.append(nodes[:divide]) + nodes = nodes[divide:] + else: + if n < k: + divide = 1 + while nodes: + result.append(nodes[:divide]) + nodes = nodes[divide:] + while len(result) < k: + result.append([]) + else: + divide = k + while len(nodes) > divide: + result = nodes[-divide:] + result + nodes = nodes[:divide] + result = nodes + result + + return result diff --git a/ProblemSolving/splitStringIntoBalancedStrings/split.py b/ProblemSolving/splitStringIntoBalancedStrings/split.py new file mode 100644 index 0000000..5d7355f --- /dev/null +++ b/ProblemSolving/splitStringIntoBalancedStrings/split.py @@ -0,0 +1,29 @@ +class Solution(object): + def balancedStringSplit(self, s): + """ + :type s: str + :rtype: int + """ + + # Logic 1: O(N) iterate and slice --> 100% faster + left = 0 + right = 0 + result = [] + i = 0 + while i < len(s): + if s and s[i] == "L": + left += 1 + i += 1 + elif s: + right += 1 + i += 1 + if left != 0 and left == right: + result.append(s[:i]) + s = s[i:] + left = right = 0 + i = 0 + return len(result) + + + # Logic 2: Use a stack --> this would require balance check on the stack every time + diff --git a/ProblemSolving/squaresOfASortedArray/square.py b/ProblemSolving/squaresOfASortedArray/square.py new file mode 100644 index 0000000..6a48c6d --- /dev/null +++ b/ProblemSolving/squaresOfASortedArray/square.py @@ -0,0 +1,32 @@ +class Solution(object): + def sortedSquares(self, A): + """ + :type A: List[int] + :rtype: List[int] + """ + + # This works but we want the squares in the result + #return sorted(A, key= lambda x: x**2) + + # Logic 1: 100 pass + #return sorted(map(lambda x: x**2, A)) + + # Logic 2 + # Naive iterative without built in functions + result = [] + for i in range(len(A)): + square = A[i]**2 + n = len(result) + if n == 0: + result.append(square) + else: + j = 0 + while j < n: + if result[j] > square: + result = result[:j] + [square] + result[j:] + break + j += 1 + #print j, result, A[i], square + if j == n and len(result) == n: + result.append(square) + return result diff --git a/ProblemSolving/squaresOfASortedArray/square2.py b/ProblemSolving/squaresOfASortedArray/square2.py new file mode 100644 index 0000000..99795fa --- /dev/null +++ b/ProblemSolving/squaresOfASortedArray/square2.py @@ -0,0 +1,52 @@ +class Solution(object): + def sortedSquares(self, A): + """ + :type A: List[int] + :rtype: List[int] + """ + + + # Logic 1: 100 pass + #return map(lambda x:x**2, sorted(A, key= lambda x: x**2)) + + # Logic 2: 100 pass + #return sorted(map(lambda x: x**2, A)) + + # Logic 3 - Time limit exceeded + # Naive iterative without built in functions + """ + result = [] + for i in range(len(A)): + square = A[i]**2 + n = len(result) + if n == 0: + result.append(square) + else: + j = 0 + while j < n: + if result[j] > square: + result = result[:j] + [square] + result[j:] + break + j += 1 + #print j, result, A[i], square + if j == n and len(result) == n: + result.append(square) + return result + """ + + # Logic 4 - 100 pass + # 2 pointer technique + + left = 0 + right = len(A)-1 + i = len(A)-1 + result = [0]*len(A) + while i >= 0: + if abs(A[left]) > abs(A[right]): + result[i] = A[left]**2 + left += 1 + else: + result[i] = A[right]**2 + right -= 1 + i -= 1 + return result diff --git a/ProblemSolving/stoneGame/stone.py b/ProblemSolving/stoneGame/stone.py new file mode 100644 index 0000000..3c2522f --- /dev/null +++ b/ProblemSolving/stoneGame/stone.py @@ -0,0 +1,41 @@ +class Solution(object): + def stoneGame(self, piles): + """ + :type piles: List[int] + :rtype: bool + """ + # lt medium 100 pass + # Logic: Recursive method of alex choosing the winning option + # * Go both ways of how lee will respond + def recurse_for_all_options(piles, alex, lee): + + # Null check - Game over condition for alex to win + if not piles: + if alex > lee: + return True + else: + return False + + # Alex turn - Assume alex always takes maximum to win + # * Max pile in the front of the list + if piles[0] > piles[-1]: + piles = piles[1:] + alex += piles[0] + elif piles[0] == piles[-1]: + # when both the front and end are equal, check the next option to maximize + if len(piles) >= 4 and piles[1] > piles[-2]: + alex += piles[-1] + piles = piles[:-1] + else: + alex += piles[0] + piles = piles[1:] + else: + # Max pile in the end of the list + alex += piles[-1] + piles = piles[:-1] + + # Lee's turn - Assume lee takes anything first or last so recurse both the option he takes + # * Or condition to check if Alex wins atleast once + return recurse_for_all_options(piles[:][1:], alex, lee+piles[:][0]) or recurse_for_all_options(piles[:][:-1], alex, lee+piles[:][-1]) + + return recurse_for_all_options(piles, 0, 0) diff --git a/ProblemSolving/stringCompression/str2.py b/ProblemSolving/stringCompression/str2.py new file mode 100644 index 0000000..38365af --- /dev/null +++ b/ProblemSolving/stringCompression/str2.py @@ -0,0 +1,54 @@ +class Solution(object): + def compress(self, chars): + """ + :type chars: List[str] + :rtype: int + """ + + # Logic 1: 2 pointer method - inplace replacement is the only way you could do this... + + select = 0 + i = 1 + n = len(chars) + + length = 1 + + while i < n: + + count = 1 + + while i < n and chars[i] == chars[select]: + count += 1 + i += 1 + + if count > 1: + count = str(count) + for dig in count: + select += 1 + chars[select] = dig + length += 1 + + if i < n: + select += 1 + chars[select] = chars[i] + length += 1 + i += 1 + + return length + + # Below logic uses extra space + """ + result = [] + while chars: + if not result: + result.append(chars.pop(0)) + result.append("1") + else: + if result[-2] == chars[0]: + result[-1] = str(int(result[-1])+1) + else: + result.append(chars[0]) + result.append("1") + chars.pop(0) + return len(result) + """ diff --git a/ProblemSolving/stringShift/shift.py b/ProblemSolving/stringShift/shift.py new file mode 100644 index 0000000..6e420eb --- /dev/null +++ b/ProblemSolving/stringShift/shift.py @@ -0,0 +1,27 @@ +class Solution(object): + def stringShift(self, s, shift): + """ + :type s: str + :type shift: List[List[int]] + :rtype: str + """ + + n = len(s) + + for [direc, sft] in shift: + # shifts that matter + while sft > n: # because >= n shift would be the same string + sft = n + + if direc == 1: + for i in range(sft): + s = s[-1] + s[:-1] + #print(s) + else: + for i in range(sft): + s = s[1:] + s[0] + #print(s) + + print(direc, sft, s) + + return s diff --git a/ProblemSolving/stringWithout3AsOr3Bs/str.py b/ProblemSolving/stringWithout3AsOr3Bs/str.py new file mode 100644 index 0000000..bf2b91d --- /dev/null +++ b/ProblemSolving/stringWithout3AsOr3Bs/str.py @@ -0,0 +1,103 @@ +class Solution(object): + def strWithout3a3b(self, A, B): + """ + :type A: int + :type B: int + :rtype: str + """ + + # Output S + # * len(S) = A+B + # * len(As) = len(a) and len(Bs) = len(b) + # * "No aaa and no bbb occurences" + result = "" + + # Logic: Known String Logic (Leverage known string as you are constructing the string) - 100 pass lt easy + # when A or B is way greater, we need the other to break the sequence so the conditions are satisfied + # * We do not have the privilege to use either of them as we traverse + # - Instead use the sequence you know for sure wont have a conflict, that is `aab` or `bba` + # - Reference: https://leetcode.com/problems/string-without-aaa-or-bbb/discuss/227167/Python3-short-and-simple + + # Other than one being zero, both should have a minimum of `2` so that know string assumption works + while A > 0 and B > 0: + if A > B: + result += "aab" + A -= 2 + B -= 1 + elif B > A: + result += "bba" + B -= 2 + A -= 1 + else: + result += "ba" + A -= 1 + B -= 1 + + # Any on A or B being 0 condition + result += "a"*A + result += "b"*B + + return result + + # Previous Tries - Faied logic below + # Try one different method, rearrange after string creation + """ + # Create string with necessary string length and count of a and b + if A > B: + result = ["a"]*A + remaining = ["b"]*B + else: + result = ["b"]*B + remaining = ["a"]*A + + # Rearrange + i = 2 + if len(result) > 2: + while i < len(result): + if result[i] == result[i-1] == result[i-2]: + result = result[:i]+[remaining.pop()]+result[i:] + i += 1 + + print result + if remaining: + result.extend(remaining) + + return "".join(result) + """ + + # Add 2 times or 1 time based on the choices + """ + result = "" + + while A > 0 or B > 0: + if A > B: + if A > 2 and "".join(result[-1:]) != "a": + result += "aa" + A -= 2 + elif A > 0 and "".join(result[-2:]) != "aa": + result += "a" + A -= 1 + else: + if B > 2 and "".join(result[-1:]) != "b": + result += "bb" + B -= 2 + elif B > 0 and "".join(result[-2:]) != "bb": + result += "b" + B -= 1 + + return result + """ + + # Add one/more time based on the choice + """ + result = "" + while A > 0 or B > 0: + while A > 0 and ((len(result) < 2) or (len(result) >= 2 and list(set(result[-2:]))[0] != "a")): + print result, list(set(result[-2:]))[0] + result += "a" + A -= 1 + while B > 0 and ((len(result) < 2) or (len(result) >= 2 and list(set(result[-2:]))[0] != "b")): + result += "b" + B -= 1 + return result + """ diff --git a/ProblemSolving/studentAttendanceRecord1/student.py b/ProblemSolving/studentAttendanceRecord1/student.py index 44cf0e1..e3393cc 100644 --- a/ProblemSolving/studentAttendanceRecord1/student.py +++ b/ProblemSolving/studentAttendanceRecord1/student.py @@ -4,7 +4,8 @@ def checkRecord(self, s): :type s: str :rtype: bool """ - + + """ if s.count("A") > 1: return False @@ -18,4 +19,27 @@ def checkRecord(self, s): return False return True + """ + + # Logic 1: O(N) naive iteration to go over the attendance + Absent = 0 + Late = 0 + for i in range(len(s)): + + # Update Values + if s[i] == "A": + Absent += 1 + Late = 0 + elif s[i] == "L": + Late += 1 + else: + Late = 0 + + # Check Conditions + if Absent > 1: + return False + elif Late > 2: + return False + + return True diff --git a/ProblemSolving/subTreeOfAnotherTree/sub2.py b/ProblemSolving/subTreeOfAnotherTree/sub2.py new file mode 100644 index 0000000..45416da --- /dev/null +++ b/ProblemSolving/subTreeOfAnotherTree/sub2.py @@ -0,0 +1,42 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right +class Solution: + def isSubtree(self, root: Optional[TreeNode], subRoot: Optional[TreeNode]) -> bool: + + # Logic 1: until matched once, compare everyone that is equal to subtree node separtely traversing them with another function. + + def checkSubtree(main, sub): + + if not main and not sub: + return True + + if (main and not sub) or (sub and not main): + return False + + if main.val != sub.val: + return False + + left = checkSubtree(main.left, sub.left) + right = checkSubtree(main.right, sub.right) + + return left and right + + def traverse(node): + + if not node: + return + + if subRoot.val == node.val and not self.matched: + self.matched = checkSubtree(node, subRoot) + + traverse(node.left) + traverse(node.right) + + self.matched = False + traverse(root) + return self.matched + diff --git a/ProblemSolving/subtreeWithAllDeepest/subtree.py b/ProblemSolving/subtreeWithAllDeepest/subtree.py new file mode 100644 index 0000000..1342b4e --- /dev/null +++ b/ProblemSolving/subtreeWithAllDeepest/subtree.py @@ -0,0 +1,104 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def subtreeWithAllDeepest(self, root): + """ + :type root: TreeNode + :rtype: TreeNode + """ + + # Height of the tree calculation + def height_of_the_tree(node): + if not node: + return 0 + else: + return 1 + max(height_of_the_tree(node.left), height_of_the_tree(node.right)) + + # Traverse the tree + # Rethink: + # * You are required to find the subtree (root of subtree) which has the max height nodes + # -- This can be true only if the farthest nodes are reachable from the same node (I knew about this but was more prone to get the list of nodes rather than just the root, also tried to solve it recursively which took a long time) + # -- Else, find the subtree whose height is the largest either left or right + # * Took inspiration from https://leetcode.com/problems/smallest-subtree-with-all-the-deepest-nodes/discuss/226585/simple-and-faster-python.Hit-it-if-you-like. + while root: + left = height_of_the_tree(root.left) + right = height_of_the_tree(root.right) + + if left == right: + return root + elif left > right: + root = root.left + else: + root = root.right + + + """ + # This idea doesnt work, + # * The part which I think I missed was, + # * Sometimes the common deepest nodes exist wide from each other that the common parent resides way above them in a tree (Solve this!) + self.deepest = 0 + self.deepest_subtree = [] + + def traverse_deepest(node, past_depth, parent): + + if node.left: + traverse_deepest(node.left, past_depth+1, node) + + if node.right: + traverse_deepest(node.right, past_depth+1, node) + + if past_depth > self.deepest: + self.deepest = past_depth + self.deepest_subtree = [parent.val, node.val] + elif past_depth == self.deepest and parent.val == self.deepest_subtree: + self.deepest_subtree.append(node.val) + elif past_depth == self.deepest and parent.val != self.deepest_subtree: + + + traverse_deepest(root, 0, 0) + if len(self.deepest_subtree) == 2: + self.deepest_subtree = self.deepest_subtree[1:] + return self.deepest_subtree + """ + + """ + # Previous Irrelevant Brainstorming... + self.deepest = 0 + self.deepest_subtree = [] + + def depth_of_node(node, depth, parent): + + if not node: + return 0 + else: + depth += max(depth_of_node(node.left, depth+1, node), depth_of_node(node.right, depth+1, node)) + print node.val, depth + if not node.left and not node.right: + if depth >= self.deepest: + self.deepest_subtree = [] + self.deppest = depth + self.deepest_subtree.append(node.val) + if parent.val not in self.deepest_subtree: + self.deepest_subtree.append(parent.val) + return depth + + depth = depth_of_node(root, 0, root) + print depth, self.deepest, self.deepest_subtree + + #def traverse(node): + # + # if not node: + ## return 0 + # else: + + #if depth > self.deepest: + # self.deepest = depth + # self.deepest_subtree = [node.val, node.left.val, node.right.val] + """ + + diff --git a/ProblemSolving/sudokuSolver/sudoku.py b/ProblemSolving/sudokuSolver/sudoku.py new file mode 100644 index 0000000..c69fbee --- /dev/null +++ b/ProblemSolving/sudokuSolver/sudoku.py @@ -0,0 +1,86 @@ +class Solution(object): + def solveSudoku(self, board): + """ + :type board: List[List[str]] + :rtype: None Do not return anything, modify board in-place instead. + """ + + # Modified version of the reference: Simple to understand and removed collections lib + # Reference: https://leetcode.com/problems/sudoku-solver/discuss/140837/Python-very-simple-backtracking-solution-using-dictionaries-and-queue-~100-ms-beats-~90 + + rows = {} # Track row elements + columns = {} # Track column elements + square = {} # Track the elements within a /3 square + self.invisible_nodes = [] + + # Iterate to fill in all the helper space data structures + for r in range(len(board)): + for c in range(len(board[0])): + if board[r][c] != ".": + # Fill rows + if r not in rows: + rows[r] = set() + rows[r].add(board[r][c]) + # Fill columns + if c not in columns: + columns[c] = set() + columns[c].add(board[r][c]) + # Fill squares + key = (r//3, c//3) + if key not in square: + square[key] = set() + square[key].add(board[r][c]) + else: + self.invisible_nodes.append((r, c)) + + #print(square) + + def backtrack(): + + # True if everything is solved + if not self.invisible_nodes: + return True + + # Take the first position to solve + r, c = self.invisible_nodes[0] + key = (r//3, c//3) + + # Start guessing + for guess in range(1, 10): + + guess = str(guess) + + # Check existence before continue + if guess not in rows[r] and guess not in columns[c] and (key not in square or guess not in square[key]): + # update guess + board[r][c] = guess + # update row + rows[r].add(guess) + # update column + columns[c].add(guess) + # update square + if key in square: + square[key].add(guess) + else: + square[key] = set() + square[key].add(guess) + # Remove from invisible + self.invisible_nodes.pop(0) + + if backtrack(): # Backtrack with all other value succeeds + return True + else: # Backtrack fails with this guess so revert everything + board[r][c] = "." + rows[r].discard(guess) + columns[c].discard(guess) + square[key].discard(guess) + self.invisible_nodes.insert(0, (r, c)) + return False + + backtrack() + + + + + + diff --git a/ProblemSolving/sumOfAbsDiffInASortedArray/sum.py b/ProblemSolving/sumOfAbsDiffInASortedArray/sum.py new file mode 100644 index 0000000..05fa779 --- /dev/null +++ b/ProblemSolving/sumOfAbsDiffInASortedArray/sum.py @@ -0,0 +1,29 @@ +class Solution: + def getSumAbsoluteDifferences(self, nums: List[int]) -> List[int]: + + # 1. Naive array iteration for each i item (o(N)**2) --> time limit exceeded 26/59 + """ + result = [0 for i in range(len(nums))] + for i in range(len(nums)): + for j in range(len(nums)): + result[j] += abs(nums[i] - nums[j]) + return result + """ + + # 2. Technique --> operate over left and right sum - 100 pass + # logically, leverage sorted order to understand that (a-b) + (a-c) + (a-d) = sum(a,b,c) will allow to group a's to 3a - b - c - d when a > b > c > d + presum = 0 + pastsum = sum(nums) + result = [0 for i in range(len(nums))] + + for i in range(len(nums)): + test1 = abs(presum - (i * nums[i])) + test2 = abs(pastsum - ((len(nums)-i) * nums[i])) + if i == 0 or i == len(nums)-1: + result[i] = max(test1, test2) + else: + result[i] = test1 + test2 + presum += nums[i] + pastsum -= nums[i] + return result + diff --git a/ProblemSolving/sumOfAllOddLengthSubArray/sum.py b/ProblemSolving/sumOfAllOddLengthSubArray/sum.py new file mode 100644 index 0000000..b05ff8d --- /dev/null +++ b/ProblemSolving/sumOfAllOddLengthSubArray/sum.py @@ -0,0 +1,15 @@ +class Solution: + def sumOddLengthSubarrays(self, arr: List[int]) -> int: + odd = 1 + final = 0 + n = len(arr) + for o in range(1, n, 2): + for i in range(n): + if i+o > n: + break + #print(arr[i:i+o]) + final += sum(arr[i:i+o]) + if n%2 != 0: + #print(arr) + final += sum(arr) + return final diff --git a/ProblemSolving/sumOfDigitsInMinimumNumber/sum.py b/ProblemSolving/sumOfDigitsInMinimumNumber/sum.py new file mode 100644 index 0000000..155e41d --- /dev/null +++ b/ProblemSolving/sumOfDigitsInMinimumNumber/sum.py @@ -0,0 +1,29 @@ +class Solution(object): + def sumOfDigits(self, A): + """ + :type A: List[int] + :rtype: int + """ + + # Logic 1: Using in-built min and sum()/eval() --> 44% faster + """ + mini = min(A) + target = eval("+".join((list(str(mini))))) + print(mini, target) + if target%2 == 0: + return 1 + else: + return 0 + """ + + # Logic 2: [without in-built] Naive O(N) iterate for minimum + Integer digit addition for sum - 92% faster + mini = float('inf') + for i in range(len(A)): + if A[i] < mini: + mini = A[i] + target = 0 + while mini: + #print(target, mini) + target += mini%10 + mini = mini//10 + return int(target%2 == 0) diff --git a/ProblemSolving/sumOfEvenNumbersAfterQueries/sum.py b/ProblemSolving/sumOfEvenNumbersAfterQueries/sum.py new file mode 100644 index 0000000..206be10 --- /dev/null +++ b/ProblemSolving/sumOfEvenNumbersAfterQueries/sum.py @@ -0,0 +1,44 @@ +class Solution(object): + def sumEvenAfterQueries(self, A, queries): + """ + :type A: List[int] + :type queries: List[List[int]] + :rtype: List[int] + """ + + # Logic 1: Literally following the instructions in the problem - 73% faster + # * Use filter to filter array of even numbers - but using filter for each iteration will make time limit exceeded + # Logic translatable in any language + + # Number of queries + n = len(queries) + + # Sum of all even numbers + sum_of_even_numbers = sum(filter(lambda x: x%2 == 0, A)) + + # Result array storing query answers + ans_for_query = [0]*n + + # Iteration of O(N) along the queries + for i in range(n): + + # Value and Index of each query + value = queries[i][0] + index = queries[i][1] + + # Original value - If it was even lets remove it so we can add newly calculated value + original_value = A[index] + if original_value%2 == 0: + sum_of_even_numbers -= original_value + + # New value based on the query - Also new value affecting the sum when even + A[index] += value + if A[index]%2 == 0: + ans_for_query[i] = sum_of_even_numbers + A[index] + else: + ans_for_query[i] = sum_of_even_numbers + + # New sum of even numbers affected by the query + sum_of_even_numbers = ans_for_query[i] + + return ans_for_query diff --git a/ProblemSolving/sumOfRootToLeafBinaryNumbers/sum.py b/ProblemSolving/sumOfRootToLeafBinaryNumbers/sum.py new file mode 100644 index 0000000..3ac27b6 --- /dev/null +++ b/ProblemSolving/sumOfRootToLeafBinaryNumbers/sum.py @@ -0,0 +1,66 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def sumRootToLeaf(self, root): + """ + :type root: TreeNode + :rtype: int + """ + + # Logic 1: Recursive traverse - 100 pass 63% faster + + # Collect all the path in binary in a list + self.path_to_leaf = [] + # Track total binary sum and return result + self.total_binary_sum = 0 + + # Traverse tree function + def traverse(node, path): + # If not leaf node, record the path left or right + if node.left: + traverse(node.left, path+str(node.val)) + if node.right: + traverse(node.right, path+str(node.val)) + + # Leaf node detect and record path + if not node.left and not node.right: + path += str(node.val) + self.path_to_leaf.append(path) + self.total_binary_sum += int(path, 2) + + traverse(root, "") + print(self.path_to_leaf) + return self.total_binary_sum + + + # Logic 2: Iterative method - 100 pass 83 percent faster + # * Each element of the list has the node and the path to it + """ + stack = [[root, ""]] # iteration to keep track + result = 0 # result holder + + # Traverse nodes by stacking them + while stack: + # current node and path tracking + current, path = stack.pop(0) + + # traverse with path + if current.left: + stack.append([current.left, path+str(current.val)]) + if current.right: + stack.append([current.right, path+str(current.val)]) + + # leaf node condition when we update result + if not current.left and not current.right: + path += str(current.val) + result += int(path, 2) + + return result + """ + + diff --git a/ProblemSolving/sumOfUniqueElements/sum.py b/ProblemSolving/sumOfUniqueElements/sum.py new file mode 100644 index 0000000..f8d4f61 --- /dev/null +++ b/ProblemSolving/sumOfUniqueElements/sum.py @@ -0,0 +1,13 @@ +class Solution: + def sumOfUnique(self, nums: List[int]) -> int: + uniq_sum = 0 + freqs = {} + for i in range(len(nums)): + if nums[i] not in freqs: + freqs[nums[i]] = 0 + freqs[nums[i]] += 1 + for k,v in freqs.items(): + if v == 1: + uniq_sum += k + return uniq_sum + diff --git a/ProblemSolving/sumRootOfLeafNumbers/sum.py b/ProblemSolving/sumRootOfLeafNumbers/sum.py new file mode 100644 index 0000000..75e0553 --- /dev/null +++ b/ProblemSolving/sumRootOfLeafNumbers/sum.py @@ -0,0 +1,33 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def sumNumbers(self, root): + """ + :type root: TreeNode + :rtype: int + """ + + def traverse(node, number): + + if not node.left and not node.right: + self.leaf_nums.append(int(number)) + else: + if node.left: + traverse(node.left, number+str(node.left.val)) + if node.right: + traverse(node.right, number+str(node.right.val)) + + self.leaf_nums = [] + if not root: + return 0 + traverse(root, str(root.val)) + print self.leaf_nums + return sum(self.leaf_nums) + + + diff --git a/ProblemSolving/summaryRanges/summary.py b/ProblemSolving/summaryRanges/summary.py new file mode 100644 index 0000000..5ae1def --- /dev/null +++ b/ProblemSolving/summaryRanges/summary.py @@ -0,0 +1,48 @@ +class Solution(object): + def summaryRanges(self, nums): + """ + :type nums: List[int] + :rtype: List[str] + """ + + # Logic: O(N) iteration + + # Control variables + n = len(nums) + ranges = [] + start = None + i = 0 + + # O(N) loop - 100 pass + while i < n: + # Set start + if start == None: + start = i + + # Condition when the range is complete + if i+1 < n and nums[i]+1 != nums[i+1]: + # condition when range is just the same number + if i == start: + ranges.append(str(nums[start])) + else: + # condition when we have a range > 1 + ranges.append(str(nums[start])+"->"+str(nums[i])) + start = None + + # Condition when list comes to an end! (Similar to the one above for list end) + if i == n-1: + if start == None: + ranges.append(str(nums[i])) + else: + if nums[i] == nums[i-1]+1: + ranges.append(str(nums[start])+"->"+str(nums[i])) + else: + ranges.append(str(nums[start])) + start = None + + i += 1 + + return ranges + + + diff --git a/ProblemSolving/summaryRanges/summary2.py b/ProblemSolving/summaryRanges/summary2.py new file mode 100644 index 0000000..eeeb601 --- /dev/null +++ b/ProblemSolving/summaryRanges/summary2.py @@ -0,0 +1,22 @@ +class Solution: + def summaryRanges(self, nums: List[int]) -> List[str]: + + start = 0 + result = [] + i = 0 + while i < len(nums): + if nums[i]-nums[i-1] > 1: + if start != i-1: + result.append(str(nums[start])+"->"+str(nums[i-1])) + else: + result.append(str(nums[start])) + start = i + i += 1 + + if nums: + if start != i-1: + result.append(str(nums[start])+"->"+str(nums[i-1])) + else: + result.append(str(nums[start])) + + return result diff --git a/ProblemSolving/swapPairs/swap.py b/ProblemSolving/swapPairs/swap.py new file mode 100644 index 0000000..83cb15f --- /dev/null +++ b/ProblemSolving/swapPairs/swap.py @@ -0,0 +1,35 @@ +# Definition for singly-linked list. +# class ListNode(object): +# def __init__(self, x): +# self.val = x +# self.next = None + +class Solution(object): + def swapPairs(self, head, parent=None, first_node=None): + """ + :type head: ListNode + :rtype: ListNode + """ + + # Return Condition + if not head: + return first_node + current = head + nxt = current.next + if not nxt: + if first_node: + return first_node + return head + + # Perform the necessary operation + if parent != None: + parent.next = nxt + current.next = nxt.next + nxt.next = current + + # Set the initial condition for return + if first_node == None: + first_node = nxt + + # Break to SubProblems ( each pair ) and call recursive + return self.swapPairs(current.next, current, first_node) diff --git a/ProblemSolving/symmetricTree/sym2.py b/ProblemSolving/symmetricTree/sym2.py new file mode 100644 index 0000000..d110bec --- /dev/null +++ b/ProblemSolving/symmetricTree/sym2.py @@ -0,0 +1,34 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def isSymmetric(self, root): + """ + :type root: TreeNode + :rtype: bool + """ + + levels = {} + + def traverse(node, height): + if height not in levels: + levels[height] = [] + if node: + traverse(node.left, height+1) + levels[height].append(node.val) + traverse(node.right, height+1) + else: + levels[height].append(None) + + traverse(root, 1) + print(levels) + for l in levels: + if levels[l] == levels[l][::-1]: + pass + else: + return False + return True diff --git a/ProblemSolving/synonymousSentences/syn.py b/ProblemSolving/synonymousSentences/syn.py new file mode 100644 index 0000000..5728020 --- /dev/null +++ b/ProblemSolving/synonymousSentences/syn.py @@ -0,0 +1,117 @@ +class Solution: + def generateSentences(self, synonyms: List[List[str]], text: str) -> List[str]: + + ### Logic 2: 55% faster + # * take the good parts of logic 1 + # * Perform something similar to BFS in BST + # * good ref: https://leetcode.com/problems/synonymous-sentences/discuss/430604/Java-BFS-Solution-Picture-Explain-Clean-code, https://leetcode.com/problems/synonymous-sentences/discuss/729580/JavaScript-BFS-undirected-graph-lightly-commented + + # 1. create graph + g = {} + + for s in synonyms: + if s[0] not in g: + g[s[0]] = [] + if s[1] not in g: + g[s[1]] = [] + g[s[0]].append(s[1]) + g[s[1]].append(s[0]) + + # 2. Maintain a list of possible candidates as stack to traverse/iterate + stack = [text] + visited = set() + + # 3. Iterate over the stack + while stack: + # Update current and visited + current = stack.pop(0) + if current not in visited: + visited.add(current) + # Placeholders and replace + words = current.split(" ") + for w in range(len(words)): + if words[w] in g: + for v in g[words[w]]: + words[w] = v + candidate = " ".join(words) + if candidate not in visited: + visited.add(candidate) + stack.append(candidate) + return sorted(visited) + + + ### Logic 1: Computational intensive and does not work with some cases... + # * Create a graph + # * Get all synonyms + # * Create placeholders in text + # * Backtrack all combinations and fill in + """ + words_that_mean_the_same = [] + g = {} + visited = set() + words = text.split(" ") + uniq = set(words) + fmt = set() + fmts = [] + + # 1. Get all the possible values for each position in a array + + # Graph traverse or expand relation into one path + def traverse_graph(node): + words_that_mean_the_same[-1].append(node) + if node in g and node not in visited: + visited.add(node) + traverse_graph(g[node]) + + for n in synonyms: + if n[0] not in g: + g[n[0]] = n[1] + else: + print("duplicate key") + + for n in g: + if n not in visited: + visited.add(n) + words_that_mean_the_same.append([n]) + traverse_graph(g[n]) + cfmt = uniq.intersection(words_that_mean_the_same[-1]) + fmt.update(cfmt) + fmts.append(cfmt) + if len(cfmt) == 0: + words_that_mean_the_same.pop() + else: + words_that_mean_the_same[-1].sort() + + # 2. Placeholders + start = 65 + hold = [] + for w in range(len(words)): + if words[w] in fmt: + for i in range(len(fmts)): + if words[w] in fmts[i]: + words[w] = chr(start+i)+chr(start+i) + hold.append(chr(start+i)+chr(start+i)) + + hold = list(set(hold)) + + # 3. Fill in + result = [] + fmtStr = " ".join(words) + n = len(words_that_mean_the_same) + def backtrack(i, curr): + if i == n: + print(fmtStr, curr, words_that_mean_the_same, fmt, hold) + #result.append(fmtStr % curr*len()) + for h in range(len(hold)): + fmtStr.replace(hold[h], curr[h]) + else: + for w in words_that_mean_the_same[i]: + backtrack(i+1, curr + (w,)) + + backtrack(0, ()) + return result + """ + + + + diff --git a/ProblemSolving/targetSum/target.py b/ProblemSolving/targetSum/target.py new file mode 100644 index 0000000..f16fe27 --- /dev/null +++ b/ProblemSolving/targetSum/target.py @@ -0,0 +1,40 @@ +# Pending... + +class Solution(object): + def findTargetSumWays(self, nums, S): + """ + :type nums: List[int] + :type S: int + :rtype: int + """ + + # Logic 1: Bruteforce with itertools... + + # BruteForce with all the combinations for the target sum + # * Use itertools + # * add symbols to each integer and then eval() to check for target sum + + import itertools + + count = 0 + + if 0 in nums: + i = 0 + while nums and i < len(nums): + if nums[i] == 0: + del nums[i] + else: + i += 1 + + if not nums: + return 0 + + n = len(nums) + + for combination in itertools.product(["+","-"], repeat=n): + expression = "" + for i in range(n): + expression += combination[i]+str(nums[i]) + if eval(expression) == S: + count += 1 + return count diff --git a/ProblemSolving/thousandSeparator/thousand.py b/ProblemSolving/thousandSeparator/thousand.py new file mode 100644 index 0000000..670f1bf --- /dev/null +++ b/ProblemSolving/thousandSeparator/thousand.py @@ -0,0 +1,20 @@ +class Solution(object): + def thousandSeparator(self, n): + """ + :type n: int + :rtype: str + """ + + # Logic 1: Iterative without inbuilt functions --> 99% faster + result = "" + if n == 0: + return "0" + while n: + next_thousand = n%1000 + n = n//1000 + if n: + fmtStr = "." + "{:03d}".format(next_thousand) + else: + fmtStr = str(next_thousand) + result = fmtStr + result + return result.strip() diff --git a/ProblemSolving/threeConsecutiveOdds/three.py b/ProblemSolving/threeConsecutiveOdds/three.py new file mode 100644 index 0000000..e4df81c --- /dev/null +++ b/ProblemSolving/threeConsecutiveOdds/three.py @@ -0,0 +1,12 @@ +class Solution: + # Logic 1: Three consecutive odd - lt easy - 100 pass - 90% faster + def threeConsecutiveOdds(self, arr: List[int]) -> bool: + odd_consec = 0 + for i in range(len(arr)): + if arr[i]%2 != 0: + odd_consec += 1 + else: + odd_consec = 0 + if odd_consec == 3: + return True + return False diff --git a/ProblemSolving/threeSum/three.py b/ProblemSolving/threeSum/three.py new file mode 100644 index 0000000..4b21b29 --- /dev/null +++ b/ProblemSolving/threeSum/three.py @@ -0,0 +1,95 @@ +class Solution: + def threeSum(self, nums: List[int]) -> List[List[int]]: + + # Logic 1: Bruteforce all three numbered groups to sum up to 0 - Time limit exceeded, all other tcs passed + """ + import itertools + result = set() + for group in itertools.combinations(nums, r=3): + uniq = tuple(sorted(group)) + if len(uniq) == 3 and uniq not in result and sum(uniq) == 0: + result.add(uniq) + return result + """ + + # Logic 2: Backtrack recursively -- Make optimal choice to backtrack - Time limit exceeded, all other tcs passed + """ + def backtrack(array, choices, chosen_ones): + #print(array, choices, chosen_ones) + if choices and len(choices) == 3: + sumi = sum(choices) + key = tuple(sorted(choices)) + if sumi == 0 and key not in choices: + chosen_ones.add(key) + return + for i in range(len(array)): + if len(choices) < 3: + backtrack(array[:i]+array[i+1:], choices + [array[i]], chosen_ones) + return chosen_ones + return backtrack(nums, [], set()) + """ + + # Logic 2(1/2) -> optimize the backtrack logic + # a + b = -c ( conversion to a 2 sum problem is the best idea referring to https://leetcode.com/problems/3sum/discuss/7498/Python-solution-with-detailed-explanation) + """ + def backtrack(array, target, choices, chosen_ones): + if choices and len(choices) == 2: + sumi = sum(choices) + key = tuple(sorted(choices+[target])) + if sumi == -target and key not in chosen_ones: + chosen_ones.add(key) + return + for i in range(len(array)): + if target == None: + backtrack(array[i+1:], array[i], choices, chosen_ones) + else: + if len(choices) < 2: + backtrack(array[i+1:], target, choices + [array[i]], chosen_ones) + return chosen_ones + nums.sort() + return backtrack(nums, None, [], set()) + """ + + # Logic 3: Iterative method + convert to 2Sum 2pointer logic + Equality decision to obtain unique combinations + + # sort to make things easier to decide + nums.sort() + + # Variable declaration + N = len(nums) + result = [] + + # Convertion to 2 sum logic --> a + b + c = 0 --> a + b = -c + # * For each number we set it as -c and continue + for i in range(N): + + # Eliminate equality or same combinations + if i > 0 and nums[i] == nums[i-1]: + continue + + # Set the target + target = -nums[i] + + # Solve with 2 Sum logic with 2 pointer logic + left = i+1 + right = N-1 + while left < right: + current_sum = nums[left]+nums[right] + if current_sum == target: + result.append([nums[left], nums[right], -target]) + left += 1 + while left < right and nums[left] == nums[left-1]: + left += 1 + elif current_sum < target: + left += 1 + else: + right -= 1 + + return result + + + + + + + diff --git a/ProblemSolving/threeSum/threeTwo.py b/ProblemSolving/threeSum/threeTwo.py new file mode 100644 index 0000000..aed6a91 --- /dev/null +++ b/ProblemSolving/threeSum/threeTwo.py @@ -0,0 +1,65 @@ +class Solution(object): + def threeSum(self, nums): + """ + :type nums: List[int] + :rtype: List[List[int]] + """ + + # Logic 1: Convert to multiple 2sum subprobs and solve + def twoSum(nums, target): + cache = {} + result = [] + visited = set() + for i in range(len(nums)): + final = target - nums[i] + if final not in cache: + cache[final] = [] + cache[final].append(i) + + for i in range(len(nums)): + if nums[i] not in cache: + continue + for j in cache[nums[i]]: + if i == j: + continue + chktmp = (nums[i], nums[j]) + if chktmp in visited: + continue + visited.add(chktmp) + result.append([i, j]) + print(target, result) + return result + + result = [] + indexTargets = {} + for i in range(len(nums)): + target = 0 - nums[i] + if target not in indexTargets: + indexTargets[target] = [] + indexTargets[target].append(i) + + + visited = set() + for target in indexTargets: + targetCombs = twoSum(nums, target) + #print(indexTargets[target], targetCombs) + + for o in indexTargets[target]: + for t in targetCombs: + tmp = [nums[o]] + tmpS = set([nums[o]]) + tS = set(t) + if o in tS: + continue + for i in t: + tmp.append(nums[i]) + tmpS.update(tS) + chktmp = tuple(sorted(tmp)) + if chktmp not in visited and sum(tmp) == 0: + visited.add(chktmp) + result.append(chktmp) + + return result + + + diff --git a/ProblemSolving/ticTacToe/tic.py b/ProblemSolving/ticTacToe/tic.py new file mode 100644 index 0000000..37bd7e8 --- /dev/null +++ b/ProblemSolving/ticTacToe/tic.py @@ -0,0 +1,71 @@ +# Logic 1: Declare Board and Make Moves + Observe for winning criteria - 100 pass - 5% faster +# * This logic checks for winning criterion every time a move is made which is pretty lame, as it iterates on every move. +# * Instead we could hold the winning category on a placeholder or dict or list and eliminiate to find the winning criteria on point. +class TicTacToe(object): + + def __init__(self, n): + """ + Initialize your data structure here. + :type n: int + """ + + # Initialize the Board + self.n = n + self.board = [["." for i in range(n)] for i in range(n)] + + def move(self, row, col, player): + """ + Player {player} makes a move at ({row}, {col}). + @param row The row of the board. + @param col The column of the board. + @param player The player, can be either 1 or 2. + @return The current winning condition, can be either: + 0: No one wins. + 1: Player 1 wins. + 2: Player 2 wins. + :type row: int + :type col: int + :type player: int + :rtype: int + """ + + # Move of a player + if player == 1: # X + self.board[row][col] = "X" + else: # O + self.board[row][col] = "O" + + # Check winning condition + # Row check + if set(self.board[row]) == set("X"): + return 1 + elif set(self.board[row]) == set("O"): + return 2 + + # Column check + if set([self.board[i][col] for i in range(self.n)]) == set("X"): + return 1 + elif set([self.board[i][col] for i in range(self.n)]) == set("O"): + return 2 + + # Diagnal check - forward diagnal + if set([self.board[i][i] for i in range(self.n)]) == set("X"): + return 1 + elif set([self.board[i][i] for i in range(self.n)]) == set("O"): + return 2 + + # Diagnal check - reverse diagnal + i = 0 + j = self.n-1 + if set([self.board[i+o][j-o] for o in range(self.n)]) == set("X"): + return 1 + elif set([self.board[i+o][j-o] for o in range(self.n)]) == set("O"): + return 2 + + #print(self.board) + return 0 # No One Wins + + +# Your TicTacToe object will be instantiated and called as such: +# obj = TicTacToe(n) +# param_1 = obj.move(row,col,player) diff --git a/ProblemSolving/timeBasedKeyValuePair/time.py b/ProblemSolving/timeBasedKeyValuePair/time.py new file mode 100644 index 0000000..7484970 --- /dev/null +++ b/ProblemSolving/timeBasedKeyValuePair/time.py @@ -0,0 +1,97 @@ +class TimeMap(object): + + def __init__(self): + """ + Initialize your data structure here. + """ + # We dont want a dictionary to loose the increasing property, use list to increase incrementally, so we maintain an time list + self.data = {} + self.times = [] + + def set(self, key, value, timestamp): + """ + :type key: str + :type value: str + :type timestamp: int + :rtype: None + """ + # Technically we do not need the key + self.times.append(timestamp) + if key not in self.data: + self.data[key] = [[],[]] + self.data[key][0].append(timestamp) + self.data[key][1].append(value) + + def get(self, key, timestamp): + """ + :type key: str + :type timestamp: int + :rtype: str + """ + + # Implement binary search to search the element close to this + """ + n = len(self.data) + left, right = 0, n + while left <= right: + mid = left+(right-1)//2 + if self.data[mid][0] == timestamp: + return + elif self.data[mid][0] < timestamp: + right = mid + else: + left = mid + """ + + #print(self.data, left, right, timestamp) + + import bisect + def binary_search(array, x): + #print(array, x) + index = bisect.bisect_left(array, x) + #print(index) + if index < len(array) and array[index] == x: + return index + elif index: + return (index-1) + else: + return -1 + + #index = binary_search(self.times, timestamp) + #print(index) + + # Naive Iteration - Time Limit Exceeded + """ + for i in range(len(self.data)-1, -1, -1): + if self.data[i][0] <= timestamp and key == self.data[i][1]: + #print(self.data[i][2]) + return self.data[i][2] + return "" + """ + + # Naive iteration with dictionary + if key not in self.data: + return "" + + #data = sorted(self.data[key], key=lambda x:x[0], reverse=True) + #data = self.data[key] + """ + for val in data: + if val[0] <= timestamp: + return val[1] + """ + times = self.data[key][0] + index = binary_search(times, timestamp) + #print(index) + if index == -1: + return "" + else: + return self.data[key][1][index] + + + + +# Your TimeMap object will be instantiated and called as such: +# obj = TimeMap() +# obj.set(key,value,timestamp) +# param_2 = obj.get(key,timestamp) diff --git a/ProblemSolving/timeBasedKeyValueStore/timebased.py b/ProblemSolving/timeBasedKeyValueStore/timebased.py new file mode 100644 index 0000000..8781d08 --- /dev/null +++ b/ProblemSolving/timeBasedKeyValueStore/timebased.py @@ -0,0 +1,146 @@ +# Logic 1: with hashmap and binary search --> still time limit exceeded, fix it... +""" +class TimeMap: + + def __init__(self): + self.dict = {} + + def set(self, key: str, value: str, timestamp: int) -> None: + + # Create key if it does not exist + if key not in self.dict: + self.dict[key] = {} + + # Else add the timestamp to the key dictionary + if timestamp in self.dict[key]: + return "Error" + + self.dict[key][timestamp] = value + + def get(self, key: str, timestamp: int) -> str: + + def binary_search(timestamps, timestamp): + left = 0 + right = len(timestamps)-1 + if right == left: + if timestamp >= timestamps[left]: + return left + while left < right: + mid = (right + left)//2 + #print(left, mid, right, timestamps, timestamp) + if timestamps[mid] == timestamp: + return mid + elif timestamps[left] == timestamp: + return left + elif timestamps[right] == timestamp: + return right + elif timestamps[mid] < timestamp: + left = mid + else: + right = mid + + if right-left == 1: + if timestamp > timestamps[right]: + return right + elif timestamp > timestamps[left]: + return left + else: + return None + + # Error if key does not exist + if key not in self.dict: + return "" + + timestamps = list(self.dict[key].keys()) + + # Logic 1: to search through the timestamp: causes time limit exceeded on last tc but passes others + + #while len(timestamps) > 0 and timestamps[-1] > timestamp: + # timestamps.pop() + + #if not timestamps: + # return "" + + + # Logic 2: Use Binary Search + last_time = binary_search(timestamps, timestamp) + + #if last_time: + # print(timestamps, timestamp, last_time, self.dict[key][timestamps[last_time]]) + #else: + # print(timestamps, timestamp, last_time) + + if last_time == None: + return "" + + return self.dict[key][timestamps[last_time]] + + +# Your TimeMap object will be instantiated and called as such: +# obj = TimeMap() +# obj.set(key,value,timestamp) +# param_2 = obj.get(key,timestamp) +""" + +# Logic 2: Change the data structure arragements to make it faster... --> 100 pass + +class TimeMap: + + def __init__(self): + self.dict = {} + + def set(self, key: str, value: str, timestamp: int) -> None: + + if key not in self.dict: + self.dict[key] = [[],[]] + + self.dict[key][0].append(timestamp) + self.dict[key][1].append(value) + + def get(self, key: str, timestamp: int) -> str: + + def binary_search(timestamps, timestamp): + left = 0 + right = len(timestamps)-1 + if right == left: + if timestamp >= timestamps[left]: + return left + while left < right: + mid = (right + left)//2 + #print(left, mid, right, timestamps, timestamp) + if timestamps[mid] == timestamp: + return mid + elif timestamps[left] == timestamp: + return left + elif timestamps[right] == timestamp: + return right + elif timestamps[mid] < timestamp: + left = mid + else: + right = mid + + if right-left == 1: + if timestamp > timestamps[right]: + return right + elif timestamp > timestamps[left]: + return left + else: + return None + + # Error if key does not exist + if key not in self.dict: + return "" + + # Logic 2: Use Binary Search + last_time = binary_search(self.dict[key][0], timestamp) + + if last_time == None: + return "" + + return self.dict[key][1][last_time] + + +# Your TimeMap object will be instantiated and called as such: +# obj = TimeMap() +# obj.set(key,value,timestamp) +# param_2 = obj.get(key,timestamp) diff --git a/ProblemSolving/timeNeededToInformAllEmployees/time.py b/ProblemSolving/timeNeededToInformAllEmployees/time.py new file mode 100644 index 0000000..c603c5c --- /dev/null +++ b/ProblemSolving/timeNeededToInformAllEmployees/time.py @@ -0,0 +1,36 @@ +class Node: + def __init__(self, n, inform, mgr, children=[]): + self.n = n + self.inform = inform + self.mgr = mgr + self.children = children + +class Solution: + def numOfMinutes(self, n: int, headID: int, manager: List[int], informTime: List[int]) -> int: + nodes = {} # map[n]*Node + visitedMgrs = set() + self.totalMins = 0 + root = None + + def computeTime(node, cumulTime): + for c in node.children: + computeTime(c, cumulTime + node.inform) + self.totalMins = max(self.totalMins, cumulTime) + + for i in range(n): + mgr = manager[i] + + if mgr == -1: + root = i + + if i not in nodes: + nodes[i] = Node(i, informTime[i], mgr != 0, []) + + if mgr not in nodes: + nodes[mgr] = Node(mgr, informTime[mgr], True, []) + + nodes[mgr].children.append(nodes[i]) + + computeTime(nodes[root], 0) + + return self.totalMins diff --git a/ProblemSolving/trafficLightsControlledIntersection/traffic.py b/ProblemSolving/trafficLightsControlledIntersection/traffic.py new file mode 100644 index 0000000..47c3dff --- /dev/null +++ b/ProblemSolving/trafficLightsControlledIntersection/traffic.py @@ -0,0 +1,47 @@ +# Logic 1: naive logic with global for current light tracking --> 100 pass 71 % faster +class TrafficLight(object): + + def __init__(self): + # Current Traffic Light that is GREEN + self.current_green_light = 1 + + # The Gist + """ + self.current_green_light = "A" + # Direction mapped to the Road A and B + self.light = ["A", "A", "B", "B"] + self.result_car = "Car %d Has Passed Road A In Direction %d" + self.result_light = "Traffic Light On Road %s Is Green" + """ + + def carArrived(self, carId, roadId, direction, turnGreen, crossCar): + """ + :type roadId: int --> // ID of the car + :type carId: int --> // ID of the road the car travels on. Can be 1 (road A) or 2 (road B) + :type direction: int --> // Direction of the car + :type turnGreen: method --> // Use turnGreen() to turn light to green on current road + :type crossCar: method --> // Use crossCar() to make car cross the intersection + :rtype: void + """ + + if roadId == self.current_green_light: + crossCar() + else: + self.current_green_light = roadId + turnGreen() + crossCar() + + # The Gist + """ + if self.light[direction] == self.current_green_light: + return self.result_car % (carId, direction) + else: + self.current_green_light = self.light[direction] + return self.result_light % (self.light[direction]) + "," + self.result_car % (carId, direction) + """ + + + + + + diff --git a/ProblemSolving/transposeOfAMatrix/trans.py b/ProblemSolving/transposeOfAMatrix/trans.py new file mode 100644 index 0000000..90bc971 --- /dev/null +++ b/ProblemSolving/transposeOfAMatrix/trans.py @@ -0,0 +1,17 @@ +class Solution(object): + def transpose(self, matrix): + """ + :type matrix: List[List[int]] + :rtype: List[List[int]] + """ + + # Logic 1: naive iteration of matrix O(n*m) to contruct the transpose + transpose = [] + + for m in matrix: + for i in range(len(m)): + if i >= len(transpose): + transpose.append([]) + transpose[i].append(m[i]) + + return transpose diff --git a/ProblemSolving/travelBetweenCities/travel.py b/ProblemSolving/travelBetweenCities/travel.py new file mode 100644 index 0000000..5bf0a01 --- /dev/null +++ b/ProblemSolving/travelBetweenCities/travel.py @@ -0,0 +1,172 @@ +# Travel Between Cities +""" +You need to travel between cities, but some roads may have been blocked by a recent storm. +You want to check before you travel to make sure you avoid them. +Given a map of the cities and their bidirectional roads, determine which roads are along any shortest path so you can check that they are not blocked. +The roads or edges are named using their 1-based index within the input arrays. +For example, given a map of g_nodes = 5 nodes, the starting nodes, ending nodes and road lengths are: +Road from/to/weight +1 (1, 2, 1) +2 (2, 3, 1) +3 (3, 4, 1) +4 (4, 5, 1) +5 (5, 1, 3) +6 (1, 3, 2) +7 (5, 3, 1) +You always need to go from node 1 to node g_nodes, so from node 1 to node 5 in this case. +The shortest path is 3, and there are three paths of that length: 1 → 5, 1 → 2 → 3 → 5, and 1 → 3 → 5. +We create an array of strings, one for each road in order, where the value is YES if a road is along a shortest path or NO if it is not. +In this case, the resulting array is [YES, YES, NO, NO, YES, YES, YES]. +Function Description +Complete the function classifyEdges in the editor below. +The function must return an array of g_edges strings where the value at ith index is YES if the ith edge is a part of a shortest path from vertex 1 to vertex g_nodes. +Otherwise it should contain NO. +classifyEdges has the following parameter(s): +g_nodes: an integer, the number of nodes +g_from[g_from[1],...g_from[g_nodes]]: an array of integers, the start g_nodes for each road +g_to[to[1],...g_to[g_nodes]]: an array of integers, the end g_nodes for each road +g_weight[g_weight[1],...g_weight[g_nodes]]: an array of integers, the lengths of each road +Constraints +2 ≤ g_nodes ≤ 3000 +1 ≤ g_edges ≤ min(105, (g_nodes x g_nodes - 1)/2) +1 ≤ g_weight[i] ≤ 105 +1 ≤ g_from[i], g_to[i] ≤ g_nodes +There is at most one edge between any pair of g_nodes +The given graph is connected +Sample Input 1 +4 5 +1 2 1 +2 4 1 +1 3 1 +3 4 2 +1 4 2 +Sample Output 1 +YES +YES +NO +NO +YES + +Sample Input 2 + +5 7 +1 2 1 +2 3 1 +3 5 1 +1 4 1 +4 5 2 +3 4 2 +2 4 4 + +Sample Output 2 +YES +YES +YES +YES +YES +NO +NO + +Sample Input 3 +4 5 +1 2 1 +1 3 1 +1 4 1 +2 3 1 +2 4 1 + +Sample Output 3 + +NO +NO +YES +NO +NO +""" + +# Logic 1: We will do using graphs to track the paths +# - Build them using a dictionary/hashmap datastructure +# - Bidirectional route - take that into consideration, consider infinite loops when cities route are completed by a circle +# - Using traceback logic + +def get_paths(src, target, weight, path, paths, visited, graph): + # Reached the target, then append to paths + if src == target: + if weight not in paths: + paths[weight] = [] + paths[weight].append(path) + else: + # Iterate all possible destinations until we reach the target + for dst in graph[src].keys(): + if dst not in visited: # Bidirectional check - we do not want to visit already visited node... avoid infinite loop + get_paths(dst, target, weight+graph[src][dst], path+[(src, dst)], paths, visited+[dst], graph) + return + +def shortest_path(s, d, paths): + + # Build graph with a dictionary + graph = {} + + # Iterate paths to fill in the dictionary + for path in paths: + # For simplicity, call out explicitly + src = path[0] + dst = path[1] + weight = path[2] + + # add the SOURCE city in the graph + if src not in graph: + graph[src] = {} + if dst not in graph: + graph[dst] = {} + + # add the DESTINATION city to the source - if duplicate choose minimum for shortest + if dst not in graph[src]: + graph[src][dst] = weight + else: + graph[src][dst] = min(graph[src][dst], weight) + if src not in graph[dst]: + graph[dst][src] = weight + else: + graph[dst][src] = min(graph[dst][src], weight) + + #print(graph) + s_paths = {} + # for s in graph.keys(): # Need iteration to start from any nodes, but we need to start from 1 in this case + get_paths(1, d, 0, [], s_paths, [1], graph) # src, target, weight, path, paths, graph + #print(s_paths) + s = [] + for dir in s_paths[min(s_paths.keys())]: + s.extend(dir) + return s + +def solution(node, map): + shortest = shortest_path(1, g_nodes, map) + print(shortest) + result = ["NO"]*len(map) + for m in range(len(map)): + s = map[m][0] + d = map[m][1] + if (s,d) in shortest or (d,s) in shortest: + result[m] = "YES" + print(result) + +# TC1 +g_nodes = 5 +map = [(1, 2, 1), (2, 3, 1), (3, 4, 1), (4, 5, 1), (5, 1, 3), (1, 3, 2), (5, 3, 1)] +solution(g_nodes, map) + +# TC2 +g_nodes = 4 +map = [(1, 2, 1), (2, 4, 1), (1, 3, 1), (3, 4, 2), (1, 4, 2)] +solution(g_nodes, map) + +# TC3 +g_nodes = 5 +map = [(1, 2, 1), (2, 3, 1), (3, 5, 1), (1, 4, 1), (4, 5, 2), (3, 4, 2), (2, 4, 4)] +solution(g_nodes, map) + +# TC4 +g_nodes = 4 +map = [(1, 2, 1), (1, 3, 1), (1, 4, 1), (2, 3, 1), (2, 4, 1)] +solution(g_nodes, map) \ No newline at end of file diff --git a/ProblemSolving/tripletMultiple/tripletMultipleMax.py b/ProblemSolving/tripletMultiple/tripletMultipleMax.py index dd02d5c..bb24325 100644 --- a/ProblemSolving/tripletMultiple/tripletMultipleMax.py +++ b/ProblemSolving/tripletMultiple/tripletMultipleMax.py @@ -10,4 +10,11 @@ def solution(A): # hence taking first 2 possible -ve numbers prod = max(A[0]*A[1]*A[-1],A[-1]*A[-2]*A[-3]) return prod + +# Leetcode +def solution(nums): + nums = sorted(nums, reverse=True) + positive_max = nums[0]*nums[1]*nums[2] + negative_max = nums[0]*nums[-1]*nums[-2] + return max(positive_max, negative_max) diff --git a/ProblemSolving/truncateSentence/truncate.py b/ProblemSolving/truncateSentence/truncate.py new file mode 100644 index 0000000..0459ef4 --- /dev/null +++ b/ProblemSolving/truncateSentence/truncate.py @@ -0,0 +1,26 @@ +class Solution: + def truncateSentence(self, s: str, k: int) -> str: + # Logic 1: using string split and rejoin k words - 100 pass - 85% faster + ## return " ".join(s.split(" ")[:k]) + + # Logic 2: Naive iteration + result = "" + word = "" + count = 0 + for c in s: + print(word, result, count, c) + if count >= k: + return result + if c == " ": + if result != "": + result += " " + result += word + word = "" + count += 1 + else: + word += c + if word: + if result: + result += " " + result += word + return result diff --git a/ProblemSolving/twoCityScheduling/twoCityScheduling.py b/ProblemSolving/twoCityScheduling/twoCityScheduling.py new file mode 100644 index 0000000..9c99882 --- /dev/null +++ b/ProblemSolving/twoCityScheduling/twoCityScheduling.py @@ -0,0 +1,50 @@ +class Solution(object): + def twoCitySchedCost(self, costs): + """ + :type costs: List[List[int]] + :rtype: int + """ + + # First, Sort days based on their delta or difference between cityA and cityB + sorted_differences = sorted(costs, key=lambda x: x[0] - x[1]) + + # N for each city, given array is 2N + N = len(costs)//2 + min_cost = 0 + + # Second, for the first few differences use cityA's value, because the lower differences means x[0] in minimum in x[0]-x[1] + min_cost += sum(i[0] for i in sorted_differences[:N]) + + # Third, for rest of the days use cityB + min_cost += sum(i[1] for i in sorted_differences[N:]) + + return min_cost + + # This logic below doesnot work for [[259,770],[448,54],[926,667],[184,139],[840,118],[577,469]], which makes me think the difference or delta is more important here + """ + # Count for city A and B each + cityA = 0 + cityB = 0 + + # As 2N people are already given. + N = len(costs)//2 + + min_cost = 0 + + for candidate in costs: + if candidate[0] < candidate[1] and cityA < N: + min_cost += candidate[0] + cityA += 1 + elif cityB >= N: + min_cost += candidate[0] + cityA += 1 + else: + min_cost += candidate[1] + cityB += 1 + # Just this wont work as we need to have N in each city + ## min_cost += min(candidate[0], candidate[1]) + print min_cost, cityA, cityB + return min_cost + """ + + diff --git a/ProblemSolving/twoCityScheduling/twoCityScheduling2.py b/ProblemSolving/twoCityScheduling/twoCityScheduling2.py new file mode 100644 index 0000000..6153f06 --- /dev/null +++ b/ProblemSolving/twoCityScheduling/twoCityScheduling2.py @@ -0,0 +1,50 @@ +class Solution(object): + def twoCitySchedCost(self, costs): + """ + :type costs: List[List[int]] + :rtype: int + """ + + # Logic1: does not work + # * Going greedy with min costs all along? - Doesnt work? + # * iteration and logic below doesnt work + """ + total = 0 + A = len(costs)//2 + B = len(costs)//2 + for c in costs: + if A and c[0] < c[1]: + total += c[0] + A -= 1 + elif B and c[1] < c[0]: + total += c[1] + B -= 1 + else: + if A: + total += c[0] + A -= 1 + elif B: + total += c[1] + B -=1 + return total + """ + + # Logic 2: Arrange and then perform - does not work + """ + cityA = sorted(costs, key=lambda x: x[0]) + A = len(costs)//2 + total = 0 + while A: + total += cityA.pop(0)[0] + A -= 1 + B = len(costs)//2 + while B: + total += cityA.pop(0)[1] + B -= 1 + return total + """ + + # Logic 3: Find Delta and arrange them accordingly - 100 pass + costs = sorted(costs, key=lambda x: x[0]-x[1]) + mid = len(costs)//2 + return sum(c[0] for c in costs[:mid])+sum(c[1] for c in costs[mid:]) diff --git a/ProblemSolving/twoOutOfThree/two.py b/ProblemSolving/twoOutOfThree/two.py new file mode 100644 index 0000000..0b6f756 --- /dev/null +++ b/ProblemSolving/twoOutOfThree/two.py @@ -0,0 +1,30 @@ +class Solution: + def twoOutOfThree(self, nums1: List[int], nums2: List[int], nums3: List[int]) -> List[int]: + + # Logic 1: using space to compute frequency across arrays: O(ABC) time + O(2N) space --> ~ 25% faster + freqs = {} + result = [] + added = set() + + def record(nums): + visited = set() + for i in nums: + if i not in freqs: + freqs[i] = 1 + else: + if i in visited: + continue + freqs[i] += 1 + visited.add(i) + + record(nums1) + record(nums2) + record(nums3) + + result = [] + for k,v in freqs.items(): + if v >= 2: + result.append(k) + + return result + diff --git a/ProblemSolving/twoSum/two.py b/ProblemSolving/twoSum/two.py new file mode 100644 index 0000000..455e9cf --- /dev/null +++ b/ProblemSolving/twoSum/two.py @@ -0,0 +1,36 @@ +class Solution(object): + def twoSum(self, nums, target): + """ + :type nums: List[int] + :type target: int + :rtype: List[int] + """ + + """ + elements = {} + + for i in range(len(nums)): + if nums[i] not in elements: + elements[nums[i]] = [] + elements[nums[i]].append(i) + + for i in range(len(nums)): + if target-nums[i] in elements: + sec = target-nums[i] + if sec == nums[i]: + if len(elements[sec]) > 1: + return [i, elements[target-nums[i]][1]] + else: + return [i, elements[target-nums[i]][0]] + return -1 + + """ + + elements = {} + for i in range(len(nums)): + if target-nums[i] in elements: + return [i, elements[target-nums[i]]] + else: + elements[nums[i]] = i + return -1 + diff --git a/ProblemSolving/twoSumBSTs/two.py b/ProblemSolving/twoSumBSTs/two.py new file mode 100644 index 0000000..05291b9 --- /dev/null +++ b/ProblemSolving/twoSumBSTs/two.py @@ -0,0 +1,34 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right +class Solution: + def twoSumBSTs(self, root1: TreeNode, root2: TreeNode, target: int) -> bool: + + # Logic 1: 2*O(N) == O(N) over each of the tree and check if the difference exists + def traverseToSet(node): + if not node: + return + + if self.search: + if target-node.val in self.tree1: + self.twoSum = self.twoSum or True + else: + self.tree1.add(node.val) + + if node.left: + traverseToSet(node.left) + if node.right: + traverseToSet(node.right) + + self.tree1 = set() + self.twoSum = False + self.search = False + traverseToSet(root1) + self.search = True + traverseToSet(root2) + return self.twoSum + + # Logic 2: Traverse one tree and Search another tree for difference diff --git a/ProblemSolving/twoSumIII/two_sum.py b/ProblemSolving/twoSumIII/two_sum.py new file mode 100644 index 0000000..c9cf691 --- /dev/null +++ b/ProblemSolving/twoSumIII/two_sum.py @@ -0,0 +1,70 @@ +# Logic 2: 100 pass --> 900ms 10% faster +# * Compute during find from the diff of numbers added +# * Add to set directly without any ops +class TwoSum: + + def __init__(self): + """ + Initialize your data structure here. + """ + # arg between set() and dict() here + # * We need to take care of scenario like 0+0=0 so dict way to get counts + self.nums = {} + + def add(self, number: int) -> None: + """ + Add the number to an internal data structure.. + """ + if number not in self.nums: + self.nums[number] = 1 + else: + self.nums[number] += 1 + + + def find(self, value: int) -> bool: + """ + Find if there exists any pair of numbers which sum is equal to the value. + """ + for num, times in self.nums.items(): + other_num = value-num + # ugly ifs but solves the problem + if num == other_num and other_num in self.nums: # 1 + 1 = 2 + if times > 1: + return True + elif value != other_num and other_num in self.nums: # 0 + 0 = 0 + return True + elif value == other_num and other_num in self.nums: # All other sums + if times > 1: + return True + return False + + +# Your TwoSum object will be instantiated and called as such: +# obj = TwoSum() +# obj.add(number) +# param_2 = obj.find(value) + +""" +# Logic 1: TIME LIMIT EXCEEDED ( Others pass ) +# * Compute during add to maintain a memo of sums +# * Return from set to speed during find +class TwoSum: + + def __init__(self): + self.nums = [] + self.sums = set() + + def add(self, number: int) -> None: + n = len(self.nums) + i = 0 + while i < n: + self.sums.add(self.nums[i]+number) + i += 1 + self.nums.append(number) + + + def find(self, value: int) -> bool: + if value in self.sums: + return True + return False +""" diff --git a/ProblemSolving/twoSums/twoSums2.py b/ProblemSolving/twoSums/twoSums2.py new file mode 100644 index 0000000..a9f0973 --- /dev/null +++ b/ProblemSolving/twoSums/twoSums2.py @@ -0,0 +1,17 @@ +class Solution(object): + def twoSum(self, nums, target): + """ + :type nums: List[int] + :type target: int + :rtype: List[int] + """ + + # Logic 1: convert to dictionary and o(n) iterate + import collections + c = collections.Counter(nums) + for i in range(len(nums)): + next_element = target - nums[i] + if next_element in c: + for j in range(len(nums)): + if nums[j] == next_element and j != i: + return [i,j] diff --git a/ProblemSolving/twoSumsIV/twoSumsIVInputBST2.py b/ProblemSolving/twoSumsIV/twoSumsIVInputBST2.py new file mode 100644 index 0000000..bf797b7 --- /dev/null +++ b/ProblemSolving/twoSumsIV/twoSumsIVInputBST2.py @@ -0,0 +1,72 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def findTarget(self, root, k): + """ + :type root: TreeNode + :type k: int + :rtype: bool + """ + + # 4 + # [1, 2, 3] ==> 1,3 + + s = set() + + def traverse(node): + + if node.val in s: + return True + + s.add(k-node.val) + + left = right = False + + if node.left: + left = traverse(node.left) + if node.right: + right = traverse(node.right) + + return left or right + + return traverse(root) + + +""" +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def findTarget(self, root, k): + """ + :type root: TreeNode + :type k: int + :rtype: bool + """ + + def traverse(node, target, visited): + if not node: + return + if node.val in visited: + self.ans = True + else: + visited.add(target-node.val) + if node.left: + traverse(node.left, target, visited) + if node.right: + traverse(node.right, target, visited) + + visit = set() + self.ans = False + traverse(root, k, visit) + return self.ans +""" diff --git a/ProblemSolving/twoSumsLessThanK/two.py b/ProblemSolving/twoSumsLessThanK/two.py new file mode 100644 index 0000000..00ece45 --- /dev/null +++ b/ProblemSolving/twoSumsLessThanK/two.py @@ -0,0 +1,41 @@ +class Solution(object): + def twoSumLessThanK(self, A, K): + """ + :type A: List[int] + :type K: int + :rtype: int + """ + + # Logic 1: Naive Iteration - 27 % faster + """ + maxi = -1 + for i in range(len(A)): + for j in range(i+1, len(A)): + target = A[i] + A[j] + if target > maxi and target < K: + maxi = target + #print(A[i],A[j], maxi) + return maxi + """ + + # Logic 2: 2 pointer technique - 78 % faster + # * Yes the truth is to follow i < j and not alter the arragement + # * But in addition i + j == j + i so it wont matter + A = sorted(A) + maxi = -1 + left = 0 + right = len(A)-1 + while left < right: + target = A[left] + A[right] + if target < K: + maxi = max(maxi, target) + left += 1 + else: + right -= 1 + return maxi + + + + + + diff --git a/ProblemSolving/uniqueBinarySearchTrees/uniq.py b/ProblemSolving/uniqueBinarySearchTrees/uniq.py new file mode 100644 index 0000000..6387410 --- /dev/null +++ b/ProblemSolving/uniqueBinarySearchTrees/uniq.py @@ -0,0 +1,29 @@ +class Solution(object): + def numTrees(self, n): + """ + :type n: int + :rtype: int + """ + + # Logic: Dynamic Programming - 100 100 + + # References: + # * https://leetcode.com/problems/unique-binary-search-trees/discuss/232795/python-easy-DP-beats-98 + # * https://leetcode.com/problems/unique-binary-search-trees/discuss/236389/6-lines-python-DP-solution-beats-100-python3-solutions + + # Subproblems for each number of nodes to n + record = [0]*(n+1) + + # Empty node condition + record[0] = 1 + # One node condition + record[1] = 1 + + # iterate for n from 2 to n + for i in range(2, n+1): + # All the previous subproblems are dependant, a choice made previous affects choice as we proceed --> so 1 to i + for j in range(i): + # Update record with the combinations that could occur for a given previous choice == value at j * future values until i + record[i] += record[j] * record[i-j-1] + return record[n] + diff --git a/ProblemSolving/uniqueEmailAddresses/uniq.py b/ProblemSolving/uniqueEmailAddresses/uniq.py new file mode 100644 index 0000000..f7469f6 --- /dev/null +++ b/ProblemSolving/uniqueEmailAddresses/uniq.py @@ -0,0 +1,16 @@ +class Solution(object): + def numUniqueEmails(self, emails): + """ + :type emails: List[str] + :rtype: int + """ + + result = [] + for email in emails: + local_name, domain_name = email.split("@") + local_name = local_name.split("+")[0] + local_name = "".join(local_name.split(".")) + result_email = local_name+"@"+domain_name + if result_email not in result: + result.append(result_email) + return len(result) diff --git a/ProblemSolving/uniqueNumberOfOccurrnces/uniq.py b/ProblemSolving/uniqueNumberOfOccurrnces/uniq.py new file mode 100644 index 0000000..812c4e3 --- /dev/null +++ b/ProblemSolving/uniqueNumberOfOccurrnces/uniq.py @@ -0,0 +1,38 @@ +class Solution(object): + def uniqueOccurrences(self, arr): + """ + :type arr: List[int] + :rtype: bool + """ + + # Logic 1: Exhaustive use of libraries - 64% faster + """ + import collections + counts = collections.Counter(arr) + if sorted(counts.values()) == sorted(set(counts.values())): + return True + else: + return False + """ + + # Logic 2: Another way of using collections - 85% faster + """ + import collections + unique = list(set(collections.Counter(collections.Counter(arr).values()).values())) + return unique[0] == 1 and len(unique) == 1 + """ + + # Logic 3: O(N) Iteration with data structure - 95% faster + # DS + freq = {} + # Iterate and populate DS + for i in range(len(arr)): + if arr[i] not in freq: + freq[arr[i]] = 0 + freq[arr[i]] += 1 + # If no repeated then return true + if len(freq.values()) == len(set(freq.values())) and min(freq.values()) == 1: + return True + else: + return False + diff --git a/ProblemSolving/uniquePaths/uniq.py b/ProblemSolving/uniquePaths/uniq.py new file mode 100644 index 0000000..58ef333 --- /dev/null +++ b/ProblemSolving/uniquePaths/uniq.py @@ -0,0 +1,16 @@ +class Solution: + def uniquePaths(self, m: int, n: int) -> int: + + grid = [[0 for i in range(n)] for i in range(m)] + + grid[0][0] = 1 + + for i in range(m): + for j in range(n): + if i-1 >= 0: + grid[i][j] += grid[i-1][j] + if j-1 >= 0: + grid[i][j] += grid[i][j-1] + + #print(grid) + return grid[m-1][n-1] diff --git a/ProblemSolving/uniquePathsII/uniq.py b/ProblemSolving/uniquePathsII/uniq.py new file mode 100644 index 0000000..d38f906 --- /dev/null +++ b/ProblemSolving/uniquePathsII/uniq.py @@ -0,0 +1,79 @@ +# Logic 1: Brute force --> correct but exceeds time limit +""" +class Solution: + def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int: + + def findWays(current, visited, path): + #print(self.path_exists) + if current in self.path_exists: + self.count += 1 + return + + if current == (len(obstacleGrid)-1, len(obstacleGrid[0])-1): + if obstacleGrid[current[0]][current[1]] != 1: + self.paths.append(path) + self.path_exists = self.path_exists.union(path) + self.count += 1 + return + + if current[1]+1 < len(obstacleGrid[0]): + right = (current[0], current[1]+1) + if right not in visited and obstacleGrid[right[0]][right[1]] != 1: + findWays(right, visited.union({right}), path+[right]) + + if current[0]+1 < len(obstacleGrid): + down = (current[0]+1, current[1]) + if down not in visited and obstacleGrid[down[0]][down[1]] != 1: + findWays(down, visited.union({down}), path+[down]) + + return + + self.paths = [] + self.count = 0 + self.path_exists = set() + if obstacleGrid[0][0] == 1: + return 0 + findWays((0,0), set(), [(0,0)]) + #print(self.paths) + return self.count +""" + +# Logic 2: dynamic prog with tabular values (memo every cell) --> 100 pass +class Solution: + def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int: + + # Tip: only down and right + rows = len(obstacleGrid) + columns = len(obstacleGrid[0]) + + if obstacleGrid[0][0] == 1 or obstacleGrid[rows-1][columns-1] == 1: + return 0 + + obstacleGrid[0][0] = 1 + + # 1st row + for c in range(1, columns): + if obstacleGrid[0][c] == 0 and obstacleGrid[0][c-1] == 1: # only if left cell is 1 we can move here + obstacleGrid[0][c] = 1 + elif obstacleGrid[0][c] == 1: + obstacleGrid[0][c] = 0 + + # 1st column + for r in range(1,rows): + if obstacleGrid[r][0] == 0 and obstacleGrid[r-1][0] == 1: + obstacleGrid[r][0] = 1 + elif obstacleGrid[r][0] == 1: + obstacleGrid[r][0] = 0 + + # All other cells + for r in range(1, rows): + for c in range(1, columns): + if obstacleGrid[r][c] == 1: + obstacleGrid[r][c] = 0 + continue + obstacleGrid[r][c] = obstacleGrid[r-1][c] + obstacleGrid[r][c-1] + + #print(obstacleGrid) + + return obstacleGrid[rows-1][columns-1] + diff --git a/ProblemSolving/univalued_binary_tree/uni.py b/ProblemSolving/univalued_binary_tree/uni.py new file mode 100644 index 0000000..8d9a720 --- /dev/null +++ b/ProblemSolving/univalued_binary_tree/uni.py @@ -0,0 +1,35 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def isUnivalTree(self, root): + """ + :type root: TreeNode + :rtype: bool + """ + + self.uni_value = root.val + self.result = True + + # Recursive traverse + def traverse(node): + + if not node: + return + + if node.val != self.uni_value: + self.result = self.result and False + + if node.left: + traverse(node.left) + if node.right: + traverse(node.right) + + traverse(root) + return self.result + + diff --git a/ProblemSolving/validAnagram/valid2.py b/ProblemSolving/validAnagram/valid2.py new file mode 100644 index 0000000..d464f88 --- /dev/null +++ b/ProblemSolving/validAnagram/valid2.py @@ -0,0 +1,10 @@ +class Solution(object): + def isAnagram(self, s, t): + """ + :type s: str + :type t: str + :rtype: bool + """ + + import collections + return collections.Counter(s) == collections.Counter(t) diff --git a/ProblemSolving/validBoomerang/valid.py b/ProblemSolving/validBoomerang/valid.py new file mode 100644 index 0000000..d6c49f6 --- /dev/null +++ b/ProblemSolving/validBoomerang/valid.py @@ -0,0 +1,42 @@ +class Solution(object): + def isBoomerang(self, points): + """ + :type points: List[List[int]] + :rtype: bool + """ + + # Logic: Using theorem math formula of collinarity + # Reference: http://mathworld.wolfram.com/Collinear.html + # Formula: x_1(y_2-y_3)+x_2(y_3-y_1)+x_3(y_1-y_2)=0 + # * Set is always 3 points as questions says, hence the formula would be an apt match + + proof = points[0][0]*(points[1][1]-points[2][1]) + points[1][0]*(points[2][1]-points[0][1]) + points[2][0]*(points[0][1]-points[1][1]) + if proof == 0: + return False + else: + return True + + """ + # Brute force + # * Some initiative to breaking collinearity + + n = len(points) + delta1 = None + delta2 = None + for i in range(n-1): + p1 = points[i] + p2 = points[i+1] + if not delta1 and not delta2: + delta1 = p2[0] - p1[0] + delta2 = p2[1] - p1[0] + else: + while p1[0]+delta1 < p2[0]: + p1[0] += 1 + while p1[1]+delta2 < p2[1]: + p1[1] += 1 + print p1[0], p1[1] + if p1[0]+delta1 != p2[0] or p1[1]+delta2 != p2[1]: + return True + return False + """ + diff --git a/ProblemSolving/validMountainArray/valid.py b/ProblemSolving/validMountainArray/valid.py new file mode 100644 index 0000000..2b91189 --- /dev/null +++ b/ProblemSolving/validMountainArray/valid.py @@ -0,0 +1,106 @@ +class Solution(object): + def validMountainArray(self, A): + """ + :type A: List[int] + :rtype: bool + """ + + # Condition 1 + if len(A) < 3: + return False + + # Condition 2 + # We have to go to the highest and then reverse to the lowest from there + # A[0].<..A[max]..>.A[n] + + # 100 pass 64 ms faster + # 2 pointer logic to meet at the peak + n = len(A) + left = 0 + right = n-1 + + # Climbing mountain from left to obtain the peak + while left < n-1 and A[left] < A[left+1]: + left += 1 + + # Climbing mountain from right to obtain peak + while right > 0 and A[right] < A[right-1]: + right -= 1 + + # Climbing both sides should have left us at the peak + # Also peak should not be at the start of the end + if left == right and left > 0 and left < n-1: + return True + + return False + + + """ + # 100 pass 64 ms faster + # Break down logic of solving each condition separate + + # Find maximum peak + peak = max(A) + + # There should be only one peak + if A.count(peak) > 1: + return False + + # Index of peak + peak_index = A.index(peak) + + # Peak should not be present in the beginning or the end + if peak_index == len(A)-1 or peak_index == 0: + return False + + # Iterate upward to peak + for i in range(0, peak_index): + if A[i] >= A[i+1]: + return False + + # Iterate downward from peak + for i in range(peak_index+1, len(A)): + if i+1 < len(A) and A[i] <= A[i+1]: + return False + + return True + """ + + """ + # Not 100 pass + # Just compare if both sides of the peak are sorted + # This also fails when both the elements are equal occurring continuously, add check + + peak = max(A) + if A.count(peak) > 1: + return False + peak_index = A.index(peak) + + + if sorted(A[:peak_index+1]) == A[:peak_index+1] and sorted(A[peak_index:]) == A[peak_index:][::-1]: + return True + else: + return False + """ + + """ + # Not 100 pass + # Simple technique - There is should be only one time when the max fall takes place A[i] > A[i+1] else it is not a mountain + # Con: this runs through the full loop though.... + # - this also doesnt work when equal numbers exist + peak = 0 + while A: + current = A.pop() + if A and current > A[-1]: + print A, current + peak += 1 + if peak != 1: + return False + else: + return True + """ + + + + + diff --git a/ProblemSolving/validPalindrome/palin2.py b/ProblemSolving/validPalindrome/palin2.py new file mode 100644 index 0000000..dbafeaf --- /dev/null +++ b/ProblemSolving/validPalindrome/palin2.py @@ -0,0 +1,23 @@ +class Solution(object): + def isPalindrome(self, s): + """ + :type s: str + :rtype: bool + """ + + s = "".join(s.split(" ")) + left = 0 + right = len(s)-1 + while left < right: + if not s[left].isalnum(): + left += 1 + elif not s[right].isalnum(): + right -= 1 + else: + if s[left].lower() != s[right].lower(): + print(s, s[left], s[right], left, right) + return False + left += 1 + right -= 1 + return True + diff --git a/ProblemSolving/validSudoku/valid.py b/ProblemSolving/validSudoku/valid.py new file mode 100644 index 0000000..f35e4e4 --- /dev/null +++ b/ProblemSolving/validSudoku/valid.py @@ -0,0 +1,37 @@ +class Solution(object): + def isValidSudoku(self, board): + """ + :type board: List[List[str]] + :rtype: bool + """ + + # Logic 1: Math way + visited_dict = set() + for i in range(len(board)): + for j in range(len(board[0])): + if board[i][j] != ".": + for x in [(i, board[i][j]), (board[i][j], j), (board[i][j], i//3, j//3)]: + if x in visited_dict: + return False + visited_dict.add(x) + return True + + + # Logic 2: Utilizing String key way --> Dictionary Key Value Way + """ + visited_dict = {} + + for i in range(len(board)): + for j in range(len(board[0])): + if board[i][j] != ".": + row_key = board[i][j] + " in row " + str(i) + column_key = board[i][j] + " in column " + str(j) + box_key = board[i][j] + " in box " + str(i//3) + str(j//3) + if row_key in visited_dict or column_key in visited_dict or box_key in visited_dict: + return False + visited_dict[row_key] = [] + visited_dict[column_key] = [] + visited_dict[box_key] = [] + return True + """ + diff --git a/ProblemSolving/validWordAbbrevation/valid.py b/ProblemSolving/validWordAbbrevation/valid.py new file mode 100644 index 0000000..c28a5ed --- /dev/null +++ b/ProblemSolving/validWordAbbrevation/valid.py @@ -0,0 +1,36 @@ +class Solution(object): + def validWordAbbreviation(self, word, abbr): + """ + :type word: str + :type abbr: str + :rtype: bool + """ + + # Logic 1: Iterate abbrevation with word - 100 pass - 94.25% faster + i = j = 0 + delta = "0" + while i < len(abbr): + print(abbr[i]) + if abbr[i].isalpha(): + j += int(delta) + delta = "0" + if j < len(word) and abbr[i] == word[j]: + i += 1 + j += 1 + else: + return False + else: + while i < len(abbr) and abbr[i].isdigit(): + delta += abbr[i] + if delta == "00": + return False + i += 1 + if j + int(delta) > len(word): + return False + j += int(delta) + if j < len(word): + return False + return True + + + diff --git a/ProblemSolving/validateBinarySearchTree/validate.py b/ProblemSolving/validateBinarySearchTree/validate.py new file mode 100644 index 0000000..d8aceff --- /dev/null +++ b/ProblemSolving/validateBinarySearchTree/validate.py @@ -0,0 +1,104 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def isValidBST(self, root): + """ + :type root: TreeNode + :rtype: bool + """ + + # Logic 1: 92 ms, 6.75% faster and 5.66% space + + # * Get left and right subtree for each node + # * Check if the bst condition is satisfied ( left subtree is less and right subtree is greater ) + + """ + # Recursive function to return the subtree (path) and check for bst satisfaction + def isBst(node): + + # Node Null condition and empty tree condition + if not node: + return [], True + + # Initialize variables to use + left_subtree = right_subtree = [] + lresult = rresult = True + + # Condition to recurse + if node.left: + left_subtree, lresult = isBst(node.left) + if node.right: + right_subtree, rresult = isBst(node.right) + + # BST conditon check, for each node, left subtree is less and right subtree is greater + for l in left_subtree: + if l >= node.val: + lresult = False + for r in right_subtree: + if r <= node.val: + rresult = False + + # Add current node to path for returning subtree + if node: + path = [node.val] + left_subtree + right_subtree + + # Debug + #print(left_subtree, right_subtree, path, lresult, rresult) + + # Exit function with returning subtree and result + return path, lresult and rresult + + # Get the subtree and result + tree, result = isBst(root) + + return result + """ + + # Logic 2: 6% faster + # * Take the in-order traversal of the tree and check if they are sorted + + # Function for in-order traversal + def in_order_traverse(node): + + if node: + # In Order Traverse + # First LEFT + if node.left: + in_order_traverse(node.left) + + # This challenge works under the assumption that BST does not have duplicates + # Find duplicates + if node.val in self.in_order_arrangement: + self.duplicate = True + return False + + # THEN ROOT + self.in_order_arrangement.append(node.val) + + # NEXT RIGHT + if node.right: + in_order_traverse(node.right) + else: + return + + self.duplicate = False + self.in_order_arrangement = [] + in_order_traverse(root) + + # Duplicate node values existence + if self.duplicate: + return False + + # Debug + #print(self.in_order_arrangement, sorted(self.in_order_arrangement), list(set(self.in_order_arrangement))) + + # If arrangement is already in the sorted form from left to right then it is a valid BST + if sorted(self.in_order_arrangement) == self.in_order_arrangement: + return True + else: + return False diff --git a/ProblemSolving/validateBinarySearchTree/validate2.py b/ProblemSolving/validateBinarySearchTree/validate2.py new file mode 100644 index 0000000..34543b1 --- /dev/null +++ b/ProblemSolving/validateBinarySearchTree/validate2.py @@ -0,0 +1,42 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def isValidBST(self, root): + """ + :type root: TreeNode + :rtype: bool + """ + # Logic 2: + def traverse(node, left, right): + if not node: + return True + if not left < node.val < right: + return False + return traverse(node.left, left, node.val) and traverse(node.right, node.val, right) + + return traverse(root, -float('inf'), float('inf')) + + # Logic 1: PreOrder traverse and compare + + """ + def traverse(node): + if node: + if node.left: + traverse(node.left) + self.nodes.append(node.val) + if node.right: + traverse(node.right) + + self.nodes = [] + traverse(root) + print(set(self.nodes)) + if sorted(set(self.nodes)) == self.nodes: + return True + else: + return False + """ diff --git a/ProblemSolving/verifyingAlienDictionary/verify.py b/ProblemSolving/verifyingAlienDictionary/verify.py new file mode 100644 index 0000000..becb3a3 --- /dev/null +++ b/ProblemSolving/verifyingAlienDictionary/verify.py @@ -0,0 +1,73 @@ +class Solution(object): + def isAlienSorted(self, words, order): + """ + :type words: List[str] + :type order: str + :rtype: bool + """ + + """ + # This logic is for each word to be lexicographic. the question asks you to do lexicographic of the words + result = True + # Brute force + for word in words: + temp = list(word) + prev = -1 + while temp: + for j in range(len(order)): + if order[j] == temp[0] and prev < j: + del temp[0] + prev = j + break + + if temp == []: + result = result and True + else: + result = result and False + return result + """ + + # 2 pointer method + + # Firstly, if there is a length decrease down the line (based on null logic), it would be a false + sort_by_len = sorted(words, key = len) + if sort_by_len == words: + return True + #else: + # return False + + # Secondly iterate by index for all the entries in the array (instead of iterating 2 by 2 or 3 by 3) + n = len(words) + indexes = [0]*n + + def sort_by_order(ch): + if ch == None: + return len(order) + return order.index(ch) + + maxi = len(sort_by_len[-1]) + for j in range(maxi): + for i in range(len(words)): + if j >= len(words[i]): + indexes[i] = None + else: + indexes[i] = words[i][j] + + if sorted(indexes,key=sort_by_order) == indexes: + continue + else: + print indexes + return False + return True + + """ + # List of lists logic may not work with this logic + # Sorted logic method + def sort_by_order(ch): + return order.index(ch) + + if sorted(words, key = sort_by_order) == words: + return True + else: + return False + """ diff --git a/ProblemSolving/verifyingAlienDictionary/verify2.py b/ProblemSolving/verifyingAlienDictionary/verify2.py new file mode 100644 index 0000000..13b34fa --- /dev/null +++ b/ProblemSolving/verifyingAlienDictionary/verify2.py @@ -0,0 +1,37 @@ +class Solution(object): # mock + def isAlienSorted(self, words, order): + """ + :type words: List[str] + :type order: str + :rtype: bool + """ + + # Hacky + """ + if sorted(words, key=lambda x: sorted(x, key=lambda y: order.index(y)) and len(x)) != words: + return False + return True + """ + + # build dictionary + position = {} + for w in range(len(order)): + position[order[w]] = w + + for i in range(len(words)-1): + word1 = list(words[i]) + word2 = list(words[i+1]) + while word1 and word2: + print(word1, word2) + char1 = word1.pop(0) + char2 = word2.pop(0) + if position[char1] > position[char2]: + return False + elif position[char1] < position[char2]: + break + else: + if word1 and not word2: + return False + #if word1 and not word2: + # return False + return True diff --git a/ProblemSolving/verifyingAlienDictionary/verify3.py b/ProblemSolving/verifyingAlienDictionary/verify3.py new file mode 100644 index 0000000..15c111a --- /dev/null +++ b/ProblemSolving/verifyingAlienDictionary/verify3.py @@ -0,0 +1,36 @@ +class Solution: + def isAlienSorted(self, words: List[str], order: str) -> bool: + + i = 0 + + ref = {} + for j, o in enumerate(order): + if o not in ref: + ref[o] = j + + while words and i < float('inf'): + + position_chars = [] + + for w, word in enumerate(words): + if i >= len(word): + if position_chars: + return False + continue + + print(i, word, position_chars) + + if position_chars and ref[word[i]] < ref[position_chars[-1]]: + #print(word[i], ref[word[i]], position_chars[-1], ref[position_chars[-1]]) + return False + elif position_chars and ref[word[i]] > ref[position_chars[-1]]: + words.pop(w) + else: + pass + + position_chars.append(word[i]) + + if position_chars == []: + return True + + i += 1 diff --git a/ProblemSolving/verifyingAnAlienDictionary/verify.py b/ProblemSolving/verifyingAnAlienDictionary/verify.py new file mode 100644 index 0000000..9d6502f --- /dev/null +++ b/ProblemSolving/verifyingAnAlienDictionary/verify.py @@ -0,0 +1,45 @@ +class Solution(object): + def isAlienSorted(self, words, order): + """ + :type words: List[str] + :type order: str + :rtype: bool + """ + + # 1. Store the indexes of each letter in dictionary for easy access + alp_order = {} + alp_order[""] = -1 + for ch in range(len(order)): + alp_order[order[ch]] = ch + + # 2. Compare function to compare 2 strings + def compare_words(w1, w2): + n = max(len(w1), len(w2)) + for c in range(n): + # Character is null if index is greater than the string + if c < len(w1): + char1 = w1[c] + else: + char1 = "" + if c < len(w2): + char2 = w2[c] + else: + char2 = "" + + # Sort when characters are set + if alp_order[char1] < alp_order[char2]: # Lesser + return -1 + elif alp_order[char2] < alp_order[char1]: # Greater + return 1 + + return 0 # equal condition + + # 2. Sort based on the index of order and check + print(sorted(words, cmp=compare_words)) + if words == sorted(words, cmp=compare_words): + return True + else: + return False + + + diff --git a/ProblemSolving/verticalOrderTraversalOfABinaryTree/vertical.py b/ProblemSolving/verticalOrderTraversalOfABinaryTree/vertical.py new file mode 100644 index 0000000..c76279d --- /dev/null +++ b/ProblemSolving/verticalOrderTraversalOfABinaryTree/vertical.py @@ -0,0 +1,47 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right +class Solution: + def verticalTraversal(self, root: Optional[TreeNode]) -> List[List[int]]: + + self.cols = {} + self.levels = {} + + def traverseByLevel(node, level, r, c): + + if not node: + return + + if c not in self.cols: + self.cols[c] = [] + if c not in self.levels: + self.levels[c] = [] + + if self.levels[c] and self.levels[c][-1] >= level: + i = len(self.levels[c])-1 + while i >= 0 and self.levels[c][i] > level: + i -= 1 + while i >= 0 and self.levels[c][i] == level and self.cols[c][i] > node.val: + i -= 1 + self.levels[c] = self.levels[c][:i+1] + [level] + self.levels[c][i+1:] + self.cols[c] = self.cols[c][:i+1] + [node.val] + self.cols[c][i+1:] + else: + self.cols[c].append(node.val) + self.levels[c].append(level) + + if node.left: + traverseByLevel(node.left, level+1, r+1, c-1) + if node.right: + traverseByLevel(node.right, level+1, r+1, c+1) + + + traverseByLevel(root, 0, 0, 0) + + result = [] + for k in sorted(self.cols.keys()): + result.append(self.cols[k]) + + return result diff --git a/ProblemSolving/waterBottles/water.py b/ProblemSolving/waterBottles/water.py new file mode 100644 index 0000000..434ddb5 --- /dev/null +++ b/ProblemSolving/waterBottles/water.py @@ -0,0 +1,15 @@ +class Solution(object): + def numWaterBottles(self, numBottles, numExchange): + """ + :type numBottles: int + :type numExchange: int + :rtype: int + """ + + # Logic 1: Use div/modulo of numExchange to loop - lt easy - 100 pass - 20% faster + result = 0 + while numBottles >= numExchange: + result += numBottles//numExchange * numExchange + numBottles = numBottles//numExchange + numBottles%numExchange + #print(numBottles, result) + return result + numBottles diff --git a/ProblemSolving/webCrawler/web.py b/ProblemSolving/webCrawler/web.py new file mode 100644 index 0000000..d331640 --- /dev/null +++ b/ProblemSolving/webCrawler/web.py @@ -0,0 +1,31 @@ +# """ +# This is HtmlParser's API interface. +# You should not implement it, or speculate about its implementation +# """ +#class HtmlParser(object): +# def getUrls(self, url): +# """ +# :type url: str +# :rtype List[str] +# """ + +class Solution(object): + def crawl(self, startUrl, htmlParser): + """ + :type startUrl: str + :type htmlParser: HtmlParser + :rtype: List[str] + """ + + # Logic 1: Backtrack and Recurse --> 23 % faster 100 pass + def back_track_crawl(start, parser, valid): + crawled = parser.getUrls(start) + for url in crawled: + if self.domain in url and url not in valid: + valid.add(url) + back_track_crawl(url, parser, valid) + return valid + + self.domain = startUrl.strip("https://") + self.domain = self.domain.split("/")[0] + return back_track_crawl(startUrl, htmlParser, {startUrl}) diff --git a/ProblemSolving/wordPattern/word2.py b/ProblemSolving/wordPattern/word2.py new file mode 100644 index 0000000..9018444 --- /dev/null +++ b/ProblemSolving/wordPattern/word2.py @@ -0,0 +1,27 @@ +class Solution(object): + def wordPattern(self, pattern, str): + """ + :type pattern: str + :type str: str + :rtype: bool + """ + + # Logic 1: + # We loose the positions of the characters in string.. so this wont work + #return len(set(pattern)) == len(set(str.split(" "))) + + # Logic 2: + relation = {} + visited = set() + s = str.split(" ") + if len(s) != len(pattern): + return False + for i, j in zip(pattern, s): + if i not in relation and j not in visited: + relation[i] = j + visited.add(j) + if i in relation and relation[i] == j: + pass + else: + return False + return True diff --git a/ProblemSolving/wordPattern/word3.py b/ProblemSolving/wordPattern/word3.py new file mode 100644 index 0000000..c4b7f22 --- /dev/null +++ b/ProblemSolving/wordPattern/word3.py @@ -0,0 +1,28 @@ +class Solution: + def wordPattern(self, pattern: str, s: str) -> bool: + + words = s.split(" ") + pattern_ref = {} + value_ref = set() + + # build pattern for reference + for i in list(pattern): + if i not in pattern_ref: + pattern_ref[i] = "" + + if len(words) != len(pattern): + return False + + # check the words + for w in range(len(words)): + word = words[w] + if pattern_ref[pattern[w]] == "" and word in value_ref: + return False + elif pattern_ref[pattern[w]] == "": + pattern_ref[pattern[w]] = word + value_ref.add(word) + elif pattern_ref[pattern[w]] == word: + continue + else: + return False + return True diff --git a/ProblemSolving/wordSearch/word.py b/ProblemSolving/wordSearch/word.py new file mode 100644 index 0000000..92dc170 --- /dev/null +++ b/ProblemSolving/wordSearch/word.py @@ -0,0 +1,66 @@ +class Solution(object): + def exist(self, board, word): + """ + :type board: List[List[str]] + :type word: str + :rtype: bool + """ + + # Logic 1: All passed except for scale testcase leading to time limit exceeded --> Fix below + # * Follow all the adjacent paths through the matrix should work + # * Disadvantage is when 2 or more possible path exists --> Solution is to recurse + """ + def recurse_and_match(current, remaining, board, path): + + print(current, len(remaining)) + + # Match has occurred + if remaining == "": + self.match = True + return + + # Possible start of match + if current == None: + for r in range(len(board)): + for c in range(len(board[0])): + if board[r][c] == remaining[0]: + recurse_and_match((r,c), remaining[1:], board, [(r,c)]) + return + else: + # Progressive match as we proceed + r, c = current + for x,y in [ (1,0), (-1,0), (0,1), (0,-1) ]: + #print(r+x, c+y, remaining[0], path) + if 0 <= r+x < len(board) and 0 <= c+y < len(board[0]) and (r+x, c+y) not in path and remaining[0] == board[r+x][c+y]: + recurse_and_match((r+x, c+y), remaining[1:], board, path + [(r+x, c+y)]) + return + + self.match = False + recurse_and_match(None, word, board, []) + return self.match + """ + + # Segregate, Recurse and Return --> Use a visited memory to track instead of a list to traverse extra (path above) + def recurse_and_match(r, c, remaining, board): + + # Match has occurred + if remaining == "": + return True + + # Progressive match as we proceed + self.visited[r][c] = 1 + for x,y in [ (r+1,c), (r-1,c), (r,c+1), (r,c-1) ]: + if 0 <= x < len(board) and 0 <= y < len(board[0]) and self.visited[x][y] == 0 and remaining[0] == board[x][y]: + if recurse_and_match(x, y, remaining[1:], board): + return True + self.visited[r][c] = 0 + return False + + # Possible start of match + self.visited = [[0]*len(board[0]) for _ in range(len(board))] + for r in range(len(board)): + for c in range(len(board[0])): + if board[r][c] == word[0] and recurse_and_match(r, c, word[1:], board): + return True + return False + diff --git a/ProblemSolving/wordSquare/wordsq.py b/ProblemSolving/wordSquare/wordsq.py new file mode 100644 index 0000000..8225ca9 --- /dev/null +++ b/ProblemSolving/wordSquare/wordsq.py @@ -0,0 +1,22 @@ +class Solution: + def validWordSquare(self, words: List[str]) -> bool: + # Logic 1: Construct row wise and column wise matrix and then verify equality - 100 pass - 65% faster + # 1. row wise arrangement of each word + matrix = [] # [word.split("") for word in words] + n = len(words[0]) + for word in words: + word = list(word) + matrix.append(word) + n = max(n, len(word)) + # 2. column wise arrangement of each word ( transpose of a matrix ) + columnwise = [[0 for i in range(len(matrix))] for i in range(n)] + #print(matrix, columnwise, n) + for i in range(len(matrix)): + if len(matrix[i]) < n: + matrix[i].extend([0]*(n-len(matrix[i]))) + for j in range(n): + #print(columnwise, matrix, i, j) + columnwise[j][i] = matrix[i][j] + if matrix == columnwise: + return True + return False diff --git a/ProblemSolving/wordSubsets/word.py b/ProblemSolving/wordSubsets/word.py new file mode 100644 index 0000000..d9cf359 --- /dev/null +++ b/ProblemSolving/wordSubsets/word.py @@ -0,0 +1,50 @@ +class Solution(object): + def wordSubsets(self, A, B): + """ + :type A: List[str] + :type B: List[str] + :rtype: List[str] + """ + + import collections + universal = [] + sort = [0]*len(B) + + for word in A: + count = 0 + superset = collections.Counter(word) + for subset in range(len(B)): + if sort[subset] == 0: + B[subset] = collections.Counter(B[subset]) + sort[subset] = 1 + intersection = list((B[subset] & superset).elements()) + #print intersection, B[subset], superset + if len(intersection) == sum(B[subset].values()) : + count += 1 + #print count + if count == len(B): + universal.append(word) + return universal + + + """ + # Logic: Subset with sorted ( Doesnt work when high delta sep characters are present ) + universal = [] + sort = [0]*len(B) + + for word in A: + count = 0 + superset = "".join(sorted(word)) + for subset in range(len(B)): + if sort[subset] == 0: + B[subset] = "".join(sorted(B[subset])) + sort[subset] = 1 + print B[subset], superset + if B[subset] in superset: + count += 1 + print count + if count == len(B): + universal.append(word) + return universal + """ + diff --git a/ProblemSolving/wordSubsets/word2.py b/ProblemSolving/wordSubsets/word2.py new file mode 100644 index 0000000..01eb594 --- /dev/null +++ b/ProblemSolving/wordSubsets/word2.py @@ -0,0 +1,79 @@ +class Solution: + def wordSubsets(self, words1: List[str], words2: List[str]) -> List[str]: + + universal = [] + + # All subsets combined together + subsets = {} + for w in words2: + curr = {} + for c in w: + if c not in curr: + curr[c] = 0 + curr[c] += 1 + for k, v in curr.items(): + if k not in subsets: + subsets[k] = v + continue + subsets[k] = max(subsets[k], v) + + # Iterate to check for universal + for word in words1: + ref = {} + for i in range(len(word)): + if word[i] not in ref: + ref[word[i]] = 0 + ref[word[i]] += 1 + + isASubset = True + matched = 0 + for k,v in ref.items(): + if k not in subsets: + continue + if subsets[k] > v: + isASubset = False + break + matched += 1 + + print(matched, isASubset, ref, subsets) + if isASubset and matched == len(subsets): + universal.append(word) + + return universal + + + """ + # checking one by one wont help. We shld combine the subsets + + universal = [] + + for word in words1: + ref = {} + for i in range(len(word)): + if word[i] not in ref: + ref[word[i]] = 0 + ref[word[i]] += 1 + subset = True + counts = 0 + for word2 in words2: + if not subset: + break + r = ref.copy() + count =0 + for ch in word2: + if ch not in r: + break + if r[ch] == 0: + break + r[ch] -= 1 + count += 1 + if count == len(word2): + subset = True + counts += 1 + else: + subset = False + if counts == len(words2): + universal.append(word) + + return universal + """ diff --git a/README.md b/README.md index 7648edd..84f1e8c 100644 --- a/README.md +++ b/README.md @@ -22,215 +22,424 @@ * [Sorting](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/AlgorithmConcepts/sorting) ### Problem Solving: +Has all the problem solving question solution (mostly in python, updating in different languages are welcome!) -* [Balanced Brackets](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/BalancedBrackets) +* [judgeRouteCircle](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/judgeRouteCircle) +* [arriveAtK](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/arriveAtK) +* [expressiveWords](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/expressiveWords) +* [romanToNumeral](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/romanToNumeral) +* [sherlockAndValidString](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/sherlockAndValidString) +* [printBinaryTree](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/printBinaryTree) +* [dominator](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/dominator) +* [keyboardRow](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/keyboardRow) +* [heaters](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/heaters) +* [removeDuplicatesFromSortedList](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/removeDuplicatesFromSortedList) +* [removeElement](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/removeElement) +* [firstBadVersion](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/firstBadVersion) +* [photoName](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/photoName) +* [palindromeIndex](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/palindromeIndex) +* [findKClosestElements](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/findKClosestElements) +* [naryTreeLevelOrderTraversal](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/naryTreeLevelOrderTraversal) +* [findBottomLeftTreeValue](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/findBottomLeftTreeValue) +* [iceCreamParlour](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/iceCreamParlour) +* [deleteAndEarn](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/deleteAndEarn) +* [findMinTimeDifference](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/findMinTimeDifference) +* [sumOfSquareNumbers](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/sumOfSquareNumbers) +* [rotateString](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/rotateString) +* [diStringMatch](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/diStringMatch) +* [longestContinuousIncreasingSequence](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/longestContinuousIncreasingSequence) +* [needleHaystack](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/needleHaystack) +* [studentAttendanceRecord1](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/studentAttendanceRecord1) +* [absDistinctValues](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/absDistinctValues) +* [isomorphicString](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/isomorphicString) +* [mostCommonWord](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/mostCommonWord) +* [caesarCipher](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/caesarCipher) +* [findModeInBinarySearchTree](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/findModeInBinarySearchTree) +* [containsDuplicates](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/containsDuplicates) +* [palindromicSubstrings](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/palindromicSubstrings) +* [interface](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/interface) +* [distinctElements](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/distinctElements) +* [productExceptSelf](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/productExceptSelf) +* [divisibleSumPairs](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/divisibleSumPairs) +* [uncommonWordsFromTwoSentence](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/uncommonWordsFromTwoSentence) +* [beautifulDaysAtMovies](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/beautifulDaysAtMovies) +* [containerWithMostWater](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/containerWithMostWater) +* [tapeEquillibrium](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/tapeEquillibrium) +* [minPerimeterRectangle](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/minPerimeterRectangle) +* [searchRange](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/searchRange) +* [deleteOperationForTwoStrings](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/deleteOperationForTwoStrings) +* [mergeIntervals](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/mergeIntervals) +* [validPerfectSquare](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/validPerfectSquare) +* [minimumAbsoluteDifference](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/minimumAbsoluteDifference) +* [validPalindrome](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/validPalindrome) +* [levelOrderTraversal](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/levelOrderTraversal) +* [nextGreaterElementI](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/nextGreaterElementI) +* [numberSolitaire](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/numberSolitaire) +* [positionOfLargeGroups](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/positionOfLargeGroups) +* [reverseString](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/reverseString) +* [CoinsCounting](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/CoinsCounting) +* [intersectionOfTwoLinkedList](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/intersectionOfTwoLinkedList) +* [classesMoreThan5Students](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/classesMoreThan5Students) +* [nonOverlappSegments](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/nonOverlappSegments) +* [longestCommonPrefix](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/longestCommonPrefix) +* [validAnagram](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/validAnagram) +* [flags](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/flags) +* [implementTriePrefixTree](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/implementTriePrefixTree) +* [triesContacts](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/triesContacts) +* [uniqMorseCodeWords](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/uniqMorseCodeWords) +* [deleteDuplicateEmails](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/deleteDuplicateEmails) +* [simpleDatabase](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/simpleDatabase) +* [binaryTreePaths](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/binaryTreePaths) +* [findAllDuplicatesInAnArray](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/findAllDuplicatesInAnArray) +* [excelSheelColumnNumber](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/excelSheelColumnNumber) +* [scoreOfParanthesis](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/scoreOfParanthesis) +* [tennisTournament](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/tennisTournament) +* [mapSumPairs](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/mapSumPairs) +* [mergeSortedLists](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/mergeSortedLists) +* [WordCount](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/WordCount) +* [lowestCommonAncestorOfABinaryTree](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/lowestCommonAncestorOfABinaryTree) +* [minimumTimeDifference](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/minimumTimeDifference) +* [degreeOfAnArray](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/degreeOfAnArray) +* [reachNumber](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/reachNumber) +* [subTreeOfAnotherTree](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/subTreeOfAnotherTree) +* [mergeSortedArray](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/mergeSortedArray) +* [countTriangles](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/countTriangles) +* [minHeightBst](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/minHeightBst) +* [binaryTreeInOrderTraversal](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/binaryTreeInOrderTraversal) +* [lonelyInteger](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/lonelyInteger) +* [deleteNode](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/deleteNode) +* [luckBalance](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/luckBalance) +* [twoSumsIV](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/twoSumsIV) +* [ransomNote](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/ransomNote) +* [reverseStringII](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/reverseStringII) +* [funnyString](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/funnyString) +* [nextGreaterElementII](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/nextGreaterElementII) +* [priyankatoys](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/priyankatoys) +* [bfsBST](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/bfsBST) +* [fairCandySwap](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/fairCandySwap) +* [customSortString](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/customSortString) +* [makingAnagrams](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/makingAnagrams) +* [peakIndexInMountainArray](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/peakIndexInMountainArray) +* [reverseVowels](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/reverseVowels) +* [anagram](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/anagram) +* [teemoAttacking](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/teemoAttacking) +* [DepthBST](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/DepthBST) +* [convertNumberToHexadecimal](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/convertNumberToHexadecimal) +* [132pattern](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/132pattern) +* [isPalindromeInteger](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/isPalindromeInteger) +* [subdomainVisitCount](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/subdomainVisitCount) +* [bfsShortestReach](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/bfsShortestReach) +* [Pairs](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/Pairs) +* [maximumBinaryTree](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/maximumBinaryTree) +* [setMismatch](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/setMismatch) +* [linkedListComponents](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/linkedListComponents) +* [rankScores](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/rankScores) +* [repeatedStringMatch](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/repeatedStringMatch) +* [countCars](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/countCars) +* [invertBinaryTree](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/invertBinaryTree) +* [linkedListCycle](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/linkedListCycle) +* [minimumMovesToEqualArrayElements](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/minimumMovesToEqualArrayElements) +* [twoLists](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/twoLists) +* [findSmallestLetterGreaterThanTarget](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/findSmallestLetterGreaterThanTarget) +* [BalancedBrackets](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/BalancedBrackets) +* [cakeWalk](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/cakeWalk) +* [superReducedString](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/superReducedString) +* [middleOfTheLinkedList](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/middleOfTheLinkedList) +* [reverseLinkedList](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/reverseLinkedList) +* [numBetweenIdenticalValue](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/numBetweenIdenticalValue) +* [CommonChild](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/CommonChild) +* [stringCompression](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/stringCompression) +* [strangeCounter](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/strangeCounter) +* [gameProgs](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/gameProgs) +* [binarySearch](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/binarySearch) +* [singleElementInASortedArray](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/singleElementInASortedArray) +* [nonDecreasingArray](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/nonDecreasingArray) +* [semiPrimes](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/semiPrimes) +* [topKFrequentElements](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/topKFrequentElements) +* [sumIntegerWithoutPlus](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/sumIntegerWithoutPlus) +* [1bitAnd2bitCharacters](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/1bitAnd2bitCharacters) +* [factorial](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/factorial) +* [maxHeightBst](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/maxHeightBst) +* [findPeakElement](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/findPeakElement) +* [minStack](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/minStack) +* [numberOfLinesToWriteString](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/numberOfLinesToWriteString) +* [maximizingXor](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/maximizingXor) +* [recursionDavisStaircase](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/recursionDavisStaircase) +* [almostSorted](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/almostSorted) +* [queue2Stacks](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/queue2Stacks) +* [rectangleIntersect](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/rectangleIntersect) +* [bonAppetit](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/bonAppetit) +* [oddOccurrencesArray](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/oddOccurrencesArray) +* [jumpOutsideArray](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/jumpOutsideArray) +* [intersectionOfTwoArray](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/intersectionOfTwoArray) +* [pascalTriangle](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/pascalTriangle) +* [longestHarmoniousSubSequence](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/longestHarmoniousSubSequence) +* [alternateCharacters](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/alternateCharacters) +* [coursesOrder](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/coursesOrder) +* [licenseKeyFormatting](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/licenseKeyFormatting) +* [magicalString](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/magicalString) +* [loveLetterMysteryMakePalindrome](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/loveLetterMysteryMakePalindrome) +* [perfectNumber](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/perfectNumber) +* [largestPermutation](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/largestPermutation) +* [numberOfRecentCalls](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/numberOfRecentCalls) +* [countAndSay](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/countAndSay) +* [numberOfSegmentsInAString](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/numberOfSegmentsInAString) +* [reverseBits](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/reverseBits) +* [sortedArrayToBST](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/sortedArrayToBST) +* [risingTemperature](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/risingTemperature) +* [tenthLine](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/tenthLine) +* [houseRobber](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/houseRobber) +* [reverseInteger](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/reverseInteger) +* [emailAddressCreator](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/emailAddressCreator) +* [sameTree](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/sameTree) +* [encodeDecodeTinyUrl](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/encodeDecodeTinyUrl) +* [tripletMultiple](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/tripletMultiple) +* [nimGame](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/nimGame) +* [counterGame](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/counterGame) +* [addTwoNumbersLinkedList](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/addTwoNumbersLinkedList) +* [missingSmallestElement](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/missingSmallestElement) +* [arrangingCoins](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/arrangingCoins) +* [jimAndOrder](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/jimAndOrder) +* [hackerRankInString](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/hackerRankInString) +* [makingAnagrams2](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/makingAnagrams2) +* [notBoringMovies](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/notBoringMovies) +* [gameOfThrones1](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/gameOfThrones1) +* [backspaceStringCompare](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/backspaceStringCompare) +* [canPlaceFlowers](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/canPlaceFlowers) +* [findAndReplacePattern](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/findAndReplacePattern) +* [replaceWords](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/replaceWords) +* [base7](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/base7) +* [toLowerCase](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/toLowerCase) +* [numberComplement](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/numberComplement) +* [findAllNumbersDisappearedInAnArray](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/findAllNumbersDisappearedInAnArray) +* [maxDisjointSetSum](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/maxDisjointSetSum) +* [combinationSum](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/combinationSum) +* [factorialTrailingZeros](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/factorialTrailingZeros) +* [levelOrderTraversalII](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/levelOrderTraversalII) +* [countZeroBinary](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/countZeroBinary) +* [arrayRotation](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/arrayRotation) +* [shortestDistanceToCharacter](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/shortestDistanceToCharacter) +* [letterCasePermutation](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/letterCasePermutation) +* [kthLargestInAStream](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/kthLargestInAStream) +* [maximizeDistanceToClosestPerson](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/maximizeDistanceToClosestPerson) +* [findDuplicateFileInSystem](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/findDuplicateFileInSystem) +* [lowestCommonAncestorOfABinarySearchTree](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/lowestCommonAncestorOfABinarySearchTree) +* [robotSimulator](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/robotSimulator) +* [extraLongFactorials](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/extraLongFactorials) +* [designLinkedList](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/designLinkedList) +* [migratingBirds](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/migratingBirds) +* [singleNumber](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/singleNumber) +* [arrayNesting](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/arrayNesting) +* [findMaxAverage](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/findMaxAverage) +* [sqrt](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/sqrt) +* [simplifyPath](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/simplifyPath) +* [NthDigit](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/NthDigit) * [equiLeader](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/equiLeader) +* [lengthOfLastWord](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/lengthOfLastWord) +* [firstUniqueCharacterInString](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/firstUniqueCharacterInString) +* [minCostClimbingStairs](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/minCostClimbingStairs) +* [jewelAndStones](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/jewelAndStones) +* [increasingOrderSearchTree](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/increasingOrderSearchTree) +* [findAnagrams](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/findAnagrams) +* [implementQueueUsingStacks](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/implementQueueUsingStacks) +* [letterFreqFix](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/letterFreqFix) +* [maxMin](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/maxMin) +* [closestNumbers](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/closestNumbers) +* [swapSalary](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/swapSalary) +* [binaryWatch](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/binaryWatch) +* [removeKDigits](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/removeKDigits) +* [sumVsXor](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/sumVsXor) +* [saveThePrisoner](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/saveThePrisoner) +* [gradingStudents](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/gradingStudents) +* [climbStairs](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/climbStairs) +* [stringConstruction](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/stringConstruction) +* [shortestUnsortedContinuousubarray](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/shortestUnsortedContinuousubarray) +* [flippingBits](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/flippingBits) +* [intersectionOfTwoArrayII](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/intersectionOfTwoArrayII) +* [reshapeMatrix](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/reshapeMatrix) +* [perfectBinaryString](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/perfectBinaryString) +* [longestPalindrome](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/longestPalindrome) +* [baseballGame](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/baseballGame) +* [rangeSumQueryImmutable](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/rangeSumQueryImmutable) +* [bitManipulationLonelyInteger](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/bitManipulationLonelyInteger) +* [stairCase](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/stairCase) * [longestPassword](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/longestPassword) +* [sortArrayByParityII](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/sortArrayByParityII) +* [findSecondMinimumInABinaryTree](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/findSecondMinimumInABinaryTree) +* [constructStringFromBinaryTree](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/constructStringFromBinaryTree) +* [averageOfLevelsInBinaryTree](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/averageOfLevelsInBinaryTree) +* [rotateList](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/rotateList) +* [arrayPartitionI](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/arrayPartitionI) +* [minimumAddToMakeParanthesesValid](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/minimumAddToMakeParanthesesValid) +* [buddyStrings](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/buddyStrings) +* [assignCookie](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/assignCookie) +* [subArraySumEqualsK](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/subArraySumEqualsK) +* [happyNumber](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/happyNumber) +* [maximumProductOfWordLengths](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/maximumProductOfWordLengths) +* [subSetsII](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/subSetsII) +* [toeplitzMatrix](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/toeplitzMatrix) +* [kangaroo](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/kangaroo) +* [addDigits](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/addDigits) +* [searchInsertPosition](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/searchInsertPosition) +* [exchangeSeats](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/exchangeSeats) +* [goatLatin](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/goatLatin) +* [findTheDifference](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/findTheDifference) +* [integerReplacement](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/integerReplacement) +* [leafSimilarTrees](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/leafSimilarTrees) +* [selfDividingNumbers](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/selfDividingNumbers) * [fiboModifiedCliq](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/fiboModifiedCliq) +* [rotateFunction](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/rotateFunction) * [stringSymmetry](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/stringSymmetry) +* [shuffleAnArray](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/shuffleAnArray) +* [bigCountries](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/bigCountries) +* [pascalTriangleII](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/pascalTriangleII) +* [maximumProductSubArray](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/maximumProductSubArray) * [missingElement](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/missingElement) +* [rotatedDigits](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/rotatedDigits) +* [longestSubstringWithoutRepeatingCharacters](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/longestSubstringWithoutRepeatingCharacters) +* [addStrings](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/addStrings) +* [pathSumIII](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/pathSumIII) +* [secondHighestSalary](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/secondHighestSalary) * [twitt](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/twitt) +* [duplicateEmails](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/duplicateEmails) * [FrogJmp](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/FrogJmp) +* [partitionLabels](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/partitionLabels) +* [rotateArray](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/rotateArray) +* [removeDuplicatesSortedArray](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/removeDuplicatesSortedArray) +* [addTwoNumbersII](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/addTwoNumbersII) +* [dailyTemperature](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/dailyTemperature) +* [rangeSumQueryMutable](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/rangeSumQueryMutable) +* [twoSumsII](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/twoSumsII) +* [Apples&Oranges](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/Apples&Oranges) +* [combineTwoTables](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/combineTwoTables) +* [majorityElement](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/majorityElement) * [countDiv](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/countDiv) +* [implementStacksUsingQueue](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/implementStacksUsingQueue) +* [abbrevation](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/abbrevation) +* [lemonadeChange](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/lemonadeChange) * [fibonacci](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/fibonacci) +* [repeatedSubstringPattern](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/repeatedSubstringPattern) * [isBalancedTree](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/isBalancedTree) +* [minimumAbsoluteDifferenceInBST](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/minimumAbsoluteDifferenceInBST) +* [dayOfTheProgrammer](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/dayOfTheProgrammer) +* [longPressedName](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/longPressedName) * [countFactors](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/countFactors) +* [validateStackSequences](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/validateStackSequences) * [maxProfitSlicing](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/maxProfitSlicing) +* [reverseWordsInStringIII](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/reverseWordsInStringIII) * [linkedListRemoveDuplicates](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/linkedListRemoveDuplicates) +* [miniMaxSum](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/miniMaxSum) +* [constructTheRectangle](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/constructTheRectangle) +* [employeeImportance](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/employeeImportance) * [stoneWall](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/stoneWall) +* [missingNumber](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/missingNumber) +* [naryTreePostOrderTraversal](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/naryTreePostOrderTraversal) * [triangleTriplet](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/triangleTriplet) +* [convertBSTtoGreaterTree](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/convertBSTtoGreaterTree) +* [missingNumbers](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/missingNumbers) +* [addBinary](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/addBinary) +* [containsDuplicatesII](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/containsDuplicatesII) +* [battleshipsInABoard](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/battleshipsInABoard) +* [detectCapital](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/detectCapital) +* [consecutiveNums](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/consecutiveNums) +* [kthSmallestElementInABst](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/kthSmallestElementInABst) +* [phraseSearch](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/phraseSearch) +* [gameOfTree](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/gameOfTree) +* [binaryTreePostOrderTraversal](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/binaryTreePostOrderTraversal) +* [uglyNumber](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/uglyNumber) +* [largestTimeFromDigits](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/largestTimeFromDigits) +* [longestWordDictionary](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/longestWordDictionary) +* [beautifulPairs](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/beautifulPairs) * [isBST](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/isBST) +* [kDiffPairsInAnArray](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/kDiffPairsInAnArray) +* [sumOfLeftLeafBinaryTree](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/sumOfLeftLeafBinaryTree) * [permutationCheck](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/permutationCheck) +* [queueReconstructionByHeight](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/queueReconstructionByHeight) +* [maxConsecutiveOnes](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/maxConsecutiveOnes) +* [compareVersionNumbers](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/compareVersionNumbers) +* [countPrimes](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/countPrimes) +* [designCircularDeque](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/designCircularDeque) +* [wordPattern](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/wordPattern) * [zeroCollect](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/zeroCollect) +* [maximumProductOfThreeNumbers](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/maximumProductOfThreeNumbers) +* [bigSorting](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/bigSorting) +* [validPalindromeII](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/validPalindromeII) +* [separateTheNumbers](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/separateTheNumbers) +* [linkedListRandomNode](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/linkedListRandomNode) +* [xOfAKindInADeckOfCards](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/xOfAKindInADeckOfCards) +* [symmetricTree](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/symmetricTree) * [markAndToys](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/markAndToys) +* [camelCase](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/camelCase) +* [excelSheelColumnTitle](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/excelSheelColumnTitle) +* [sherklockAndBeast](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/sherklockAndBeast) +* [binaryTreeZigZagLevelOrderTraversal](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/binaryTreeZigZagLevelOrderTraversal) +* [plusOne](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/plusOne) +* [largestPalindromeProduct](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/largestPalindromeProduct) +* [longestUncommonSubsequence](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/longestUncommonSubsequence) +* [subSets](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/subSets) +* [validMountainArray](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/validMountainArray) +* [nRepeatedElementIn2DArray](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/nRepeatedElementIn2DArray) +* [sortCharactersByFrequency](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/sortCharactersByFrequency) +* [circularArrayRotation](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/circularArrayRotation) +* [buyAndSellStock1](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/buyAndSellStock1) +* [poorPigs](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/poorPigs) * [CrackCodeInt](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/CrackCodeInt) +* [betweenTwoSets](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/betweenTwoSets) +* [consecutiveSums](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/consecutiveSums) +* [trimBST](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/trimBST) +* [largestNumberTwiceOfOthers](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/largestNumberTwiceOfOthers) +* [pangram](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/pangram) +* [validParentheses](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/validParentheses) +* [powerOf3](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/powerOf3) +* [sortArrayByParity](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/sortArrayByParity) * [countingChocolate](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/countingChocolate) +* [palindromeLinkedList](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/palindromeLinkedList) * [maxCounters](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/maxCounters) * [maxSliceSum](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/maxSliceSum) +* [sortedLinkedListToBst](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/sortedLinkedListToBst) +* [powerOf4](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/powerOf4) * [frogJmpCounting](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/frogJmpCounting) +* [keypadCombination](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/keypadCombination) +* [findRelativeRanks](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/findRelativeRanks) +* [binaryTreeTilt](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/binaryTreeTilt) +* [permutations](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/permutations) +* [removeLinkedListElements](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/removeLinkedListElements) +* [diameterOfBinaryTree](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/diameterOfBinaryTree) +* [customersWhoNeverOrder](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/customersWhoNeverOrder) +* [employeeEarningMoreThanTheirManagers](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/employeeEarningMoreThanTheirManagers) +* [implementMagicDictionary](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/implementMagicDictionary) +* [gemStones](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/gemStones) +* [minimumDistanceBetweenBSTNodes](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/minimumDistanceBetweenBSTNodes) +* [findPivotIndex](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/findPivotIndex) +* [guessNumberHigherLower](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/guessNumberHigherLower) +* [fizzBuzz](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/fizzBuzz) * [primeComplexity](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/primeComplexity) * [fiboModified](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/fiboModified) -* [tieRope](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/tieRope) -* [twoSums](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/twoSums) -* [powerOf2](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/powerOf2) -* [iceCreamParlour-Hashtables](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/iceCreamParlour) -* [recursionDavisStaircase](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/recursionDavisStaircase) -* [bitManipulationLonelyInteger](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/bitManipulationLonelyInteger) -* [gradingStudents](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/gradingStudents) -* [emailAddressCreator](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/emailAddressCreator) -* [maxDisjointSetSum](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/maxDisjointSetSum) -* [Apples&Oranges](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/Apples%26Oranges) -* [kangaroo](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/kangaroo) -* [lonelyInteger](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/lonelyInteger) -* [maximizingXor](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/maximizingXor) -* [counterGame](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/counterGame) -* [bfsShortestReach](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/bfsShortestReach) -* [sherlockAndArray](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/sherlockAndArray) -* [missingNumber](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/missingNumber) -* [camelCase](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/camelCase) -* [sumVsXor](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/sumVsXor) -* [flippingBits](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/flippingBits) -* [hackerrankInString](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/hackerRankInString) -* [caesarCipher](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/caesarCipher) -* [luckBalance](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/pangram) -* [sherlockNBeast](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/luckBalance) -* [beautifulPairs](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/beautifulPairs) -* [coursePlan](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/coursesOrder) -* [jimAndOrder](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/jimAndOrder) -* [phrasesearch](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/phraseSearch) -* [anagrams](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/anagram) -* [rectangleIntersection](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/rectangleIntersect) -* [keypadCombinations](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/keypadCombination) -* [superReducedString](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/superReducedString) -* [strongPassword](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/strongPassword) * [marsExploration](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/marsExploration) -* [courseOrder](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/courseOrder) -* [migratingBirds](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/migratingBirds) -* [bonAppetit](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/bonAppetit) -* [closestNumbers](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/closestNumbers) -* [gameOfThrones](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/gameOfThrones) +* [findLargestValueInEachTreeRow](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/findLargestValueInEachTreeRow) * [twoStrings](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/twoStrings) -* [stringConstruction](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/stringConstruction) -* [sherlockAndValidString](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/sherlockAndValidString) -* [palindromeIndex](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/palindromeIndex) -* [perfectBinaryString](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/perfectBinaryString) -* [loveLetterMysteryMakePalindrome](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/loveLetterMysteryMakePalindrome) -* [funnyString](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/funnyString) -* [isPalindromeInteger](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/isPalindromeInteger) -* [removeDuplicatesSortedArray](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/removeDuplicatesSortedArray) -* [removeElement](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/removeElement) -* [reverseInteger](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/reverseInteger) -* [needleHayStack](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/needleHayStack) -* [romanToNumeral](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/romanToNumeral) -* [gemStones](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/gemStones) -* [alternateCharacters](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/alternateCharacters) -* [minMaxSum](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/minMaxSum) -* [stairCase](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/stairCase) -* [lengthOfLastWord](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/lengthOfLastWord) -* [plusOne](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/plusOne) -* [addBinary](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/addBinary) -* [squareRoot](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/squareRoot) -* [climbStairs](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/climbStairs) -* [jewelAndStones](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/jewelAndStones) -* [setMismatch](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/setMismatch) -* [uniqueMorseCodeWords](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/uniqueMorseCodeWords) -* [nextGreaterElementI](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/nextGreaterElementI) -* [nextGreaterElementII](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/nextGreaterElementII) -* [happyNumber](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/happyNumber) -* [uglyNumber](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/uglyNumber) -* [findTheDifference](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/findTheDifference) -* [longestWordDictionary](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/longWordDictionary) -* [sumIntegerWithoutPlus](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/sumIntegerWithoutPlus) -* [intersectionOfTwoArray](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/intersectionOfTwoArray) -* [intersectionOfTwoArrayII](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/intersectionOfTwoArrayII) -* [constructStringFromBinaryTree](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/constructStringFromBinaryTree) -* [addTwoNumbersLinkedList](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/addTwoNumbersLinkedList) -* [addStrings](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/addStrings) -* [maxHeightBst](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/maxHeightBst) -* [minHeightBst](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/minHeightBst) -* [sameTree](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/sameTree) -* [intersectionOfTwoLinkedList](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/intersectionOfTwoLinkedList) -* [powerOf2](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/powerOf2) -* [wordPattern](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/wordPattern) -* [isomorphicString](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/isomorphicString) -* [firstUniqueCharacterInString](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/firstUniqueCharacterInString) -* [sortCharactersByFrequency](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/sortCharactersByFrequency) -* [guessNumberHigherLower](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/guessNumberHigherLower) -* [firstBadVersion](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/firstBadVersion) -* [searchInsertPosition](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/searchInsertPosition) -* [numberComplement](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/numberComplement) -* [longestContinuousIncreasingSequence](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/longestContinuousIncreasingSequence) -* [largestNumberTwiceOfOthers](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/largestNumberTwiceOfOthers) -* [removeDuplicatesFromSortedList](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/removeDuplicatesFromSortedList) -* [binaryWatch](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/binaryWatch) -* [reverseLinkedList](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/reverseLinkedList) -* [numberOfSegmentsInAString](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/numberOfSegmentsInAString) -* [rotatedDigits](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/rotatedDigits) -* [twoSumsII](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/twoSumsII) -* [majorityElement](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/majorityElement) -* [containsDuplicates](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/containsDuplicates) -* [containsDuplicatesII](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/containsDuplicatesII) -* [reverseVowels](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/reverseVowels) -* [reverseStringII](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/reverseStringII) -* [reverseWordsInStringIII](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/reverseWordsInStringIII) -* [findPivotIndex](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/findPivotIndex) -* [subArraySumEqualsK](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/subArraySumEqualsK) -* [poorPigs](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/poorPigs) -* [arrangingCoins](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/arrangingCoins) -* [sumOfSquareNumbers](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/sumOfSquareNumbers) -* [validPerfectSquare](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/validPerfectSquare) -* [encodeDecodeTinyUrl](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/encodeDecodeTinyUrl) -* [longestSubstringWithoutRepeatingCharacters](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/longestSubstringWithoutRepeatingCharacters) -* [maxConsecutiveOnes](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/maxConsecutiveOnes) -* [goatLatin](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/goatLatin) -* [selfDividingNumbers](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/selfDividingNumbers) -* [perfectNumber](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/perfectNumber) -* [validAnagram](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/validAnagram) -* [longestPalindrome](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/longestPalindrome) -* [tenthLine](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/tenthLine) -* [linkedListCycle](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/linkedListCycle) -* [canPlaceFlowers](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/canPlaceFlowers) -* [teemoAttacking](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/teemoAttacking) -* [shortestUnsortedContinuousubarray](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/shortestUnsortedContinuousubarray) +* [minimumIndexSumOfTwoList](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/minimumIndexSumOfTwoList) +* [distributeCandies](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/distributeCandies) +* [tieRope](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/tieRope) +* [sherklockAndArray](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/sherklockAndArray) +* [oddEvenLinkedList](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/oddEvenLinkedList) +* [binaryTreePreOrderTraversal](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/binaryTreePreOrderTraversal) * [thirdMaximumNumber](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/thirdMaximumNumber) -* [beautifulDaysAtMovies](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/beautifulDaysAtMovies) -* [rotateArray](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/rotateArray) -* [rotateList](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/beautifulDaysAtMovies) -* [heaters](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/heaters) -* [minStack](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/minStack) -* [separateTheNumbers](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/separateTheNumbers) -* [saveThePrisoner](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/saveThePrisoner) -* [circularArrayRotation](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/circularArrayRotation) -* [longestCommonPrefix](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/longestCommonPrefix) -* [repeatedStringMatch](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/repeatedStringMatch) -* [compareVersionNumbers](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/compareVersionNumbers) -* [deleteNode](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/deleteNode) -* [mergeSortedLists](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/mergeSortedLists) -* [removeLinkedListElements](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/removeLinkedListElements) -* [implementQueueUsingStacks](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/implementQueueUsingStacks) -* [implementStacksUsingQueue](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/implementStacksUsingQueue) -* [simplifyPath](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/simplifyPath) -* [minimumMovesToEqualArrayElements](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/minimumMovesToEqualArrayElements) -* [mergeSortedArray](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/mergeSortedArray) -* [searchRange](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/searchRange) -* [ransomNote](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/ransomNote) -* [132pattern](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/132pattern) +* [twoSums](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/twoSums) +* [strongPassword](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/strongPassword) * [balancedBinaryTree](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/balancedBinaryTree) -* [constructStringFromBinaryTree](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/constructStringFromBinaryTree) -* [nonDecreasingArray](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/nonDecreasingArray) -* [twoLists](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/twoLists) -* [strangeCounter](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/strangeCounter) -* [findAllNumbersDisappearedInAnArray](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/findAllNumbersDisappearedInAnArray) -* [findAllDuplicatesInAnArray](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/findAllDuplicatesInAnArray) -* [findSmallestLetterGreaterThanTarget](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/findSmallestLetterGreaterThanTarget) -* [findPeakElement](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/findPeakElement) -* [licenseKeyFormatting](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/licenseKeyFormatting) -* [rotateFunction](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/rotateFunction) -* [partitionLabels](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/partitionLabels) -* [mergeIntervals](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/mergeIntervals) -* [almostSorted](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/almostSorted) -* [abbrevation](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/abbrevation) -* [validPalindrome](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/validPalindrome) -* [validPalindromeII](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/validPalindromeII) -* [productExceptSelf](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/productExceptSelf) -* [maximumProductSubArray](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/maximumProductSubArray) -* [maximumProductOfThreeNumbers](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/maximumProductOfThreeNumbers) -* [houseRobber](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/houseRobber) -* [largestPermutation](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/largestPermutation) -* [NthDigit](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/NthDigit) -* [maxMin](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/maxMin) -* [betweenTwoSets](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/betweenTwoSets) -* [dayOfTheProgrammer](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/dayOfTheProgrammer) -* [divisibleSumPairs](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/divisibleSumPairs) -* [levelOrderTraversal](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/levelOrderTraversal) -* [levelOrderTraversalII](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/levelOrderTraversalII) -* [averageOfLevelsInBinaryTree](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/averageOfLevelsInBinaryTree) +* [powerOf2](https://github.com/Srinivas11789/AlgorithmNuggets/tree/master/ProblemSolving/powerOf2) ### WIP * Ruby * Java * Swift +### Commit Information +* Every commit has a key called + - lt => leetcode + - hr => hackerrank + ### Links and References: * Leetcode - https://leetcode.com/srinivas11789/ * HackerRank - https://www.hackerrank.com/spg349 diff --git a/Techniques/reflect.go b/Techniques/reflect.go new file mode 100644 index 0000000..b4cd0be --- /dev/null +++ b/Techniques/reflect.go @@ -0,0 +1,44 @@ +// Reflect +package main; + +import ( + "fmt" + "reflect" +) + +const ( + Cust = iota + Staff +) + +type Office struct { + Cust Record + Staff Record +} + +type Record struct { + fname string + lname string +} + +func main() { + downtown := Office{ + Cust: Record{ + fname: "Foo", + lname: "Bar", + }, + Staff: Record{ + fname: "Boo", + lname: "Bee", + }, + } + fmt.Println(downtown) + value := reflect.ValueOf(&downtown).Elem().Field(Cust) + new_record := Record{ + fname: "Fam", + lname: "Bat", + } + value.Set(reflect.ValueOf(new_record)) + fmt.Println(downtown) +} + diff --git a/adventOfCode/2018/1.example b/adventOfCode/2018/1.example new file mode 100644 index 0000000..9205ed4 --- /dev/null +++ b/adventOfCode/2018/1.example @@ -0,0 +1,4 @@ ++1 +-2 ++3 ++1 diff --git a/adventOfCode/2018/11.input b/adventOfCode/2018/11.input new file mode 100644 index 0000000..2a7a1fa --- /dev/null +++ b/adventOfCode/2018/11.input @@ -0,0 +1,1005 @@ +-19 ++8 +-10 ++9 ++2 ++19 ++5 ++8 ++13 ++16 ++4 +-8 ++16 +-10 ++11 ++13 +-12 +-5 +-15 +-12 ++9 +-6 +-18 ++5 ++3 ++18 +-3 ++5 +-19 ++21 +-9 +-9 ++20 +-18 ++11 ++11 ++17 ++17 +-20 +-7 ++5 ++7 ++7 ++7 ++7 ++16 +-12 ++18 ++10 ++3 ++15 +-10 ++8 ++5 ++7 +-16 +-16 +-2 +-15 ++3 +-6 ++9 +-15 ++19 +-12 +-20 +-1 +-12 ++11 +-22 ++10 ++15 ++2 +-10 +-19 ++1 +-18 +-21 +-4 ++16 +-15 ++13 ++20 ++7 ++23 ++13 +-3 ++10 ++8 +-7 ++4 +-19 +-7 +-4 ++19 ++20 +-18 +-5 ++11 ++22 +-14 ++15 +-3 ++16 ++20 +-16 +-11 +-12 ++7 +-13 ++7 ++12 ++20 ++9 +-15 ++1 +-14 ++11 ++16 ++13 ++9 +-16 ++18 +-8 +-6 ++17 ++7 ++15 ++7 +-15 +-15 +-14 +-16 ++15 ++17 ++19 ++6 +-16 ++13 +-12 ++20 +-18 +-11 +-8 +-14 ++18 +-11 ++6 +-16 ++14 +-10 +-6 ++1 ++16 ++4 +-6 +-8 ++27 ++18 ++10 +-3 +-2 ++11 +-10 ++11 ++7 ++19 +-1 ++11 ++14 +-16 +-10 ++15 +-9 ++2 +-1 ++13 +-4 ++6 +-9 ++10 +-2 +-10 ++17 +-14 +-10 ++15 ++17 +-12 +-15 ++18 ++8 ++13 ++3 ++17 ++14 ++1 ++15 ++18 ++7 ++15 +-2 ++9 ++3 +-1 +-18 +-15 +-11 +-10 +-1 +-14 ++13 +-18 +-2 ++5 ++5 +-7 +-5 +-12 ++4 ++19 ++15 ++9 +-17 +-10 +-5 ++13 ++15 ++7 +-10 ++12 ++1 ++9 +-18 ++14 ++20 ++2 ++5 ++7 ++6 ++13 ++4 ++12 +-9 ++17 ++10 +-5 +-9 ++18 ++4 ++5 +-16 ++1 ++16 ++1 +-5 ++19 +-5 ++14 +-15 +-3 ++7 +-15 ++14 +-7 ++16 ++13 ++1 ++17 +-4 +-9 ++12 ++15 ++10 ++5 ++8 ++31 ++22 ++12 ++16 +-17 ++9 +-21 +-13 ++22 +-1 +-2 ++17 ++14 ++34 ++18 +-15 ++10 ++14 ++11 ++4 +-9 ++13 +-12 ++7 ++3 +-15 ++6 ++5 ++21 +-18 +-20 ++7 ++18 +-11 ++8 +-9 ++11 +-19 +-2 +-2 +-20 +-13 ++16 +-14 +-1 ++4 ++20 +-10 ++6 +-18 ++15 ++41 +-1 ++25 ++21 ++15 ++1 +-14 +-1 +-11 ++17 +-9 +-5 +-1 ++21 +-2 ++9 ++3 +-13 +-16 ++1 ++13 +-4 +-18 +-8 +-20 +-1 ++2 ++1 ++4 +-8 +-46 +-29 +-16 +-5 +-36 ++35 +-144 ++3 ++2 +-7 +-1 +-11 +-20 +-22 +-12 +-18 +-2 +-18 ++8 +-18 ++3 +-1 ++7 +-18 ++7 ++19 +-12 +-19 +-19 +-14 ++15 ++15 ++6 +-17 ++12 ++11 ++24 ++16 ++4 ++12 ++4 +-18 ++3 ++19 +-10 ++12 +-4 ++19 ++3 ++2 ++5 ++19 ++5 ++22 +-21 ++1 +-21 +-19 ++13 +-12 ++10 +-12 +-13 +-2 +-11 +-16 +-7 ++10 +-21 +-3 ++4 ++22 ++18 ++11 ++1 +-10 ++15 ++5 +-9 ++2 ++1 +-24 +-1 +-2 ++6 +-26 +-15 +-16 ++9 ++25 ++14 +-7 +-27 +-24 ++16 +-30 +-30 ++26 ++12 ++3 +-32 ++3 +-10 +-4 ++8 +-19 +-7 ++15 ++13 +-3 ++16 ++7 +-21 +-23 +-12 ++14 +-149 +-77 ++19 ++6 +-80 ++11 +-16 +-19 +-65 ++6 +-67327 +-14 ++16 +-15 +-10 ++4 ++16 +-12 +-3 +-10 ++7 ++14 +-2 ++17 ++8 +-7 ++15 +-17 +-13 +-11 +-18 ++19 +-22 +-11 +-1 +-16 +-2 ++10 +-12 +-6 ++11 ++9 ++1 ++13 ++9 +-6 ++19 +-10 +-4 +-12 ++14 ++1 ++19 ++15 ++8 +-16 ++1 ++8 ++18 +-12 +-5 ++10 ++15 +-9 +-15 ++12 ++8 +-9 ++3 ++16 ++5 ++14 ++18 +-1 +-5 ++4 ++17 ++12 +-9 +-12 +-15 ++11 +-19 ++1 +-13 ++17 +-11 +-11 +-14 ++8 ++10 +-15 ++18 +-12 ++4 +-1 ++10 ++16 ++11 ++3 +-11 +-14 +-4 ++17 ++13 ++4 ++12 +-18 +-16 +-20 ++14 +-22 +-20 +-20 ++6 ++16 +-15 +-35 +-7 +-17 +-20 ++19 +-17 +-11 +-9 +-16 +-3 ++7 +-10 +-2 ++7 ++2 ++2 ++16 ++14 ++17 +-8 +-18 ++2 +-6 ++3 +-10 +-8 ++7 ++5 ++18 +-20 +-13 +-17 +-17 +-7 ++9 ++13 +-17 ++16 ++4 ++12 +-3 ++1 +-12 +-7 ++16 ++13 ++1 ++14 +-3 +-4 ++16 +-21 +-20 +-17 ++1 +-14 +-10 +-5 +-14 +-1 +-5 ++19 ++3 ++16 +-9 +-13 ++2 ++3 +-7 +-15 ++4 ++6 ++8 +-10 ++5 ++12 ++8 ++18 +-7 ++8 +-15 ++5 +-11 +-15 ++16 ++16 ++7 +-2 ++14 ++18 ++24 ++9 ++19 ++17 ++13 +-16 +-13 +-14 +-20 +-5 ++18 +-3 ++20 ++13 ++15 ++7 ++11 +-15 +-22 +-15 +-6 ++18 +-8 ++18 +-6 +-24 +-12 ++21 ++17 ++18 ++40 ++22 ++27 +-4 +-16 ++17 +-10 +-18 ++49 ++15 +-12 ++7 ++13 +-16 ++10 ++15 +-1 +-3 ++16 ++6 +-7 ++4 +-18 ++13 +-4 +-16 ++18 +-5 ++1 ++9 +-4 +-2 ++19 ++17 +-4 +-14 +-24 +-21 ++1 ++6 +-18 ++8 ++15 +-18 +-2 +-31 +-30 ++4 ++2 +-28 +-53 +-33 ++10 +-11 +-18 +-19 +-4 +-6 +-24 +-6 +-4 ++11 +-24 +-16 ++3 +-1 +-1 ++13 +-15 +-10 +-7 +-3 ++8 +-11 ++2 ++5 ++8 +-3 +-7 ++15 ++1 +-11 +-11 +-2 +-4 ++16 ++5 ++14 +-24 +-14 +-22 +-11 +-15 +-6 ++8 ++15 ++19 +-14 +-12 ++1 ++9 ++5 ++18 ++6 +-18 ++16 +-8 +-10 +-8 +-9 ++1 ++11 +-16 ++8 ++18 ++12 ++8 ++2 ++10 ++11 +-2 ++14 ++1 ++11 +-9 +-18 +-24 ++2 +-8 ++15 +-14 +-18 ++11 ++2 +-10 +-11 +-5 +-13 +-3 +-12 +-5 +-13 ++16 ++5 +-19 +-16 +-12 +-4 ++10 +-15 ++14 +-6 ++3 +-18 ++17 ++12 +-2 ++6 ++13 ++16 +-11 ++3 ++3 +-20 +-6 ++8 +-9 +-19 +-3 ++16 +-14 +-14 ++1 +-12 +-10 ++19 +-12 +-18 ++5 +-3 ++7 +-20 +-16 +-18 ++17 +-23 ++25 ++65 ++11 ++11 ++16 +-1 ++16 +-9 ++19 ++13 +-8 +-10 ++9 +-18 +-16 +-16 +-19 ++1 +-28 ++4 ++35 ++13 ++12 ++15 +-5 +-3 ++4 ++16 ++2 ++10 ++15 ++17 ++18 ++27 ++19 ++15 ++13 ++6 +-17 ++12 ++15 ++9 ++23 ++78 +-221 +-28 ++19 ++18 +-13 +-22 +-11 +-5 +-5 +-9 +-16 +-2 ++11 ++30 ++10 ++28 +-4 +-72 +-36 ++10 +-5 ++77 ++35 ++102 ++153 +-29 +-676 +-67225 +-5 ++13 ++19 ++3 ++15 ++7 +-11 +-1 +-7 ++13 ++17 ++17 ++6 +-15 +-9 ++11 +-8 +-7 ++10 ++1 ++13 ++19 +-11 +-11 ++2 ++4 +-11 +-7 ++10 ++19 ++17 ++7 ++12 ++20 +-2 ++135638 + diff --git a/adventOfCode/2018/11.py b/adventOfCode/2018/11.py new file mode 100644 index 0000000..8d4c74d --- /dev/null +++ b/adventOfCode/2018/11.py @@ -0,0 +1,10 @@ +# Calculate the End Frequency Changes from the Freq changes list +# * Start from 0 +import requests +# Sent the cookie set through the environment variable to get this +input = requests.get("https://adventofcode.com/2018/day/1/input") +# Hard Coded inputs +input = open("11.input","r").read() +input = input.split("\n") +print input +print eval("0"+"".join(input)) diff --git a/adventOfCode/2018/12.input b/adventOfCode/2018/12.input new file mode 100644 index 0000000..2a7a1fa --- /dev/null +++ b/adventOfCode/2018/12.input @@ -0,0 +1,1005 @@ +-19 ++8 +-10 ++9 ++2 ++19 ++5 ++8 ++13 ++16 ++4 +-8 ++16 +-10 ++11 ++13 +-12 +-5 +-15 +-12 ++9 +-6 +-18 ++5 ++3 ++18 +-3 ++5 +-19 ++21 +-9 +-9 ++20 +-18 ++11 ++11 ++17 ++17 +-20 +-7 ++5 ++7 ++7 ++7 ++7 ++16 +-12 ++18 ++10 ++3 ++15 +-10 ++8 ++5 ++7 +-16 +-16 +-2 +-15 ++3 +-6 ++9 +-15 ++19 +-12 +-20 +-1 +-12 ++11 +-22 ++10 ++15 ++2 +-10 +-19 ++1 +-18 +-21 +-4 ++16 +-15 ++13 ++20 ++7 ++23 ++13 +-3 ++10 ++8 +-7 ++4 +-19 +-7 +-4 ++19 ++20 +-18 +-5 ++11 ++22 +-14 ++15 +-3 ++16 ++20 +-16 +-11 +-12 ++7 +-13 ++7 ++12 ++20 ++9 +-15 ++1 +-14 ++11 ++16 ++13 ++9 +-16 ++18 +-8 +-6 ++17 ++7 ++15 ++7 +-15 +-15 +-14 +-16 ++15 ++17 ++19 ++6 +-16 ++13 +-12 ++20 +-18 +-11 +-8 +-14 ++18 +-11 ++6 +-16 ++14 +-10 +-6 ++1 ++16 ++4 +-6 +-8 ++27 ++18 ++10 +-3 +-2 ++11 +-10 ++11 ++7 ++19 +-1 ++11 ++14 +-16 +-10 ++15 +-9 ++2 +-1 ++13 +-4 ++6 +-9 ++10 +-2 +-10 ++17 +-14 +-10 ++15 ++17 +-12 +-15 ++18 ++8 ++13 ++3 ++17 ++14 ++1 ++15 ++18 ++7 ++15 +-2 ++9 ++3 +-1 +-18 +-15 +-11 +-10 +-1 +-14 ++13 +-18 +-2 ++5 ++5 +-7 +-5 +-12 ++4 ++19 ++15 ++9 +-17 +-10 +-5 ++13 ++15 ++7 +-10 ++12 ++1 ++9 +-18 ++14 ++20 ++2 ++5 ++7 ++6 ++13 ++4 ++12 +-9 ++17 ++10 +-5 +-9 ++18 ++4 ++5 +-16 ++1 ++16 ++1 +-5 ++19 +-5 ++14 +-15 +-3 ++7 +-15 ++14 +-7 ++16 ++13 ++1 ++17 +-4 +-9 ++12 ++15 ++10 ++5 ++8 ++31 ++22 ++12 ++16 +-17 ++9 +-21 +-13 ++22 +-1 +-2 ++17 ++14 ++34 ++18 +-15 ++10 ++14 ++11 ++4 +-9 ++13 +-12 ++7 ++3 +-15 ++6 ++5 ++21 +-18 +-20 ++7 ++18 +-11 ++8 +-9 ++11 +-19 +-2 +-2 +-20 +-13 ++16 +-14 +-1 ++4 ++20 +-10 ++6 +-18 ++15 ++41 +-1 ++25 ++21 ++15 ++1 +-14 +-1 +-11 ++17 +-9 +-5 +-1 ++21 +-2 ++9 ++3 +-13 +-16 ++1 ++13 +-4 +-18 +-8 +-20 +-1 ++2 ++1 ++4 +-8 +-46 +-29 +-16 +-5 +-36 ++35 +-144 ++3 ++2 +-7 +-1 +-11 +-20 +-22 +-12 +-18 +-2 +-18 ++8 +-18 ++3 +-1 ++7 +-18 ++7 ++19 +-12 +-19 +-19 +-14 ++15 ++15 ++6 +-17 ++12 ++11 ++24 ++16 ++4 ++12 ++4 +-18 ++3 ++19 +-10 ++12 +-4 ++19 ++3 ++2 ++5 ++19 ++5 ++22 +-21 ++1 +-21 +-19 ++13 +-12 ++10 +-12 +-13 +-2 +-11 +-16 +-7 ++10 +-21 +-3 ++4 ++22 ++18 ++11 ++1 +-10 ++15 ++5 +-9 ++2 ++1 +-24 +-1 +-2 ++6 +-26 +-15 +-16 ++9 ++25 ++14 +-7 +-27 +-24 ++16 +-30 +-30 ++26 ++12 ++3 +-32 ++3 +-10 +-4 ++8 +-19 +-7 ++15 ++13 +-3 ++16 ++7 +-21 +-23 +-12 ++14 +-149 +-77 ++19 ++6 +-80 ++11 +-16 +-19 +-65 ++6 +-67327 +-14 ++16 +-15 +-10 ++4 ++16 +-12 +-3 +-10 ++7 ++14 +-2 ++17 ++8 +-7 ++15 +-17 +-13 +-11 +-18 ++19 +-22 +-11 +-1 +-16 +-2 ++10 +-12 +-6 ++11 ++9 ++1 ++13 ++9 +-6 ++19 +-10 +-4 +-12 ++14 ++1 ++19 ++15 ++8 +-16 ++1 ++8 ++18 +-12 +-5 ++10 ++15 +-9 +-15 ++12 ++8 +-9 ++3 ++16 ++5 ++14 ++18 +-1 +-5 ++4 ++17 ++12 +-9 +-12 +-15 ++11 +-19 ++1 +-13 ++17 +-11 +-11 +-14 ++8 ++10 +-15 ++18 +-12 ++4 +-1 ++10 ++16 ++11 ++3 +-11 +-14 +-4 ++17 ++13 ++4 ++12 +-18 +-16 +-20 ++14 +-22 +-20 +-20 ++6 ++16 +-15 +-35 +-7 +-17 +-20 ++19 +-17 +-11 +-9 +-16 +-3 ++7 +-10 +-2 ++7 ++2 ++2 ++16 ++14 ++17 +-8 +-18 ++2 +-6 ++3 +-10 +-8 ++7 ++5 ++18 +-20 +-13 +-17 +-17 +-7 ++9 ++13 +-17 ++16 ++4 ++12 +-3 ++1 +-12 +-7 ++16 ++13 ++1 ++14 +-3 +-4 ++16 +-21 +-20 +-17 ++1 +-14 +-10 +-5 +-14 +-1 +-5 ++19 ++3 ++16 +-9 +-13 ++2 ++3 +-7 +-15 ++4 ++6 ++8 +-10 ++5 ++12 ++8 ++18 +-7 ++8 +-15 ++5 +-11 +-15 ++16 ++16 ++7 +-2 ++14 ++18 ++24 ++9 ++19 ++17 ++13 +-16 +-13 +-14 +-20 +-5 ++18 +-3 ++20 ++13 ++15 ++7 ++11 +-15 +-22 +-15 +-6 ++18 +-8 ++18 +-6 +-24 +-12 ++21 ++17 ++18 ++40 ++22 ++27 +-4 +-16 ++17 +-10 +-18 ++49 ++15 +-12 ++7 ++13 +-16 ++10 ++15 +-1 +-3 ++16 ++6 +-7 ++4 +-18 ++13 +-4 +-16 ++18 +-5 ++1 ++9 +-4 +-2 ++19 ++17 +-4 +-14 +-24 +-21 ++1 ++6 +-18 ++8 ++15 +-18 +-2 +-31 +-30 ++4 ++2 +-28 +-53 +-33 ++10 +-11 +-18 +-19 +-4 +-6 +-24 +-6 +-4 ++11 +-24 +-16 ++3 +-1 +-1 ++13 +-15 +-10 +-7 +-3 ++8 +-11 ++2 ++5 ++8 +-3 +-7 ++15 ++1 +-11 +-11 +-2 +-4 ++16 ++5 ++14 +-24 +-14 +-22 +-11 +-15 +-6 ++8 ++15 ++19 +-14 +-12 ++1 ++9 ++5 ++18 ++6 +-18 ++16 +-8 +-10 +-8 +-9 ++1 ++11 +-16 ++8 ++18 ++12 ++8 ++2 ++10 ++11 +-2 ++14 ++1 ++11 +-9 +-18 +-24 ++2 +-8 ++15 +-14 +-18 ++11 ++2 +-10 +-11 +-5 +-13 +-3 +-12 +-5 +-13 ++16 ++5 +-19 +-16 +-12 +-4 ++10 +-15 ++14 +-6 ++3 +-18 ++17 ++12 +-2 ++6 ++13 ++16 +-11 ++3 ++3 +-20 +-6 ++8 +-9 +-19 +-3 ++16 +-14 +-14 ++1 +-12 +-10 ++19 +-12 +-18 ++5 +-3 ++7 +-20 +-16 +-18 ++17 +-23 ++25 ++65 ++11 ++11 ++16 +-1 ++16 +-9 ++19 ++13 +-8 +-10 ++9 +-18 +-16 +-16 +-19 ++1 +-28 ++4 ++35 ++13 ++12 ++15 +-5 +-3 ++4 ++16 ++2 ++10 ++15 ++17 ++18 ++27 ++19 ++15 ++13 ++6 +-17 ++12 ++15 ++9 ++23 ++78 +-221 +-28 ++19 ++18 +-13 +-22 +-11 +-5 +-5 +-9 +-16 +-2 ++11 ++30 ++10 ++28 +-4 +-72 +-36 ++10 +-5 ++77 ++35 ++102 ++153 +-29 +-676 +-67225 +-5 ++13 ++19 ++3 ++15 ++7 +-11 +-1 +-7 ++13 ++17 ++17 ++6 +-15 +-9 ++11 +-8 +-7 ++10 ++1 ++13 ++19 +-11 +-11 ++2 ++4 +-11 +-7 ++10 ++19 ++17 ++7 ++12 ++20 +-2 ++135638 + diff --git a/adventOfCode/2018/12.py b/adventOfCode/2018/12.py new file mode 100644 index 0000000..d3c279d --- /dev/null +++ b/adventOfCode/2018/12.py @@ -0,0 +1,31 @@ +# Calculate the End Frequency Changes from the Freq changes list +# * Start from 0 +# * Condition: When first repeating freq result occurs, start from beginning + +# Fetch input from url +import requests, sys +# Sent the cookie set through the environment variable to get this +input = requests.get("https://adventofcode.com/2018/day/1/input") + +# Hard Coded inputs +input = open("12.input","r").read() +input = input.split("\n") + +# freqs list to track the frequency +exp = "0" +freqs = [] +count = 0 +while exp: + for i in input: + if i != "": + exp = str(eval(exp+i)) + if exp in freqs: + print exp + sys.exit() + else: + freqs.append(exp) + #print exp + count += 1 + print count + #sys.exit() + diff --git a/adventOfCode/2018/21.input b/adventOfCode/2018/21.input new file mode 100644 index 0000000..e18eed0 --- /dev/null +++ b/adventOfCode/2018/21.input @@ -0,0 +1,251 @@ +qwubbihrkplymcraxefntvdzns +qwugbihrkplyzcjahefttvdzns +qwugbihrkplymcjoxrsotvdzns +qwugbphrkplympjaxmfotvdzns +qwugbghrkpltbcjaxefotvdzns +qwubbihrwpuymcjaxefotvdzns +qiugpihrkplymcwaxefotvdzns +qwugbihrkplymcjavefotvotns +qwugbihrkpvymcjaxefotvnzes +qwvgbihrkpltmcnaxefotvdzns +qwugvihrkplymvjaxefotvczns +qwugbihrkplymwjazefotvyzns +qwugbihrkplbmcjbxefttvdzns +qhugbihrkplymcjaxefotnazns +qwugbihrkpyyacjacefotvdzns +qwugsihrkpsymcjaxafotvdzns +qwugbihriplymcjixefosvdzns +qwuibihrkjlvmcjaxefotvdzns +qwugbjhrgplymcjaxefotvdzys +qwugnimrkplymcjayefotvdzns +qwumjihrkplymcjexefotvdzns +qwugbihukptymcjaxefotvvzns +qwughthrgplymcjaxefotvdzns +qlugbihrkplymcjbxhfotvdzns +qhugbiyrkplymcjaxefotvdzes +qwugbihrkvlymcjaxecotvtzns +qwugbihrkphymcjaxefitvizns +qwugbbhdtplymcjaxefotvdzns +qwugbihrkplymceaxefotvltns +mwugbihrkptymcpaxefotvdzns +qwugbihrdplymcvaxefotvdwns +qwugbihrkplymcjaxekhtvhzns +qjugbihrkplyjcjaxefonvdzns +qwugbihrjplymcjaxefgtudzns +qlugbihrkplymcjaxefztvdpns +qwugbihrkclyvpjaxefotvdzns +qwugbihrsplymnjhxefotvdzns +qwudbihrbxlymcjaxefotvdzns +qwugbihrkplymcjxxefatvdzng +qwujbihrkplyqdjaxefotvdzns +qwugnihrkplamcjaxefotvmzns +qwugnihrkplymcjajekotvdzns +qwugbihrkslymcjamsfotvdzns +fwugbihrkplymcjaxetotvdzne +qwughihrkplyucfaxefotvdzns +qwuebihrkplymcraxefotvdzgs +qwugbinrkplymcjaxefodvdznh +qwudbihrkplymcjsxefotvjzns +qwlgbihrkzlymcjixefotvdzns +qwugbihckpoymcpaxefotvdzns +qwfgbibskplymcjaxefotvdzns +qwugbihrkplymczaxdfotvuzns +qwugbihwkplymcjaxepxtvdzns +qwubbihrkplymcjaxefntfdzns +qwunbihrkpaymcjaxefotvdzni +qwugfihrkplymujaxefotvdzni +qwugrihrkplymkjaxxfotvdzns +ztugbihrkplymcjaxefotvdznt +qwugbihrkplvmcjaxefotvdzph +qwugtinrfplymcjaxefotvdzns +qwugbihrkplamcjkmefotvdzns +qwtgbihryplymcjaxeeotvdzns +qwugbiazkplymhjaxefotvdzns +pwugbihrkplymklaxefotvdzns +wwugbihkxplymcjaxefotvdzns +dwugbihrgpdymcjaxefotvdzns +qwulbihrkplymcjaxefoqvqzns +qvugbihrkplyhcjtxefotvdzns +qwugbihrkplymcjaxcfotvfzjs +qwugbihrkpkymyjaxdfotvdzns +qwugbinrkplymcjswefotvdzns +qcuguiqrkplymcjaxefotvdzns +qwugbihlkplyccjaxefrtvdzns +qwugbihpkplomcjaxefotvdhns +qwggbphrkplymcjaxbfotvdzns +qwuipihrkplymcjaxefotvdznt +qwugbihrhplyccjaxeforvdzns +qwugbdhrkplymcjdxefotvdznv +qwugbihrkplymcjaxefotvbfos +qwugtihrkplymcocxefotvdzns +qwugbihrkpljmcjaxwfovvdzns +qwugbnhrkplymcjaxefotvdxnm +qwugbihrkpeymcjauefotvlzns +qwugbihjkplymcraxefftvdzns +qwugbghrkplymcjaxefotvizni +qwwgbihrkplymcjrxefotvrzns +qwugbihrkplymzjawexotvdzns +qwugnihrkplymcjpxnfotvdzns +qwugbihrkdlytcjaxecotvdzns +qwugbihrkacymdjaxefotvdzns +qlugbehrkplymcjaxzfotvdzns +fwugbihrkplymcjamefotldzns +qwugbihrkplymcjarefotlszns +qwsgbihrkpnymcjfxefotvdzns +awuubihrkplymcjaxefrtvdzns +qwngbihrkpjtmcjaxefotvdzns +qwugbihrkpltmkjaxefytvdzns +ewugbihrkplymcjvxefotvdzus +qwugbihrpplymcjaxsfmtvdzns +qwrgbihrmplymcjaxefutvdzns +qwugbihrknxymcwaxefotvdzns +qwugbnurkplymcjabefotvdzns +qwugbihrkphomfjaxefotvdzns +qwugbchrkplymcjaxefctvdens +qwugbidrkplymcjaxefotwwzns +qwggbohrkplgmcjaxefotvdzns +nwkgbihrkplymcjaxqfotvdzns +qwuibihrkpnymajaxefotvdzns +qwugsihrzplymujaxefotvdzns +qwugbihrkplumcgaxefodvdzns +qwugbqhrkplymcjaxefotvddts +qwugbiorkpvyacjaxefotvdzns +bjugbihukplymcjaxefotvdzns +qwugbyhrkplymxjaxexotvdzns +vwugbihrkplymcraxefotgdzns +qwugbihrkplymjwaxeaotvdzns +qwpsbihrkplykcjaxefotvdzns +qwugbqhrkplymcjaxefotgdzno +qwugbjhrkplymcjaxefatvczns +qwuglihrkclymcjvxefotvdzns +qjugbihrkpsymcjajefotvdzns +qwugbinrkptymcjaxedotvdzns +qwurbihrkglymcjaxefomvdzns +qfugbihrsxlymcjaxefotvdzns +lwuggihrkplymcjaxefotvdzds +qwugbihrkplymcjhxwfjtvdzns +qwugbhjrkplymcjaxefotvdyns +qwugbihrkplymcjoxefepvdzns +awwgbihryplymcjaxefotvdzns +qpugbihrkplymcjaxekorvdzns +qwulbihrkplymcuapefotvdzns +qwugbwhrkplymljaxefotvdrns +qwugxihrkplymjjalefotvdzns +qwugbmhrkplymcjyxefotvdnns +qwugbihrkplymcjnxgfotsdzns +qwygbihrkplsmczaxefotvdzns +qwugbihrkplymqjaxefovgdzns +qwuwbihrkplymcjaxefktvdznu +qwugbihrkplyfcjaxeoowvdzns +qwufbiyrkplymcjaxedotvdzns +qwusbirrkplymcjaxefotvdlns +qwurbihroplymtjaxefotvdzns +qiugbihrkplymcjaxefvtvmzns +qwugrihrkflymcjaxefotvdzls +qwugbimrzplymcoaxefotvdzns +qyugbiwrkplymcjasefotvdzns +qwubbihrkpiymcjaxefotvdzws +qwugbilrkplymjjgxefotvdzns +qwugbihykplympjaxefotgdzns +qwugmxhrkplymcjaxefotvdins +qwfjbahrkplymcjaxefotvdzns +owuzbihrkplymcbaxefotvdzns +qwugbihrkilymcjaxefotsdzvs +qwugbwhrkplymcpzxefotvdzns +qwugbihrkplymcjlcefotvdjns +kwugbihrkplymcjaxefotvhdns +qwulbihrkplymcfwxefotvdzns +qwxabihrkplyhcjaxefotvdzns +qwugbihrzpoymcjaxefotqdzns +qwugbihrknlymcjabefovvdzns +qyugbihrkplymclaxefotvgzns +qwugbxhrkpgymcjaxefotvdlns +qwuplihrkplymcjaxefhtvdzns +qwugbihruplymcjaxefotmdzps +qwugkihrkplymcqtxefotvdzns +qwugbihrkplymcjaxeyodvszns +qwukbihrkplymojaxefotvczns +nwugbihrkplymcjaxrfothdzns +qwugbihrkklymcjaxqfotvdzcs +qwugbihrkplemcjaxefotvufns +qwugbihrkplymcjaxbfitvdzne +qwugbizrkplymcjaxgfotvdhns +qwulbihrxplymcjaxefolvdzns +jwugbihckpoymcpaxefotvdzns +qwugeihrkplymbjcxefotvdzns +qwuxbihbkplymcjaxeuotvdzns +qwugbshrkplyvcjlxefotvdzns +qwugbimrjplymcjaxtfotvdzns +qwugzikrkplymcjaxefxtvdzns +qwugbihrkplymcjaxefftvdgnq +qwugbihnkilymcjaxemotvdzns +qfugbihrkplyfcjadefotvdzns +qwugbihrkplymrsaxefwtvdzns +qwugfihrkpsymckaxefotvdzns +qwulbihrkplymyjaxefotvdkns +quugbikrkpkymcjaxefotvdzns +qwugbihfgplymdjaxefotvdzns +qougbihrkplemcjaqefotvdzns +qwugbihrkplemcjjxefotvdyns +qfuhbikrkplymcjaxefotvdzns +qhugbihrcplymcjaxefrtvdzns +qwugbmhnkplymcjnxefotvdzns +qwugbihrkplymmjaaefofvdzns +qwugbihrtplykcjaxefoxvdzns +qwugbihrkmvymcjaxefetvdzns +qwugbfjrkplymcjaxefotadzns +qwuibihrrplymcjaxefotvdznv +qwcgbihrkjlymcjzxefotvdzns +qwugbihrkplymcjuxefytvzzns +qwkgwihrkllymcjaxefotvdzns +qwugbihrkplymcpaxgfogvdzns +qwuvbihrkplymcdaxefotvdmns +qwtgbihrkplqmcjgxefotvdzns +qwuglihrkplnmcjaxefptvdzns +qbugbihrkplymcjawefotidzns +qwegbihrvplymcjaxefqtvdzns +qwugbihrgqlyncjaxefotvdzns +qwugbihrpplymcjaxefotvdeqs +qwugbihrkplypzjaxefbtvdzns +qwugbihrkpkyncjanefotvdzns +qwugbshrkplymcjaxefotfdzys +qwugbihrkpymmcjaxefotzdzns +qwugbphrkplymcjaxefotvdzru +qyugbihrkplamcjjxefotvdzns +qwugbihrmphymcjaxefotedzns +qwuafihrkplymcjaxefozvdzns +qwugwihrkplymcjaxwfotvdzws +qwugbihrkzlymcjaxjfotvdznz +uwugsihrkplypcjaxefotvdzns +qwugbihrkplymcjaxefotudzur +qwugbihrkplymcjoxefotfdzng +qwugbihxkplymcjamebotvdzns +qpugvihrkplymcjaxefotvdzhs +qwugbihrkplyocgaxefotvdzss +qwugbihrkplymcpaqekotvdzns +qwunbihrkplymclaxefitvdzns +qzugbihrkplsmcjaxebotvdzns +qvugbihrkplymcjsxefotvmzns +qwugbihrkprymcyaxkfotvdzns +qwugbihukplymcjaxefotzlzns +qwusbihrkplymcjaxwfotxdzns +qwugbihrwplymcjaxefbtcdzns +qwugbihrkplymcjpxefotkdons +qwugbihrkhlymcjaxefohvwzns +qwukbihrkplymxjaxefotvdzms +qwugbiprkplsmcjaxefotvdznm +qwugbqhrkplymcjawwfotvdzns +qwugbihrkprymcjaxefotvdxnb +qwugbihrkplymcjaxefoivpzos +qwugbuhrkplymcjaxefotvdzsb +qwugblhrcplymcjaxefotvdyns +qtuabihrkplymejaxefotvdzns +qwucbihrkplyvcjaxefotvdznu +rwugbyhrkplymcjaxefotvdzrs +qruybihrkpsymcjaxefotvdzns +qwugbihrjpwymcjaxejotvdzns +qwugbihshplymcjaxefoavdzns +vwugbihrkplymwjaxefotvdznc +qwugbihrkpmymcjvxcfotvdzns +qkxgbihrkplymcjnxefotvdzns + diff --git a/adventOfCode/2018/21.py b/adventOfCode/2018/21.py new file mode 100644 index 0000000..c477f7a --- /dev/null +++ b/adventOfCode/2018/21.py @@ -0,0 +1,36 @@ +# Count the boxes with box names having 2 repeating and 3 repeating letters +# * multiply them to obtain the checksum + +# Fetch input from url +import requests, sys +# Sent the cookie set through the environment variable to get this +input = requests.get("https://adventofcode.com/2018/day/2/input") + +# Hard Coded inputs +input = open("21.input","r").read() +input = input.split("\n") + +# Iterate and count frequency of 2 and 3 +# function to return dictionary of freqs +def freq(input): + import collections + return collections.Counter(input) + +twos = 0 +threes = 0 +for i in input: + fq = freq(i) + # Count for exactly 2 or 3 times + t = 0 + th = 0 + for k,v in fq.items(): + if v == 2 and t == 0: + twos += 1 + t += 1 + if v == 3 and th == 0: + threes += 1 + th += 1 + +# checksum +print twos * threes + diff --git a/adventOfCode/2018/22.example b/adventOfCode/2018/22.example new file mode 100644 index 0000000..3e1abfc --- /dev/null +++ b/adventOfCode/2018/22.example @@ -0,0 +1,7 @@ +abcde +fghij +klmno +pqrst +fguij +axcye +wvxyz diff --git a/adventOfCode/2018/22.py b/adventOfCode/2018/22.py new file mode 100644 index 0000000..061e0d4 --- /dev/null +++ b/adventOfCode/2018/22.py @@ -0,0 +1,72 @@ +# Count the boxes with box names having 2 repeating and 3 repeating letters +# * multiply them to obtain the checksum + +# Fetch input from url +import requests, sys +# Sent the cookie set through the environment variable to get this +input = requests.get("https://adventofcode.com/2018/day/2/input") + +# Hard Coded inputs +input = open("21.input","r").read() +input = input.split("\n") + +""" +# Set logic complicates by giving unique and unordered elements +# * use multiset to preseve repeating elements which is only found in the bag implementation +# * Or use collection.Counter to do this kind of task + +# Logic +""" +""" +>>> a = {"s", "r", "i"} +>>> b = {"s", "r", "n"} +>>> a.difference(b) +set(['i']) +""" +""" +result = [] +# Do worst case brute force to crack this soon +# Set alters the positions and deletes repeated elements, becareful +for i in range(len(input)): + for j in range(i+1, len(input)): + +""" +""" + one = set(input[i]) + two = set(input[j]) + #inter1 = len(one.intersection(two)) + #inter2 = len(two.intersection(one)) + #if (inter1 == len(input[i])-1) and (inter2 == len(input[j])-1): + if len(one.difference(two)) == 1 and len(two.difference(one)) == 1: + index = input[i].index(one.difference(two).pop()) + index2 = input[j].index(two.difference(one).pop()) + #print index, index2, one, two + if index == index2: + print input[i], input[j] + result.append(input[i][:index]+input[i][index+1:]) +print set(result) +""" + +# Logic 2 revamping with comparison logic + +print input +result = [] +n = len(input) +for i in range(n): + for j in range(i+1, n): + print i, j, input[i],input[j] + one = list(input[i]) + two = list(input[j]) + count = 0 + if len(one) == len(two): + for k in range(len(one)): + if one[k] == two[k]: + pass + else: + count += 1 + index = k + if count == 1: + result.append(input[i][:index]+input[i][index+1:]) +print result + +# Better logic: identify the same prefix between two strings and quantify the postfix equality after the irregularity (different character) diff --git a/adventOfCode/2018/31.example b/adventOfCode/2018/31.example new file mode 100644 index 0000000..3755d52 --- /dev/null +++ b/adventOfCode/2018/31.example @@ -0,0 +1,3 @@ +#1 @ 1,3: 4x4 +#2 @ 3,1: 4x4 +#3 @ 5,5: 2x2 diff --git a/adventOfCode/2018/31.input b/adventOfCode/2018/31.input new file mode 100644 index 0000000..ea66efd --- /dev/null +++ b/adventOfCode/2018/31.input @@ -0,0 +1,1374 @@ +#1 @ 7,589: 24x11 +#2 @ 846,110: 28x22 +#3 @ 940,313: 27x11 +#4 @ 457,400: 27x27 +#5 @ 762,971: 13x21 +#6 @ 703,27: 3x9 +#7 @ 154,903: 13x12 +#8 @ 404,604: 18x17 +#9 @ 339,668: 17x25 +#10 @ 293,931: 14x20 +#11 @ 733,923: 29x22 +#12 @ 512,502: 13x15 +#13 @ 562,173: 14x28 +#14 @ 79,942: 17x19 +#15 @ 264,48: 14x23 +#16 @ 891,581: 13x21 +#17 @ 621,54: 11x18 +#18 @ 939,527: 18x29 +#19 @ 568,858: 20x16 +#20 @ 147,56: 29x22 +#21 @ 945,933: 27x26 +#22 @ 749,595: 21x27 +#23 @ 770,380: 26x27 +#24 @ 35,926: 23x17 +#25 @ 746,212: 20x23 +#26 @ 877,590: 27x27 +#27 @ 32,740: 10x19 +#28 @ 710,879: 13x16 +#29 @ 460,47: 16x10 +#30 @ 190,0: 18x27 +#31 @ 824,675: 12x28 +#32 @ 607,394: 21x17 +#33 @ 586,395: 16x20 +#34 @ 833,489: 23x16 +#35 @ 587,155: 19x23 +#36 @ 9,186: 13x23 +#37 @ 961,422: 20x18 +#38 @ 509,875: 18x22 +#39 @ 900,811: 11x23 +#40 @ 323,485: 10x13 +#41 @ 153,704: 18x29 +#42 @ 390,268: 21x25 +#43 @ 15,267: 23x20 +#44 @ 764,871: 21x16 +#45 @ 546,111: 17x26 +#46 @ 325,154: 16x22 +#47 @ 282,5: 23x11 +#48 @ 22,924: 12x25 +#49 @ 629,218: 29x28 +#50 @ 639,184: 23x17 +#51 @ 229,922: 23x13 +#52 @ 631,900: 22x13 +#53 @ 77,717: 17x25 +#54 @ 755,892: 10x28 +#55 @ 268,217: 16x17 +#56 @ 184,31: 16x27 +#57 @ 795,495: 15x19 +#58 @ 28,494: 18x11 +#59 @ 252,907: 25x16 +#60 @ 308,950: 20x26 +#61 @ 497,889: 27x20 +#62 @ 270,920: 17x12 +#63 @ 594,804: 13x21 +#64 @ 572,182: 19x21 +#65 @ 373,353: 22x17 +#66 @ 905,674: 14x10 +#67 @ 899,315: 29x27 +#68 @ 930,549: 16x11 +#69 @ 267,173: 18x25 +#70 @ 697,145: 24x20 +#71 @ 660,416: 15x25 +#72 @ 515,930: 20x24 +#73 @ 427,408: 20x17 +#74 @ 41,937: 18x18 +#75 @ 733,669: 22x26 +#76 @ 49,631: 28x23 +#77 @ 457,952: 19x22 +#78 @ 27,963: 28x19 +#79 @ 202,231: 21x10 +#80 @ 352,147: 10x25 +#81 @ 472,560: 27x16 +#82 @ 302,247: 11x18 +#83 @ 303,847: 28x13 +#84 @ 954,397: 12x17 +#85 @ 234,508: 21x19 +#86 @ 436,4: 27x22 +#87 @ 14,276: 18x19 +#88 @ 722,757: 23x10 +#89 @ 842,24: 28x13 +#90 @ 890,962: 29x11 +#91 @ 310,0: 12x18 +#92 @ 492,248: 14x19 +#93 @ 518,370: 11x16 +#94 @ 647,902: 20x14 +#95 @ 107,76: 12x23 +#96 @ 878,768: 22x13 +#97 @ 539,534: 29x16 +#98 @ 31,479: 18x19 +#99 @ 571,765: 15x15 +#100 @ 254,233: 15x14 +#101 @ 526,441: 25x23 +#102 @ 543,343: 16x11 +#103 @ 840,507: 22x11 +#104 @ 544,538: 19x13 +#105 @ 9,471: 11x17 +#106 @ 803,498: 15x26 +#107 @ 926,882: 16x16 +#108 @ 239,67: 16x21 +#109 @ 402,330: 14x14 +#110 @ 673,598: 29x10 +#111 @ 448,402: 19x13 +#112 @ 179,484: 29x21 +#113 @ 403,600: 22x12 +#114 @ 835,729: 27x16 +#115 @ 739,178: 14x26 +#116 @ 276,43: 18x16 +#117 @ 864,892: 26x11 +#118 @ 586,398: 13x25 +#119 @ 232,855: 12x23 +#120 @ 838,929: 27x20 +#121 @ 254,877: 18x17 +#122 @ 258,718: 14x23 +#123 @ 269,453: 13x20 +#124 @ 755,823: 19x25 +#125 @ 462,749: 22x10 +#126 @ 839,0: 28x11 +#127 @ 680,745: 23x19 +#128 @ 886,763: 12x20 +#129 @ 285,712: 25x12 +#130 @ 573,522: 27x13 +#131 @ 808,871: 27x22 +#132 @ 310,13: 10x15 +#133 @ 305,659: 21x28 +#134 @ 301,294: 28x26 +#135 @ 607,793: 26x11 +#136 @ 949,112: 21x28 +#137 @ 8,933: 17x16 +#138 @ 721,880: 10x18 +#139 @ 542,858: 26x17 +#140 @ 37,464: 21x26 +#141 @ 348,827: 29x26 +#142 @ 97,388: 15x13 +#143 @ 258,461: 23x18 +#144 @ 431,625: 11x20 +#145 @ 650,721: 27x18 +#146 @ 721,537: 25x22 +#147 @ 770,939: 22x14 +#148 @ 108,653: 27x20 +#149 @ 816,79: 12x11 +#150 @ 579,237: 10x15 +#151 @ 279,604: 10x12 +#152 @ 288,170: 17x26 +#153 @ 279,75: 24x13 +#154 @ 249,792: 20x21 +#155 @ 934,195: 27x21 +#156 @ 676,909: 18x25 +#157 @ 525,261: 21x18 +#158 @ 602,28: 28x28 +#159 @ 290,699: 13x18 +#160 @ 544,304: 24x26 +#161 @ 3,53: 20x17 +#162 @ 924,62: 14x16 +#163 @ 700,923: 25x16 +#164 @ 742,375: 29x26 +#165 @ 92,87: 23x14 +#166 @ 709,933: 24x20 +#167 @ 638,702: 11x16 +#168 @ 485,336: 19x14 +#169 @ 689,547: 10x15 +#170 @ 834,262: 16x23 +#171 @ 561,442: 26x28 +#172 @ 122,638: 4x5 +#173 @ 40,741: 10x23 +#174 @ 527,583: 22x20 +#175 @ 799,397: 28x21 +#176 @ 242,698: 23x28 +#177 @ 896,581: 16x29 +#178 @ 927,264: 26x22 +#179 @ 750,49: 24x21 +#180 @ 768,416: 25x19 +#181 @ 397,61: 19x11 +#182 @ 117,669: 28x12 +#183 @ 32,544: 15x22 +#184 @ 359,935: 7x11 +#185 @ 37,151: 24x27 +#186 @ 291,63: 14x20 +#187 @ 802,562: 27x21 +#188 @ 366,91: 22x22 +#189 @ 429,204: 16x27 +#190 @ 851,750: 11x14 +#191 @ 376,107: 29x12 +#192 @ 106,244: 14x18 +#193 @ 850,312: 26x18 +#194 @ 35,951: 18x17 +#195 @ 100,849: 26x20 +#196 @ 759,962: 13x17 +#197 @ 800,945: 18x14 +#198 @ 648,406: 29x17 +#199 @ 202,739: 23x28 +#200 @ 739,44: 29x28 +#201 @ 548,595: 29x27 +#202 @ 929,50: 23x19 +#203 @ 704,923: 25x24 +#204 @ 385,540: 12x18 +#205 @ 524,47: 13x25 +#206 @ 299,739: 10x29 +#207 @ 523,51: 15x13 +#208 @ 486,508: 26x15 +#209 @ 959,389: 16x10 +#210 @ 406,943: 27x17 +#211 @ 42,775: 14x25 +#212 @ 652,177: 22x21 +#213 @ 714,471: 16x11 +#214 @ 560,624: 29x23 +#215 @ 491,44: 25x21 +#216 @ 207,85: 15x14 +#217 @ 568,418: 22x24 +#218 @ 270,43: 29x17 +#219 @ 412,947: 13x28 +#220 @ 965,290: 18x15 +#221 @ 570,310: 13x26 +#222 @ 198,9: 18x19 +#223 @ 868,738: 22x17 +#224 @ 12,319: 13x14 +#225 @ 243,824: 14x13 +#226 @ 69,72: 16x22 +#227 @ 448,195: 29x18 +#228 @ 722,313: 22x16 +#229 @ 167,526: 11x11 +#230 @ 775,289: 25x14 +#231 @ 301,375: 15x16 +#232 @ 136,660: 12x18 +#233 @ 700,250: 23x28 +#234 @ 234,491: 28x29 +#235 @ 844,135: 20x20 +#236 @ 246,532: 13x19 +#237 @ 801,392: 21x15 +#238 @ 913,50: 13x14 +#239 @ 104,793: 26x15 +#240 @ 828,617: 16x10 +#241 @ 232,392: 26x15 +#242 @ 832,129: 24x10 +#243 @ 305,231: 25x18 +#244 @ 48,174: 25x13 +#245 @ 830,308: 14x28 +#246 @ 254,717: 23x27 +#247 @ 548,717: 20x28 +#248 @ 681,444: 21x15 +#249 @ 790,117: 11x13 +#250 @ 126,343: 26x14 +#251 @ 34,650: 25x27 +#252 @ 518,897: 18x14 +#253 @ 908,148: 21x27 +#254 @ 404,595: 18x20 +#255 @ 316,617: 21x18 +#256 @ 52,482: 12x29 +#257 @ 416,383: 25x10 +#258 @ 768,250: 24x19 +#259 @ 758,827: 20x21 +#260 @ 851,406: 22x20 +#261 @ 327,1: 27x24 +#262 @ 338,961: 21x26 +#263 @ 867,876: 27x25 +#264 @ 685,791: 18x15 +#265 @ 407,312: 20x18 +#266 @ 149,475: 12x19 +#267 @ 472,415: 10x10 +#268 @ 974,285: 16x25 +#269 @ 753,645: 26x22 +#270 @ 676,178: 16x22 +#271 @ 522,370: 19x18 +#272 @ 623,824: 18x14 +#273 @ 967,96: 19x25 +#274 @ 458,945: 17x11 +#275 @ 775,382: 15x6 +#276 @ 620,40: 16x22 +#277 @ 911,222: 17x25 +#278 @ 575,801: 28x17 +#279 @ 523,821: 19x13 +#280 @ 618,611: 12x24 +#281 @ 286,762: 20x19 +#282 @ 252,965: 12x17 +#283 @ 306,480: 10x28 +#284 @ 407,623: 12x22 +#285 @ 299,556: 15x26 +#286 @ 841,32: 23x15 +#287 @ 445,352: 18x17 +#288 @ 359,215: 21x26 +#289 @ 607,799: 29x11 +#290 @ 7,592: 16x23 +#291 @ 693,145: 24x22 +#292 @ 814,963: 14x17 +#293 @ 619,732: 18x26 +#294 @ 277,182: 23x12 +#295 @ 312,905: 7x3 +#296 @ 723,387: 23x28 +#297 @ 487,965: 12x15 +#298 @ 274,35: 24x17 +#299 @ 690,432: 14x16 +#300 @ 140,240: 11x17 +#301 @ 841,739: 16x17 +#302 @ 48,58: 11x27 +#303 @ 81,511: 26x11 +#304 @ 100,902: 20x11 +#305 @ 137,402: 15x15 +#306 @ 556,186: 16x13 +#307 @ 918,462: 28x11 +#308 @ 266,631: 25x11 +#309 @ 121,2: 27x19 +#310 @ 783,300: 17x17 +#311 @ 41,557: 26x23 +#312 @ 896,448: 22x28 +#313 @ 691,802: 15x26 +#314 @ 532,49: 23x13 +#315 @ 641,34: 14x7 +#316 @ 227,77: 21x28 +#317 @ 480,358: 16x19 +#318 @ 766,192: 17x14 +#319 @ 334,818: 16x28 +#320 @ 218,161: 29x22 +#321 @ 317,265: 23x15 +#322 @ 78,136: 12x19 +#323 @ 101,70: 20x26 +#324 @ 467,79: 14x28 +#325 @ 177,47: 24x13 +#326 @ 233,512: 16x13 +#327 @ 126,798: 24x17 +#328 @ 585,74: 23x10 +#329 @ 712,141: 29x12 +#330 @ 243,502: 13x22 +#331 @ 899,548: 19x26 +#332 @ 742,470: 28x15 +#333 @ 469,836: 12x12 +#334 @ 296,884: 11x22 +#335 @ 616,747: 23x10 +#336 @ 433,304: 26x21 +#337 @ 891,16: 10x11 +#338 @ 842,446: 10x13 +#339 @ 403,628: 29x26 +#340 @ 502,102: 19x28 +#341 @ 962,386: 22x18 +#342 @ 191,932: 22x25 +#343 @ 45,662: 27x12 +#344 @ 390,398: 23x24 +#345 @ 537,191: 13x15 +#346 @ 722,542: 19x10 +#347 @ 701,688: 18x26 +#348 @ 392,284: 16x17 +#349 @ 44,10: 24x19 +#350 @ 295,80: 27x21 +#351 @ 216,326: 12x14 +#352 @ 321,793: 23x13 +#353 @ 569,899: 25x27 +#354 @ 248,871: 21x25 +#355 @ 476,867: 12x15 +#356 @ 678,328: 19x15 +#357 @ 153,587: 28x10 +#358 @ 977,91: 16x13 +#359 @ 400,488: 19x17 +#360 @ 11,965: 28x22 +#361 @ 803,860: 28x19 +#362 @ 290,418: 15x27 +#363 @ 210,105: 12x10 +#364 @ 258,941: 18x14 +#365 @ 915,246: 29x12 +#366 @ 48,654: 18x21 +#367 @ 340,129: 11x21 +#368 @ 758,71: 10x18 +#369 @ 847,737: 16x22 +#370 @ 605,164: 13x24 +#371 @ 551,131: 25x16 +#372 @ 440,71: 22x28 +#373 @ 514,599: 29x10 +#374 @ 362,703: 26x22 +#375 @ 143,117: 13x12 +#376 @ 663,900: 20x29 +#377 @ 661,663: 23x19 +#378 @ 480,72: 25x23 +#379 @ 728,184: 24x24 +#380 @ 865,1: 21x12 +#381 @ 703,405: 27x16 +#382 @ 435,870: 14x15 +#383 @ 899,453: 21x14 +#384 @ 571,980: 16x17 +#385 @ 907,582: 16x16 +#386 @ 885,2: 18x21 +#387 @ 6,786: 28x22 +#388 @ 688,693: 22x17 +#389 @ 101,724: 11x23 +#390 @ 8,978: 24x12 +#391 @ 38,863: 27x23 +#392 @ 504,824: 25x15 +#393 @ 960,240: 15x16 +#394 @ 170,700: 13x19 +#395 @ 690,419: 19x12 +#396 @ 245,867: 15x25 +#397 @ 476,525: 15x28 +#398 @ 486,432: 26x11 +#399 @ 765,417: 27x18 +#400 @ 246,618: 26x21 +#401 @ 327,38: 19x21 +#402 @ 220,243: 28x25 +#403 @ 7,738: 28x24 +#404 @ 978,792: 19x21 +#405 @ 471,64: 16x27 +#406 @ 305,57: 20x11 +#407 @ 285,306: 18x25 +#408 @ 121,219: 15x20 +#409 @ 52,164: 10x20 +#410 @ 836,864: 10x16 +#411 @ 30,737: 16x27 +#412 @ 227,385: 15x27 +#413 @ 278,26: 28x18 +#414 @ 429,240: 29x24 +#415 @ 543,30: 11x18 +#416 @ 155,715: 21x28 +#417 @ 804,378: 24x21 +#418 @ 712,902: 24x13 +#419 @ 814,577: 25x18 +#420 @ 249,98: 13x10 +#421 @ 481,31: 20x22 +#422 @ 804,409: 16x24 +#423 @ 354,922: 24x29 +#424 @ 834,274: 17x27 +#425 @ 470,940: 15x28 +#426 @ 78,870: 24x18 +#427 @ 970,156: 23x18 +#428 @ 466,417: 10x27 +#429 @ 822,448: 24x20 +#430 @ 455,797: 14x25 +#431 @ 172,645: 15x11 +#432 @ 857,132: 20x16 +#433 @ 752,154: 12x27 +#434 @ 614,555: 21x21 +#435 @ 176,858: 18x19 +#436 @ 978,210: 21x15 +#437 @ 142,311: 24x13 +#438 @ 76,701: 16x17 +#439 @ 268,205: 26x17 +#440 @ 975,591: 13x13 +#441 @ 964,857: 12x20 +#442 @ 548,530: 12x13 +#443 @ 488,327: 15x25 +#444 @ 27,776: 17x16 +#445 @ 549,860: 26x27 +#446 @ 586,714: 25x15 +#447 @ 4,24: 21x20 +#448 @ 125,599: 25x25 +#449 @ 200,638: 25x14 +#450 @ 294,2: 18x25 +#451 @ 317,784: 20x13 +#452 @ 548,660: 17x21 +#453 @ 691,559: 17x25 +#454 @ 765,683: 14x24 +#455 @ 287,192: 24x13 +#456 @ 135,326: 10x15 +#457 @ 97,301: 20x25 +#458 @ 824,834: 29x25 +#459 @ 794,421: 29x12 +#460 @ 719,385: 26x13 +#461 @ 568,788: 11x23 +#462 @ 452,243: 17x19 +#463 @ 40,138: 21x12 +#464 @ 674,115: 19x24 +#465 @ 180,99: 13x12 +#466 @ 498,228: 27x13 +#467 @ 604,2: 11x16 +#468 @ 582,446: 26x20 +#469 @ 704,882: 26x19 +#470 @ 887,565: 11x16 +#471 @ 822,972: 18x24 +#472 @ 868,349: 17x14 +#473 @ 610,6: 26x15 +#474 @ 111,225: 15x10 +#475 @ 647,906: 22x10 +#476 @ 819,209: 15x18 +#477 @ 776,106: 16x15 +#478 @ 645,960: 24x21 +#479 @ 916,116: 23x22 +#480 @ 946,84: 18x26 +#481 @ 971,388: 17x14 +#482 @ 292,492: 17x15 +#483 @ 848,39: 15x19 +#484 @ 928,296: 22x25 +#485 @ 828,731: 10x21 +#486 @ 328,392: 26x28 +#487 @ 370,57: 20x11 +#488 @ 165,873: 17x10 +#489 @ 456,404: 14x20 +#490 @ 9,350: 19x28 +#491 @ 405,54: 28x15 +#492 @ 938,104: 16x16 +#493 @ 128,254: 19x26 +#494 @ 831,40: 11x20 +#495 @ 592,802: 19x26 +#496 @ 979,128: 20x29 +#497 @ 166,883: 13x25 +#498 @ 329,28: 21x21 +#499 @ 926,109: 23x10 +#500 @ 899,270: 17x27 +#501 @ 533,830: 26x20 +#502 @ 336,873: 19x17 +#503 @ 315,301: 15x10 +#504 @ 204,25: 19x17 +#505 @ 620,813: 24x12 +#506 @ 739,481: 21x16 +#507 @ 191,808: 17x19 +#508 @ 317,631: 27x17 +#509 @ 508,894: 29x13 +#510 @ 481,582: 16x25 +#511 @ 872,160: 19x24 +#512 @ 782,119: 14x15 +#513 @ 851,122: 20x10 +#514 @ 811,526: 27x28 +#515 @ 712,917: 16x29 +#516 @ 897,955: 20x14 +#517 @ 259,828: 22x25 +#518 @ 249,41: 21x24 +#519 @ 650,909: 13x3 +#520 @ 302,910: 21x27 +#521 @ 467,193: 19x11 +#522 @ 600,382: 15x17 +#523 @ 260,189: 12x21 +#524 @ 821,138: 28x18 +#525 @ 748,878: 19x15 +#526 @ 351,11: 28x14 +#527 @ 112,766: 28x20 +#528 @ 591,310: 17x19 +#529 @ 726,14: 16x11 +#530 @ 930,449: 29x19 +#531 @ 30,219: 28x12 +#532 @ 430,710: 23x29 +#533 @ 574,95: 27x29 +#534 @ 807,808: 10x14 +#535 @ 534,785: 13x10 +#536 @ 401,262: 23x13 +#537 @ 659,257: 28x19 +#538 @ 35,64: 29x24 +#539 @ 569,123: 10x14 +#540 @ 32,429: 22x11 +#541 @ 179,87: 21x28 +#542 @ 652,150: 22x17 +#543 @ 328,464: 23x25 +#544 @ 806,605: 25x11 +#545 @ 684,914: 18x17 +#546 @ 105,80: 28x11 +#547 @ 134,797: 19x23 +#548 @ 850,505: 14x24 +#549 @ 390,612: 29x29 +#550 @ 478,201: 22x28 +#551 @ 419,708: 13x24 +#552 @ 670,425: 12x28 +#553 @ 541,923: 24x15 +#554 @ 157,433: 28x15 +#555 @ 801,76: 25x17 +#556 @ 603,955: 15x10 +#557 @ 285,52: 10x29 +#558 @ 359,635: 22x18 +#559 @ 720,943: 26x16 +#560 @ 921,56: 23x27 +#561 @ 331,37: 12x15 +#562 @ 417,484: 29x14 +#563 @ 648,30: 26x23 +#564 @ 392,301: 22x18 +#565 @ 562,763: 13x11 +#566 @ 460,608: 23x14 +#567 @ 370,732: 23x19 +#568 @ 499,532: 12x29 +#569 @ 7,29: 7x11 +#570 @ 690,317: 12x15 +#571 @ 769,954: 10x20 +#572 @ 29,947: 26x27 +#573 @ 206,815: 18x16 +#574 @ 314,279: 16x29 +#575 @ 471,449: 23x21 +#576 @ 49,920: 19x28 +#577 @ 202,396: 29x10 +#578 @ 241,571: 21x26 +#579 @ 596,129: 13x28 +#580 @ 457,927: 14x22 +#581 @ 584,915: 11x20 +#582 @ 417,458: 27x19 +#583 @ 721,311: 22x21 +#584 @ 503,21: 23x28 +#585 @ 826,538: 29x25 +#586 @ 773,512: 25x12 +#587 @ 479,444: 13x20 +#588 @ 109,68: 22x22 +#589 @ 886,743: 19x17 +#590 @ 304,439: 22x11 +#591 @ 91,236: 10x19 +#592 @ 939,935: 11x18 +#593 @ 929,569: 17x29 +#594 @ 611,790: 22x26 +#595 @ 637,720: 20x23 +#596 @ 944,774: 20x22 +#597 @ 915,873: 23x20 +#598 @ 215,496: 27x16 +#599 @ 939,744: 22x28 +#600 @ 100,312: 18x24 +#601 @ 721,850: 27x17 +#602 @ 890,518: 18x13 +#603 @ 554,715: 25x28 +#604 @ 813,599: 24x25 +#605 @ 300,831: 26x29 +#606 @ 814,396: 28x19 +#607 @ 665,655: 22x26 +#608 @ 734,601: 15x15 +#609 @ 622,777: 27x26 +#610 @ 209,403: 15x11 +#611 @ 303,769: 27x21 +#612 @ 156,462: 17x13 +#613 @ 289,482: 28x25 +#614 @ 317,58: 13x27 +#615 @ 184,91: 7x16 +#616 @ 262,668: 21x27 +#617 @ 359,697: 16x19 +#618 @ 169,551: 23x13 +#619 @ 17,760: 17x28 +#620 @ 983,664: 14x11 +#621 @ 502,531: 15x10 +#622 @ 558,864: 13x14 +#623 @ 217,645: 14x16 +#624 @ 704,320: 11x13 +#625 @ 927,918: 18x13 +#626 @ 199,822: 24x23 +#627 @ 304,701: 11x19 +#628 @ 183,19: 21x21 +#629 @ 643,963: 12x25 +#630 @ 684,629: 10x21 +#631 @ 593,395: 16x11 +#632 @ 275,869: 22x20 +#633 @ 712,243: 20x24 +#634 @ 754,197: 13x18 +#635 @ 682,896: 12x20 +#636 @ 313,435: 21x16 +#637 @ 127,861: 21x19 +#638 @ 935,322: 18x16 +#639 @ 610,359: 17x29 +#640 @ 400,491: 8x12 +#641 @ 970,719: 11x16 +#642 @ 817,1: 10x18 +#643 @ 910,574: 28x15 +#644 @ 2,485: 13x28 +#645 @ 795,193: 27x21 +#646 @ 980,206: 17x11 +#647 @ 169,579: 14x16 +#648 @ 84,35: 26x18 +#649 @ 972,590: 10x14 +#650 @ 802,600: 13x19 +#651 @ 553,284: 29x21 +#652 @ 821,685: 11x23 +#653 @ 681,550: 14x23 +#654 @ 145,161: 24x11 +#655 @ 753,680: 16x17 +#656 @ 323,964: 24x26 +#657 @ 874,66: 10x29 +#658 @ 19,966: 28x29 +#659 @ 13,290: 12x25 +#660 @ 139,301: 11x27 +#661 @ 169,851: 16x12 +#662 @ 587,286: 13x14 +#663 @ 480,371: 12x20 +#664 @ 795,404: 18x26 +#665 @ 751,876: 28x10 +#666 @ 544,193: 15x24 +#667 @ 354,872: 24x22 +#668 @ 0,470: 28x25 +#669 @ 144,342: 16x15 +#670 @ 392,485: 23x23 +#671 @ 537,507: 17x27 +#672 @ 9,85: 29x12 +#673 @ 748,196: 24x25 +#674 @ 615,234: 15x16 +#675 @ 903,255: 26x26 +#676 @ 889,590: 17x26 +#677 @ 153,904: 19x24 +#678 @ 210,750: 16x13 +#679 @ 475,37: 10x14 +#680 @ 662,709: 22x23 +#681 @ 198,91: 13x19 +#682 @ 809,335: 28x13 +#683 @ 606,26: 24x18 +#684 @ 64,924: 29x28 +#685 @ 278,762: 9x16 +#686 @ 96,18: 28x18 +#687 @ 92,238: 24x21 +#688 @ 459,793: 21x27 +#689 @ 538,602: 12x24 +#690 @ 746,931: 17x24 +#691 @ 856,3: 27x13 +#692 @ 604,592: 27x25 +#693 @ 757,639: 12x28 +#694 @ 461,467: 16x10 +#695 @ 490,343: 12x11 +#696 @ 357,141: 15x29 +#697 @ 725,196: 15x14 +#698 @ 244,582: 25x18 +#699 @ 93,60: 22x12 +#700 @ 707,430: 14x19 +#701 @ 294,437: 17x26 +#702 @ 631,390: 25x20 +#703 @ 224,600: 22x14 +#704 @ 825,730: 23x12 +#705 @ 84,519: 23x19 +#706 @ 307,681: 10x16 +#707 @ 165,556: 14x24 +#708 @ 572,333: 21x18 +#709 @ 261,858: 17x24 +#710 @ 144,114: 19x12 +#711 @ 251,230: 19x19 +#712 @ 569,344: 20x10 +#713 @ 279,326: 15x20 +#714 @ 626,396: 12x27 +#715 @ 200,88: 11x29 +#716 @ 40,777: 24x13 +#717 @ 241,903: 15x25 +#718 @ 532,284: 24x20 +#719 @ 774,358: 14x21 +#720 @ 339,389: 24x26 +#721 @ 8,52: 15x15 +#722 @ 465,554: 24x19 +#723 @ 196,138: 3x16 +#724 @ 50,662: 20x13 +#725 @ 105,781: 12x25 +#726 @ 291,383: 18x22 +#727 @ 843,346: 28x11 +#728 @ 226,543: 18x26 +#729 @ 125,218: 21x27 +#730 @ 647,163: 29x14 +#731 @ 340,158: 14x17 +#732 @ 349,215: 29x12 +#733 @ 62,16: 24x28 +#734 @ 353,643: 17x15 +#735 @ 599,5: 12x27 +#736 @ 529,901: 11x21 +#737 @ 437,380: 26x10 +#738 @ 607,701: 12x20 +#739 @ 110,898: 12x24 +#740 @ 308,902: 16x10 +#741 @ 25,937: 5x4 +#742 @ 22,227: 24x27 +#743 @ 332,274: 24x11 +#744 @ 480,65: 29x23 +#745 @ 526,268: 14x19 +#746 @ 618,63: 27x25 +#747 @ 139,223: 22x27 +#748 @ 917,563: 20x20 +#749 @ 284,635: 21x22 +#750 @ 457,831: 18x26 +#751 @ 166,605: 22x12 +#752 @ 544,492: 27x15 +#753 @ 304,916: 12x11 +#754 @ 866,225: 17x26 +#755 @ 222,598: 11x17 +#756 @ 371,135: 16x15 +#757 @ 964,95: 17x18 +#758 @ 730,841: 23x28 +#759 @ 869,78: 15x21 +#760 @ 214,334: 26x14 +#761 @ 9,44: 18x20 +#762 @ 231,205: 17x28 +#763 @ 614,573: 19x21 +#764 @ 619,441: 16x19 +#765 @ 37,95: 22x19 +#766 @ 18,851: 26x27 +#767 @ 331,509: 19x17 +#768 @ 526,38: 14x29 +#769 @ 538,630: 14x23 +#770 @ 792,6: 26x10 +#771 @ 47,81: 15x22 +#772 @ 555,622: 15x23 +#773 @ 672,175: 18x22 +#774 @ 11,771: 13x17 +#775 @ 689,310: 29x16 +#776 @ 850,396: 19x19 +#777 @ 481,872: 15x11 +#778 @ 308,812: 27x29 +#779 @ 963,862: 13x12 +#780 @ 581,292: 10x17 +#781 @ 56,518: 25x13 +#782 @ 117,621: 17x15 +#783 @ 565,314: 29x23 +#784 @ 113,608: 12x17 +#785 @ 323,674: 20x26 +#786 @ 302,566: 11x21 +#787 @ 189,756: 22x20 +#788 @ 790,945: 26x18 +#789 @ 118,13: 10x27 +#790 @ 120,633: 10x15 +#791 @ 687,734: 29x28 +#792 @ 941,596: 14x17 +#793 @ 462,366: 10x19 +#794 @ 668,724: 26x27 +#795 @ 263,320: 21x27 +#796 @ 532,118: 19x26 +#797 @ 98,30: 19x10 +#798 @ 319,140: 26x16 +#799 @ 888,779: 27x19 +#800 @ 544,112: 27x25 +#801 @ 206,765: 12x16 +#802 @ 557,328: 20x11 +#803 @ 185,853: 16x13 +#804 @ 659,141: 15x21 +#805 @ 901,661: 12x17 +#806 @ 708,387: 17x21 +#807 @ 540,891: 21x21 +#808 @ 235,135: 11x12 +#809 @ 890,185: 16x11 +#810 @ 440,67: 24x22 +#811 @ 133,488: 20x21 +#812 @ 650,419: 18x10 +#813 @ 826,34: 24x17 +#814 @ 838,570: 26x19 +#815 @ 360,937: 15x14 +#816 @ 29,505: 18x27 +#817 @ 27,782: 18x11 +#818 @ 367,460: 28x11 +#819 @ 540,731: 25x20 +#820 @ 222,135: 16x11 +#821 @ 740,347: 15x29 +#822 @ 420,362: 28x19 +#823 @ 389,57: 15x24 +#824 @ 178,296: 24x14 +#825 @ 326,22: 13x16 +#826 @ 887,300: 23x28 +#827 @ 619,952: 27x14 +#828 @ 221,229: 21x27 +#829 @ 203,235: 21x17 +#830 @ 183,943: 17x25 +#831 @ 877,773: 20x24 +#832 @ 971,586: 19x15 +#833 @ 410,264: 21x19 +#834 @ 558,665: 28x21 +#835 @ 910,441: 20x23 +#836 @ 703,131: 16x26 +#837 @ 859,710: 18x21 +#838 @ 889,450: 17x20 +#839 @ 769,573: 10x18 +#840 @ 794,13: 19x20 +#841 @ 559,121: 21x10 +#842 @ 952,139: 13x11 +#843 @ 617,479: 19x19 +#844 @ 525,843: 18x11 +#845 @ 264,685: 27x18 +#846 @ 820,854: 29x15 +#847 @ 570,534: 10x27 +#848 @ 555,968: 21x25 +#849 @ 924,862: 25x14 +#850 @ 428,379: 26x19 +#851 @ 722,749: 16x16 +#852 @ 281,588: 14x26 +#853 @ 845,855: 23x16 +#854 @ 88,364: 17x25 +#855 @ 335,268: 21x17 +#856 @ 964,170: 10x25 +#857 @ 800,591: 10x28 +#858 @ 881,85: 16x25 +#859 @ 86,959: 10x12 +#860 @ 804,569: 24x12 +#861 @ 482,316: 25x25 +#862 @ 780,929: 20x12 +#863 @ 740,64: 15x27 +#864 @ 238,809: 13x22 +#865 @ 484,22: 25x18 +#866 @ 498,603: 29x26 +#867 @ 301,823: 19x10 +#868 @ 527,910: 10x28 +#869 @ 280,888: 19x24 +#870 @ 247,627: 20x11 +#871 @ 101,72: 23x26 +#872 @ 240,27: 23x28 +#873 @ 959,613: 28x23 +#874 @ 812,147: 11x27 +#875 @ 710,432: 6x14 +#876 @ 235,144: 28x20 +#877 @ 428,868: 26x24 +#878 @ 620,481: 3x13 +#879 @ 751,606: 14x10 +#880 @ 214,185: 20x29 +#881 @ 53,825: 27x11 +#882 @ 633,923: 29x20 +#883 @ 306,397: 20x14 +#884 @ 58,520: 29x14 +#885 @ 452,802: 22x13 +#886 @ 747,663: 22x12 +#887 @ 554,529: 15x28 +#888 @ 198,951: 28x25 +#889 @ 611,943: 17x25 +#890 @ 853,222: 26x16 +#891 @ 289,845: 29x20 +#892 @ 502,883: 11x20 +#893 @ 563,477: 26x19 +#894 @ 893,841: 27x17 +#895 @ 937,915: 16x10 +#896 @ 183,611: 23x23 +#897 @ 626,428: 20x21 +#898 @ 59,130: 26x14 +#899 @ 397,601: 27x28 +#900 @ 930,851: 16x10 +#901 @ 459,442: 27x23 +#902 @ 586,115: 18x21 +#903 @ 273,197: 12x23 +#904 @ 126,952: 10x20 +#905 @ 162,447: 27x22 +#906 @ 213,517: 23x24 +#907 @ 492,550: 21x15 +#908 @ 917,569: 17x21 +#909 @ 903,460: 12x29 +#910 @ 288,853: 19x19 +#911 @ 954,599: 25x17 +#912 @ 477,622: 27x12 +#913 @ 235,405: 15x17 +#914 @ 671,134: 14x21 +#915 @ 483,183: 17x11 +#916 @ 157,870: 10x18 +#917 @ 410,587: 15x28 +#918 @ 41,81: 11x20 +#919 @ 205,144: 25x10 +#920 @ 550,904: 20x17 +#921 @ 555,717: 24x29 +#922 @ 56,568: 16x15 +#923 @ 680,712: 26x21 +#924 @ 58,669: 17x16 +#925 @ 429,307: 23x11 +#926 @ 325,521: 10x16 +#927 @ 759,585: 22x16 +#928 @ 974,623: 11x19 +#929 @ 280,438: 29x27 +#930 @ 368,219: 13x17 +#931 @ 273,191: 26x15 +#932 @ 615,81: 23x18 +#933 @ 149,439: 22x27 +#934 @ 176,87: 28x27 +#935 @ 480,335: 19x12 +#936 @ 579,413: 14x24 +#937 @ 453,537: 26x17 +#938 @ 168,524: 17x20 +#939 @ 617,397: 14x18 +#940 @ 534,513: 14x14 +#941 @ 438,201: 13x11 +#942 @ 691,945: 27x14 +#943 @ 581,838: 10x16 +#944 @ 424,301: 28x27 +#945 @ 110,320: 28x16 +#946 @ 34,374: 15x14 +#947 @ 586,896: 27x28 +#948 @ 653,385: 25x15 +#949 @ 543,196: 19x17 +#950 @ 879,599: 15x21 +#951 @ 765,86: 16x25 +#952 @ 720,479: 20x29 +#953 @ 396,135: 20x13 +#954 @ 898,445: 29x29 +#955 @ 570,811: 27x17 +#956 @ 313,135: 15x20 +#957 @ 730,687: 24x23 +#958 @ 109,410: 19x22 +#959 @ 219,579: 28x16 +#960 @ 950,274: 17x15 +#961 @ 499,261: 29x21 +#962 @ 307,247: 27x14 +#963 @ 15,268: 20x16 +#964 @ 193,131: 23x27 +#965 @ 253,202: 17x27 +#966 @ 275,741: 14x15 +#967 @ 659,170: 26x19 +#968 @ 116,222: 10x26 +#969 @ 647,239: 27x25 +#970 @ 717,911: 28x16 +#971 @ 379,323: 24x11 +#972 @ 330,125: 15x18 +#973 @ 761,508: 15x13 +#974 @ 440,396: 22x10 +#975 @ 380,328: 25x14 +#976 @ 296,958: 16x16 +#977 @ 933,304: 16x21 +#978 @ 281,506: 12x12 +#979 @ 706,473: 28x28 +#980 @ 74,410: 19x14 +#981 @ 880,700: 19x18 +#982 @ 525,66: 28x26 +#983 @ 977,614: 10x22 +#984 @ 144,214: 22x15 +#985 @ 693,213: 14x28 +#986 @ 469,134: 24x24 +#987 @ 788,499: 23x18 +#988 @ 540,788: 17x13 +#989 @ 659,257: 18x17 +#990 @ 203,508: 23x21 +#991 @ 387,606: 26x16 +#992 @ 881,568: 17x20 +#993 @ 577,912: 15x17 +#994 @ 670,527: 29x15 +#995 @ 763,112: 22x24 +#996 @ 72,859: 13x17 +#997 @ 863,51: 10x29 +#998 @ 581,77: 11x20 +#999 @ 135,875: 10x21 +#1000 @ 772,688: 22x10 +#1001 @ 800,502: 23x18 +#1002 @ 49,433: 15x28 +#1003 @ 39,618: 20x25 +#1004 @ 313,372: 26x12 +#1005 @ 247,943: 24x15 +#1006 @ 853,706: 14x22 +#1007 @ 464,942: 27x23 +#1008 @ 273,760: 21x23 +#1009 @ 817,465: 21x27 +#1010 @ 797,492: 11x27 +#1011 @ 510,437: 11x18 +#1012 @ 394,644: 15x10 +#1013 @ 564,847: 29x16 +#1014 @ 809,364: 27x27 +#1015 @ 816,11: 16x23 +#1016 @ 237,800: 20x21 +#1017 @ 424,304: 17x28 +#1018 @ 527,829: 27x18 +#1019 @ 623,805: 27x26 +#1020 @ 473,960: 20x10 +#1021 @ 493,952: 15x17 +#1022 @ 43,739: 17x15 +#1023 @ 286,914: 28x22 +#1024 @ 145,721: 29x25 +#1025 @ 272,193: 29x27 +#1026 @ 57,570: 13x17 +#1027 @ 53,609: 20x15 +#1028 @ 936,855: 11x27 +#1029 @ 300,915: 26x17 +#1030 @ 497,353: 18x21 +#1031 @ 775,239: 26x11 +#1032 @ 328,257: 21x23 +#1033 @ 354,504: 13x27 +#1034 @ 70,829: 16x11 +#1035 @ 166,643: 27x22 +#1036 @ 17,274: 18x14 +#1037 @ 353,353: 26x12 +#1038 @ 318,796: 23x13 +#1039 @ 941,765: 27x28 +#1040 @ 62,709: 21x24 +#1041 @ 218,144: 22x19 +#1042 @ 544,802: 25x18 +#1043 @ 27,674: 26x27 +#1044 @ 665,359: 23x25 +#1045 @ 746,595: 12x14 +#1046 @ 894,756: 29x24 +#1047 @ 356,136: 23x22 +#1048 @ 482,937: 15x29 +#1049 @ 334,653: 17x24 +#1050 @ 640,951: 14x24 +#1051 @ 762,198: 25x20 +#1052 @ 106,732: 20x27 +#1053 @ 903,807: 13x29 +#1054 @ 700,22: 11x21 +#1055 @ 302,629: 21x21 +#1056 @ 626,686: 15x21 +#1057 @ 213,242: 26x19 +#1058 @ 294,920: 27x20 +#1059 @ 771,94: 28x11 +#1060 @ 563,619: 12x20 +#1061 @ 38,493: 14x19 +#1062 @ 735,472: 12x19 +#1063 @ 476,530: 14x22 +#1064 @ 786,220: 12x27 +#1065 @ 587,573: 28x13 +#1066 @ 396,395: 27x22 +#1067 @ 66,694: 14x11 +#1068 @ 18,940: 13x24 +#1069 @ 294,241: 29x28 +#1070 @ 465,905: 18x23 +#1071 @ 431,411: 19x23 +#1072 @ 827,577: 13x15 +#1073 @ 332,799: 29x11 +#1074 @ 963,252: 25x22 +#1075 @ 132,597: 25x21 +#1076 @ 544,815: 20x17 +#1077 @ 862,1: 17x17 +#1078 @ 391,490: 27x28 +#1079 @ 3,403: 11x10 +#1080 @ 73,326: 29x17 +#1081 @ 960,390: 14x16 +#1082 @ 698,932: 17x24 +#1083 @ 348,37: 26x27 +#1084 @ 99,420: 14x14 +#1085 @ 218,969: 10x18 +#1086 @ 602,235: 27x25 +#1087 @ 248,666: 15x15 +#1088 @ 533,25: 29x11 +#1089 @ 546,930: 16x13 +#1090 @ 101,858: 23x24 +#1091 @ 854,559: 24x13 +#1092 @ 535,693: 22x28 +#1093 @ 208,197: 24x20 +#1094 @ 455,5: 15x14 +#1095 @ 408,498: 23x26 +#1096 @ 175,535: 21x16 +#1097 @ 275,330: 25x13 +#1098 @ 241,907: 18x12 +#1099 @ 9,385: 15x24 +#1100 @ 179,882: 11x24 +#1101 @ 207,204: 22x19 +#1102 @ 831,290: 12x18 +#1103 @ 131,434: 25x25 +#1104 @ 427,63: 14x10 +#1105 @ 99,192: 14x11 +#1106 @ 917,769: 28x13 +#1107 @ 440,374: 23x12 +#1108 @ 128,78: 20x25 +#1109 @ 273,837: 25x12 +#1110 @ 342,224: 15x11 +#1111 @ 468,507: 25x29 +#1112 @ 687,539: 27x23 +#1113 @ 948,399: 20x16 +#1114 @ 281,446: 23x26 +#1115 @ 19,332: 17x21 +#1116 @ 445,803: 29x24 +#1117 @ 152,913: 21x14 +#1118 @ 655,928: 13x11 +#1119 @ 705,880: 29x22 +#1120 @ 958,206: 29x19 +#1121 @ 260,922: 24x18 +#1122 @ 191,59: 12x13 +#1123 @ 816,940: 29x14 +#1124 @ 16,276: 13x20 +#1125 @ 283,865: 22x21 +#1126 @ 479,639: 22x11 +#1127 @ 197,493: 24x22 +#1128 @ 481,433: 11x11 +#1129 @ 458,77: 25x19 +#1130 @ 68,236: 17x18 +#1131 @ 544,625: 22x19 +#1132 @ 662,329: 29x11 +#1133 @ 256,462: 11x26 +#1134 @ 827,517: 12x24 +#1135 @ 541,51: 7x8 +#1136 @ 957,428: 23x20 +#1137 @ 122,658: 26x27 +#1138 @ 797,958: 22x16 +#1139 @ 616,726: 25x19 +#1140 @ 117,781: 15x29 +#1141 @ 289,37: 22x10 +#1142 @ 458,799: 15x15 +#1143 @ 577,555: 26x22 +#1144 @ 394,540: 12x23 +#1145 @ 182,865: 10x14 +#1146 @ 973,143: 21x14 +#1147 @ 791,482: 28x22 +#1148 @ 980,784: 12x19 +#1149 @ 578,235: 10x13 +#1150 @ 338,595: 25x10 +#1151 @ 811,871: 13x10 +#1152 @ 957,151: 20x26 +#1153 @ 94,235: 16x22 +#1154 @ 395,93: 20x23 +#1155 @ 600,165: 28x11 +#1156 @ 177,99: 11x10 +#1157 @ 633,275: 24x21 +#1158 @ 663,308: 11x29 +#1159 @ 900,539: 11x16 +#1160 @ 241,526: 19x27 +#1161 @ 829,851: 10x23 +#1162 @ 767,963: 18x14 +#1163 @ 515,434: 28x26 +#1164 @ 553,350: 11x10 +#1165 @ 243,581: 13x16 +#1166 @ 595,346: 27x24 +#1167 @ 357,15: 17x12 +#1168 @ 855,326: 12x12 +#1169 @ 361,583: 11x17 +#1170 @ 180,293: 26x24 +#1171 @ 41,953: 8x4 +#1172 @ 78,603: 19x14 +#1173 @ 105,90: 10x15 +#1174 @ 743,460: 25x23 +#1175 @ 490,948: 17x11 +#1176 @ 170,701: 28x15 +#1177 @ 16,281: 13x17 +#1178 @ 148,858: 10x14 +#1179 @ 41,880: 19x12 +#1180 @ 272,851: 26x10 +#1181 @ 534,526: 16x17 +#1182 @ 681,607: 16x25 +#1183 @ 750,61: 24x29 +#1184 @ 560,534: 14x14 +#1185 @ 923,862: 20x27 +#1186 @ 63,391: 27x23 +#1187 @ 368,313: 15x16 +#1188 @ 613,788: 11x17 +#1189 @ 118,950: 24x26 +#1190 @ 107,18: 24x11 +#1191 @ 420,609: 24x19 +#1192 @ 889,528: 15x19 +#1193 @ 600,322: 11x26 +#1194 @ 223,750: 10x14 +#1195 @ 93,37: 16x23 +#1196 @ 238,387: 25x14 +#1197 @ 590,746: 28x16 +#1198 @ 290,189: 24x18 +#1199 @ 776,253: 19x18 +#1200 @ 268,196: 17x12 +#1201 @ 589,73: 29x25 +#1202 @ 836,47: 28x11 +#1203 @ 446,902: 28x14 +#1204 @ 97,174: 13x25 +#1205 @ 781,208: 22x28 +#1206 @ 967,631: 16x10 +#1207 @ 55,867: 28x15 +#1208 @ 675,926: 28x14 +#1209 @ 592,567: 26x26 +#1210 @ 570,605: 28x21 +#1211 @ 376,525: 19x10 +#1212 @ 501,930: 21x29 +#1213 @ 166,50: 19x23 +#1214 @ 278,63: 14x19 +#1215 @ 767,356: 11x10 +#1216 @ 445,811: 20x28 +#1217 @ 496,96: 13x14 +#1218 @ 359,512: 10x26 +#1219 @ 772,380: 25x12 +#1220 @ 133,65: 27x27 +#1221 @ 921,56: 25x26 +#1222 @ 584,752: 27x16 +#1223 @ 107,18: 17x15 +#1224 @ 615,290: 20x24 +#1225 @ 618,243: 14x20 +#1226 @ 919,279: 18x15 +#1227 @ 871,766: 20x14 +#1228 @ 655,391: 13x24 +#1229 @ 548,134: 12x13 +#1230 @ 265,49: 16x24 +#1231 @ 973,156: 14x18 +#1232 @ 892,194: 10x15 +#1233 @ 726,460: 18x16 +#1234 @ 476,943: 12x20 +#1235 @ 213,516: 17x11 +#1236 @ 122,4: 21x12 +#1237 @ 37,387: 14x28 +#1238 @ 621,449: 13x23 +#1239 @ 951,95: 22x19 +#1240 @ 33,176: 16x25 +#1241 @ 671,594: 21x17 +#1242 @ 433,409: 12x23 +#1243 @ 798,974: 25x23 +#1244 @ 219,140: 29x17 +#1245 @ 592,166: 24x24 +#1246 @ 480,525: 21x25 +#1247 @ 877,707: 14x16 +#1248 @ 495,260: 4x3 +#1249 @ 808,386: 29x27 +#1250 @ 922,39: 26x22 +#1251 @ 482,744: 19x21 +#1252 @ 5,204: 14x15 +#1253 @ 781,935: 25x26 +#1254 @ 484,964: 29x13 +#1255 @ 971,714: 22x29 +#1256 @ 73,77: 6x13 +#1257 @ 133,399: 25x18 +#1258 @ 603,792: 10x23 +#1259 @ 862,153: 23x24 +#1260 @ 932,105: 21x21 +#1261 @ 585,566: 11x25 +#1262 @ 0,55: 23x11 +#1263 @ 158,704: 17x18 +#1264 @ 86,152: 14x26 +#1265 @ 814,199: 26x18 +#1266 @ 856,340: 16x29 +#1267 @ 460,203: 24x16 +#1268 @ 887,848: 13x14 +#1269 @ 420,469: 11x16 +#1270 @ 723,372: 22x14 +#1271 @ 70,333: 11x15 +#1272 @ 790,425: 28x20 +#1273 @ 242,134: 28x28 +#1274 @ 812,148: 22x17 +#1275 @ 70,241: 11x5 +#1276 @ 144,145: 25x25 +#1277 @ 691,227: 23x28 +#1278 @ 384,444: 24x17 +#1279 @ 9,273: 28x19 +#1280 @ 544,815: 22x19 +#1281 @ 662,316: 17x16 +#1282 @ 408,118: 13x22 +#1283 @ 124,75: 17x23 +#1284 @ 748,76: 20x24 +#1285 @ 906,144: 17x12 +#1286 @ 253,979: 29x12 +#1287 @ 310,70: 18x20 +#1288 @ 928,277: 24x27 +#1289 @ 627,445: 26x15 +#1290 @ 260,308: 22x16 +#1291 @ 696,308: 23x26 +#1292 @ 964,451: 24x25 +#1293 @ 745,401: 17x11 +#1294 @ 791,800: 23x25 +#1295 @ 810,563: 10x11 +#1296 @ 309,432: 13x18 +#1297 @ 797,928: 15x22 +#1298 @ 333,657: 28x12 +#1299 @ 284,8: 14x4 +#1300 @ 142,213: 28x27 +#1301 @ 238,298: 27x15 +#1302 @ 407,915: 24x27 +#1303 @ 674,418: 21x23 +#1304 @ 819,206: 28x11 +#1305 @ 487,624: 13x20 +#1306 @ 211,739: 20x20 +#1307 @ 821,621: 19x14 +#1308 @ 646,47: 16x23 +#1309 @ 223,535: 17x27 +#1310 @ 110,49: 20x12 +#1311 @ 20,331: 23x20 +#1312 @ 112,79: 23x22 +#1313 @ 466,409: 25x13 +#1314 @ 817,256: 27x26 +#1315 @ 507,836: 16x26 +#1316 @ 453,937: 26x26 +#1317 @ 182,794: 25x27 +#1318 @ 963,654: 28x17 +#1319 @ 505,506: 25x14 +#1320 @ 223,287: 16x26 +#1321 @ 976,585: 18x10 +#1322 @ 929,107: 10x21 +#1323 @ 281,186: 16x28 +#1324 @ 381,115: 20x11 +#1325 @ 294,778: 22x11 +#1326 @ 490,122: 21x21 +#1327 @ 643,51: 11x18 +#1328 @ 666,411: 20x22 +#1329 @ 0,492: 25x29 +#1330 @ 430,402: 28x24 +#1331 @ 310,26: 23x21 +#1332 @ 639,32: 22x12 +#1333 @ 88,591: 25x17 +#1334 @ 387,922: 23x26 +#1335 @ 864,328: 19x22 +#1336 @ 619,40: 13x27 +#1337 @ 668,242: 12x16 +#1338 @ 692,541: 14x25 +#1339 @ 70,622: 28x10 +#1340 @ 285,639: 18x14 +#1341 @ 124,437: 17x23 +#1342 @ 169,532: 19x19 +#1343 @ 613,398: 12x28 +#1344 @ 486,529: 19x12 +#1345 @ 205,233: 22x10 +#1346 @ 479,602: 11x18 +#1347 @ 636,795: 13x14 +#1348 @ 739,15: 10x17 +#1349 @ 86,23: 14x18 +#1350 @ 464,91: 10x26 +#1351 @ 245,863: 15x27 +#1352 @ 292,806: 10x22 +#1353 @ 370,944: 26x15 +#1354 @ 465,730: 24x23 +#1355 @ 357,529: 28x16 +#1356 @ 648,364: 18x10 +#1357 @ 761,391: 22x25 +#1358 @ 958,466: 22x16 +#1359 @ 196,92: 17x14 +#1360 @ 246,101: 13x13 +#1361 @ 446,616: 19x10 +#1362 @ 448,743: 15x21 +#1363 @ 352,821: 24x16 +#1364 @ 239,846: 25x15 +#1365 @ 651,286: 23x19 +#1366 @ 578,332: 26x20 +#1367 @ 537,717: 22x22 +#1368 @ 67,963: 29x26 +#1369 @ 975,202: 17x12 +#1370 @ 670,280: 18x18 +#1371 @ 527,462: 15x14 +#1372 @ 951,190: 25x12 +#1373 @ 130,274: 15x26 + diff --git a/adventOfCode/2018/31.py b/adventOfCode/2018/31.py new file mode 100644 index 0000000..f003712 --- /dev/null +++ b/adventOfCode/2018/31.py @@ -0,0 +1,95 @@ +# Day 3 Program + +# Full Cloth (a 2D array) global declaration (for example use 10x10, for input 1000x1000) + +## Do not use [["."]*10]*10 it is copies of the same list (mutations permitted everywhere) +field = [["."]*1000 for _ in range(1000)] + +# To hold the data of all the ids +records = {} + +def debug(field): + """Print the full cloth with all entries""" + for f in field: + print "".join(f) + +def construct(input): + """Fill in Record with Id details and Fill in cloth, measure the overlap""" + + # Part1 output + count = 0 + + # Part2 output + selected_id = "" + count1 = 0 # Control for part 2 item + + # Iterate over the inputs + for entry in input: + if entry: + # Construct the dictionary of records, for each entry + entry = entry.split(" ") + id = entry[0].strip("#") + if id not in records: + records[id] = {} + try: + records[id]["left"], records[id]["top"] = entry[2].strip(":").split(",") + records[id]["width"], records[id]["height"] = entry[3].split("x") + except: + print entry + print "Failed due to the above input!" + + if "indexes" not in records[id]: + records[id]["indexes"] = [] + + # Draw the rectangle in the region of the field declared above + # construct indexes + horizontal_index = [int(records[id]["left"]), int(records[id]["width"])] + vertical_index = [int(records[id]["top"]), int(records[id]["height"])] + #print horizontal_index, vertical_index + while vertical_index[1]: + i = horizontal_index[0] + j = horizontal_index[1] + while j: + records[id]["indexes"].append([vertical_index[0], i]) + if field[vertical_index[0]][i] == ".": + field[vertical_index[0]][i] = id + else: + if field[vertical_index[0]][i] == "X": + pass + else: + field[vertical_index[0]][i] = "X" + count += 1 + i += 1 + j -= 1 + vertical_index[0] += 1 + vertical_index[1] -= 1 + + # Print the full cloth + #debug(field) + + # Part 2 Calculation + for id, vals in records.items(): + count1 = 0 + for index in vals["indexes"]: + if field[index[0]][index[1]] != "X": + count1 += 1 + if count1 == len(vals["indexes"]): + selected_id = id + + return count, selected_id + + +def main(): + # Fetch input from url + import requests, sys + # Sent the cookie set through the environment variable to get this + #input = requests.get("https://adventofcode.com/2018/day/8/input") + + # Hard Coded inputs + input = open("31.input","r").read() + input = input.split("\n") + count, id = construct(input[:-1]) + print "Day 3: Part 1 answer is --> " + str(count) + print "Day 3: Part 2 answer is --> " + id + +main() diff --git a/adventOfCode/2018/404.html b/adventOfCode/2018/404.html new file mode 100644 index 0000000..4316ae0 --- /dev/null +++ b/adventOfCode/2018/404.html @@ -0,0 +1 @@ +Hi... diff --git a/adventOfCode/2018/41.example b/adventOfCode/2018/41.example new file mode 100644 index 0000000..496d314 --- /dev/null +++ b/adventOfCode/2018/41.example @@ -0,0 +1,17 @@ +[1518-11-01 00:00] Guard #10 begins shift +[1518-11-01 00:05] falls asleep +[1518-11-01 00:25] wakes up +[1518-11-01 00:30] falls asleep +[1518-11-01 00:55] wakes up +[1518-11-01 23:58] Guard #99 begins shift +[1518-11-02 00:40] falls asleep +[1518-11-02 00:50] wakes up +[1518-11-03 00:05] Guard #10 begins shift +[1518-11-03 00:24] falls asleep +[1518-11-03 00:29] wakes up +[1518-11-04 00:02] Guard #99 begins shift +[1518-11-04 00:36] falls asleep +[1518-11-04 00:46] wakes up +[1518-11-05 00:03] Guard #99 begins shift +[1518-11-05 00:45] falls asleep +[1518-11-05 00:55] wakes up diff --git a/adventOfCode/2018/41.input b/adventOfCode/2018/41.input new file mode 100644 index 0000000..afbdce3 --- /dev/null +++ b/adventOfCode/2018/41.input @@ -0,0 +1,1026 @@ +[1518-08-12 00:43] falls asleep +[1518-10-03 00:55] falls asleep +[1518-09-04 00:18] falls asleep +[1518-11-22 00:02] Guard #1607 begins shift +[1518-03-25 00:57] wakes up +[1518-03-19 00:16] falls asleep +[1518-04-15 00:38] wakes up +[1518-06-14 00:04] falls asleep +[1518-07-16 00:56] wakes up +[1518-05-11 23:50] Guard #1069 begins shift +[1518-09-14 00:49] wakes up +[1518-10-25 00:47] wakes up +[1518-06-24 00:38] wakes up +[1518-08-06 00:55] wakes up +[1518-08-15 00:54] wakes up +[1518-03-20 00:20] wakes up +[1518-03-22 00:44] falls asleep +[1518-05-10 00:51] wakes up +[1518-04-13 00:00] Guard #1607 begins shift +[1518-04-24 00:15] falls asleep +[1518-06-09 23:56] Guard #1439 begins shift +[1518-06-26 00:59] wakes up +[1518-03-28 00:46] falls asleep +[1518-09-25 00:58] wakes up +[1518-11-17 00:40] wakes up +[1518-09-29 00:47] wakes up +[1518-09-07 00:33] wakes up +[1518-07-16 00:28] wakes up +[1518-09-26 00:54] falls asleep +[1518-04-19 00:04] Guard #1069 begins shift +[1518-07-28 00:51] wakes up +[1518-07-27 00:00] Guard #2003 begins shift +[1518-10-29 00:50] wakes up +[1518-05-13 00:37] wakes up +[1518-10-19 00:58] wakes up +[1518-07-18 00:39] falls asleep +[1518-09-13 00:46] wakes up +[1518-05-11 00:57] wakes up +[1518-05-15 00:19] falls asleep +[1518-08-13 00:04] Guard #2287 begins shift +[1518-06-26 00:41] falls asleep +[1518-08-18 00:22] falls asleep +[1518-09-30 00:56] wakes up +[1518-08-01 00:51] wakes up +[1518-09-06 00:20] wakes up +[1518-06-11 23:57] Guard #1087 begins shift +[1518-07-05 00:35] wakes up +[1518-11-02 00:14] falls asleep +[1518-10-20 00:20] falls asleep +[1518-05-27 23:50] Guard #2287 begins shift +[1518-08-24 00:00] Guard #1523 begins shift +[1518-10-09 00:06] falls asleep +[1518-04-20 00:59] wakes up +[1518-07-18 00:53] wakes up +[1518-06-02 00:00] Guard #2069 begins shift +[1518-07-13 00:35] wakes up +[1518-08-22 00:56] wakes up +[1518-04-03 00:46] falls asleep +[1518-05-07 00:04] falls asleep +[1518-05-13 00:42] falls asleep +[1518-05-16 00:55] wakes up +[1518-08-30 00:04] falls asleep +[1518-08-18 00:04] Guard #2707 begins shift +[1518-03-30 00:34] falls asleep +[1518-11-20 00:00] Guard #1627 begins shift +[1518-06-30 00:23] falls asleep +[1518-09-20 00:54] falls asleep +[1518-04-01 23:56] Guard #2707 begins shift +[1518-06-13 00:32] falls asleep +[1518-08-12 00:08] falls asleep +[1518-11-10 00:55] wakes up +[1518-05-22 00:54] falls asleep +[1518-07-11 00:11] falls asleep +[1518-03-20 00:19] falls asleep +[1518-09-29 00:54] falls asleep +[1518-06-14 23:58] Guard #1409 begins shift +[1518-11-19 00:51] falls asleep +[1518-05-16 00:43] wakes up +[1518-10-05 00:22] wakes up +[1518-04-17 00:06] falls asleep +[1518-04-04 00:00] Guard #1171 begins shift +[1518-07-17 00:04] Guard #1787 begins shift +[1518-05-20 00:10] falls asleep +[1518-08-09 00:58] wakes up +[1518-10-08 00:54] falls asleep +[1518-09-04 00:53] wakes up +[1518-09-18 00:30] falls asleep +[1518-06-19 23:58] Guard #2857 begins shift +[1518-07-29 23:57] Guard #2857 begins shift +[1518-10-18 00:07] wakes up +[1518-05-08 00:04] Guard #1439 begins shift +[1518-09-21 00:57] falls asleep +[1518-07-15 00:49] wakes up +[1518-11-21 00:00] Guard #1069 begins shift +[1518-06-27 00:55] wakes up +[1518-04-17 00:16] wakes up +[1518-09-09 00:42] wakes up +[1518-07-04 23:57] Guard #1789 begins shift +[1518-09-23 00:23] falls asleep +[1518-07-06 00:44] wakes up +[1518-09-14 23:58] Guard #1439 begins shift +[1518-05-25 00:53] falls asleep +[1518-09-20 00:00] Guard #1409 begins shift +[1518-11-07 00:56] wakes up +[1518-06-10 00:38] wakes up +[1518-04-25 00:22] falls asleep +[1518-05-11 00:28] wakes up +[1518-06-15 23:53] Guard #2003 begins shift +[1518-07-11 00:04] Guard #107 begins shift +[1518-10-30 23:57] Guard #2081 begins shift +[1518-04-03 00:58] wakes up +[1518-09-21 00:58] wakes up +[1518-08-21 00:14] falls asleep +[1518-04-13 00:29] wakes up +[1518-08-11 00:43] wakes up +[1518-11-06 00:59] wakes up +[1518-06-19 00:02] Guard #3469 begins shift +[1518-08-28 00:57] wakes up +[1518-07-11 00:53] wakes up +[1518-11-14 00:05] falls asleep +[1518-07-07 23:56] Guard #2857 begins shift +[1518-08-07 00:44] falls asleep +[1518-05-01 00:48] falls asleep +[1518-08-09 00:00] Guard #2857 begins shift +[1518-08-30 23:58] Guard #1607 begins shift +[1518-09-07 00:19] falls asleep +[1518-08-16 00:05] falls asleep +[1518-08-28 00:00] falls asleep +[1518-05-21 00:02] Guard #1607 begins shift +[1518-03-25 00:41] falls asleep +[1518-03-24 00:52] falls asleep +[1518-10-20 00:51] wakes up +[1518-11-13 23:53] Guard #3373 begins shift +[1518-05-27 00:56] wakes up +[1518-05-30 00:01] Guard #1523 begins shift +[1518-04-11 00:56] wakes up +[1518-03-19 00:19] wakes up +[1518-04-03 00:32] wakes up +[1518-11-15 00:54] wakes up +[1518-06-11 00:01] Guard #3373 begins shift +[1518-10-03 00:02] Guard #1523 begins shift +[1518-09-15 00:52] falls asleep +[1518-05-27 00:39] wakes up +[1518-03-23 00:02] falls asleep +[1518-05-06 23:47] Guard #3469 begins shift +[1518-03-24 00:39] falls asleep +[1518-04-19 00:59] wakes up +[1518-06-07 00:39] wakes up +[1518-05-17 23:57] Guard #1439 begins shift +[1518-08-30 00:48] falls asleep +[1518-04-05 00:36] wakes up +[1518-06-04 00:23] falls asleep +[1518-10-07 00:24] falls asleep +[1518-05-02 00:12] wakes up +[1518-05-04 00:21] falls asleep +[1518-05-18 00:27] falls asleep +[1518-08-03 00:49] wakes up +[1518-10-16 00:54] falls asleep +[1518-04-11 00:51] falls asleep +[1518-04-16 00:57] wakes up +[1518-10-22 23:58] Guard #1069 begins shift +[1518-11-07 00:32] falls asleep +[1518-07-22 00:26] falls asleep +[1518-06-09 00:23] falls asleep +[1518-05-06 00:59] wakes up +[1518-10-17 23:53] Guard #1607 begins shift +[1518-09-11 23:48] Guard #2069 begins shift +[1518-08-30 00:51] wakes up +[1518-08-31 00:30] falls asleep +[1518-03-19 00:02] Guard #523 begins shift +[1518-10-07 00:59] wakes up +[1518-04-02 00:59] wakes up +[1518-05-07 00:42] wakes up +[1518-03-20 00:54] wakes up +[1518-05-15 00:36] wakes up +[1518-03-21 00:59] wakes up +[1518-10-09 00:11] wakes up +[1518-08-26 00:03] Guard #107 begins shift +[1518-03-20 00:35] falls asleep +[1518-11-22 00:49] wakes up +[1518-10-02 00:57] wakes up +[1518-08-20 00:18] falls asleep +[1518-07-04 00:59] wakes up +[1518-04-11 00:04] Guard #107 begins shift +[1518-07-01 00:54] falls asleep +[1518-07-20 00:40] wakes up +[1518-10-08 00:38] falls asleep +[1518-09-29 00:05] falls asleep +[1518-10-10 00:36] wakes up +[1518-10-01 00:08] wakes up +[1518-08-02 00:59] wakes up +[1518-10-23 00:53] wakes up +[1518-07-10 00:51] wakes up +[1518-08-19 00:42] falls asleep +[1518-06-24 23:56] Guard #2707 begins shift +[1518-10-22 00:11] falls asleep +[1518-04-15 00:59] wakes up +[1518-11-23 00:03] Guard #523 begins shift +[1518-04-17 00:42] wakes up +[1518-05-30 23:56] Guard #107 begins shift +[1518-04-23 00:39] wakes up +[1518-11-07 23:59] Guard #1523 begins shift +[1518-07-10 00:24] wakes up +[1518-05-26 00:00] Guard #2081 begins shift +[1518-04-26 23:51] Guard #1607 begins shift +[1518-10-30 00:14] falls asleep +[1518-05-16 00:48] falls asleep +[1518-04-08 00:53] wakes up +[1518-04-14 00:51] wakes up +[1518-07-23 00:03] Guard #2707 begins shift +[1518-07-14 00:06] falls asleep +[1518-06-18 00:09] falls asleep +[1518-06-25 00:38] wakes up +[1518-09-06 00:05] falls asleep +[1518-10-08 00:50] falls asleep +[1518-06-08 00:03] Guard #2287 begins shift +[1518-03-17 00:04] Guard #2707 begins shift +[1518-09-19 00:11] falls asleep +[1518-05-26 00:55] wakes up +[1518-06-04 00:58] wakes up +[1518-11-13 00:45] wakes up +[1518-06-24 00:00] Guard #1409 begins shift +[1518-06-08 00:59] wakes up +[1518-07-08 00:23] falls asleep +[1518-07-24 00:48] falls asleep +[1518-09-20 00:16] wakes up +[1518-11-11 00:59] wakes up +[1518-03-28 00:54] wakes up +[1518-06-14 00:56] wakes up +[1518-05-16 00:01] Guard #2857 begins shift +[1518-07-14 00:22] wakes up +[1518-03-26 00:16] wakes up +[1518-11-02 00:41] wakes up +[1518-07-12 00:04] falls asleep +[1518-08-27 00:01] Guard #2707 begins shift +[1518-10-10 00:01] Guard #1607 begins shift +[1518-08-23 00:55] wakes up +[1518-07-24 00:41] falls asleep +[1518-09-18 00:01] Guard #1409 begins shift +[1518-11-11 00:32] wakes up +[1518-09-22 23:50] Guard #1789 begins shift +[1518-10-11 00:44] wakes up +[1518-11-21 00:36] wakes up +[1518-10-29 00:49] falls asleep +[1518-05-01 00:27] wakes up +[1518-10-02 00:47] wakes up +[1518-04-21 00:53] wakes up +[1518-07-25 00:01] Guard #1787 begins shift +[1518-09-16 23:58] Guard #1409 begins shift +[1518-04-16 00:42] wakes up +[1518-04-08 23:59] Guard #2003 begins shift +[1518-07-28 00:21] wakes up +[1518-10-26 00:00] Guard #3469 begins shift +[1518-08-23 00:53] falls asleep +[1518-08-04 00:57] wakes up +[1518-10-29 00:22] wakes up +[1518-05-25 00:34] falls asleep +[1518-10-31 00:43] wakes up +[1518-05-17 00:50] wakes up +[1518-04-24 00:58] wakes up +[1518-03-26 00:10] falls asleep +[1518-04-17 00:31] falls asleep +[1518-10-11 00:19] falls asleep +[1518-04-05 00:01] Guard #523 begins shift +[1518-05-26 00:48] wakes up +[1518-09-25 00:14] falls asleep +[1518-06-15 00:32] falls asleep +[1518-07-23 00:51] wakes up +[1518-11-23 00:23] falls asleep +[1518-09-15 00:49] wakes up +[1518-06-30 00:27] wakes up +[1518-09-28 00:09] falls asleep +[1518-10-01 00:51] wakes up +[1518-10-10 23:59] Guard #3373 begins shift +[1518-04-02 00:14] falls asleep +[1518-08-21 23:57] Guard #3469 begins shift +[1518-11-03 00:52] wakes up +[1518-06-21 00:55] wakes up +[1518-09-11 00:03] Guard #2287 begins shift +[1518-04-06 00:04] Guard #1171 begins shift +[1518-04-29 00:13] falls asleep +[1518-05-21 00:41] falls asleep +[1518-07-13 00:09] falls asleep +[1518-07-03 00:55] falls asleep +[1518-10-22 00:40] falls asleep +[1518-11-16 00:56] wakes up +[1518-09-12 00:31] wakes up +[1518-10-07 00:02] Guard #2707 begins shift +[1518-06-04 23:52] Guard #107 begins shift +[1518-09-14 00:04] Guard #2707 begins shift +[1518-10-01 00:54] falls asleep +[1518-06-01 00:36] wakes up +[1518-03-24 00:44] wakes up +[1518-06-03 23:59] Guard #2069 begins shift +[1518-06-27 00:41] falls asleep +[1518-06-15 00:58] wakes up +[1518-11-10 00:34] falls asleep +[1518-04-18 00:27] falls asleep +[1518-10-28 00:48] falls asleep +[1518-08-06 23:59] Guard #107 begins shift +[1518-11-05 00:35] wakes up +[1518-04-12 00:00] Guard #1087 begins shift +[1518-08-22 00:34] falls asleep +[1518-05-24 00:29] falls asleep +[1518-11-20 00:19] falls asleep +[1518-03-21 00:54] falls asleep +[1518-04-07 00:49] falls asleep +[1518-05-25 00:50] wakes up +[1518-04-18 00:28] wakes up +[1518-09-09 00:13] falls asleep +[1518-09-19 00:21] wakes up +[1518-05-17 00:56] falls asleep +[1518-10-12 00:40] wakes up +[1518-07-18 00:33] wakes up +[1518-05-28 00:32] wakes up +[1518-03-29 00:28] wakes up +[1518-07-24 00:57] wakes up +[1518-08-18 23:58] Guard #1523 begins shift +[1518-07-23 00:15] falls asleep +[1518-05-21 00:35] wakes up +[1518-10-03 23:56] Guard #1523 begins shift +[1518-11-16 00:05] falls asleep +[1518-11-03 00:01] falls asleep +[1518-07-23 00:56] falls asleep +[1518-05-09 00:49] falls asleep +[1518-05-17 00:00] Guard #1627 begins shift +[1518-05-11 00:51] falls asleep +[1518-08-27 00:54] wakes up +[1518-05-11 00:20] falls asleep +[1518-06-11 00:19] falls asleep +[1518-08-17 00:01] Guard #1627 begins shift +[1518-09-17 00:57] wakes up +[1518-09-06 00:35] wakes up +[1518-09-21 00:48] wakes up +[1518-08-07 00:41] wakes up +[1518-10-05 00:11] falls asleep +[1518-06-28 00:40] wakes up +[1518-05-04 00:49] wakes up +[1518-03-31 00:49] wakes up +[1518-08-10 00:59] wakes up +[1518-10-15 00:01] Guard #3469 begins shift +[1518-10-08 00:20] wakes up +[1518-06-26 23:57] Guard #3373 begins shift +[1518-07-30 00:32] wakes up +[1518-07-03 00:39] falls asleep +[1518-07-13 00:24] wakes up +[1518-07-09 00:23] falls asleep +[1518-07-27 00:06] falls asleep +[1518-08-08 00:51] falls asleep +[1518-07-28 00:16] falls asleep +[1518-07-30 00:50] falls asleep +[1518-07-26 00:57] wakes up +[1518-09-28 23:48] Guard #1607 begins shift +[1518-10-16 00:41] falls asleep +[1518-07-16 00:00] Guard #523 begins shift +[1518-10-06 00:02] Guard #1087 begins shift +[1518-06-18 00:02] Guard #523 begins shift +[1518-04-07 23:57] Guard #107 begins shift +[1518-09-27 00:00] Guard #1607 begins shift +[1518-04-02 00:28] wakes up +[1518-08-28 00:14] falls asleep +[1518-10-21 00:05] falls asleep +[1518-07-28 00:02] Guard #2287 begins shift +[1518-07-18 00:01] Guard #2857 begins shift +[1518-05-08 23:56] Guard #107 begins shift +[1518-03-23 00:49] falls asleep +[1518-04-26 00:44] falls asleep +[1518-05-20 00:33] wakes up +[1518-07-07 00:04] Guard #2081 begins shift +[1518-08-19 00:57] wakes up +[1518-09-19 00:04] Guard #1171 begins shift +[1518-08-26 00:43] falls asleep +[1518-08-16 00:32] wakes up +[1518-07-01 00:00] falls asleep +[1518-11-03 00:38] falls asleep +[1518-06-05 00:29] wakes up +[1518-07-20 00:21] falls asleep +[1518-05-10 00:07] falls asleep +[1518-07-23 23:58] Guard #1439 begins shift +[1518-06-10 00:19] falls asleep +[1518-08-07 00:36] falls asleep +[1518-10-10 00:41] falls asleep +[1518-09-03 00:53] falls asleep +[1518-05-25 00:00] Guard #1627 begins shift +[1518-03-17 00:26] falls asleep +[1518-06-29 00:17] falls asleep +[1518-05-31 00:42] wakes up +[1518-06-03 00:11] falls asleep +[1518-09-28 00:24] wakes up +[1518-11-10 00:48] falls asleep +[1518-05-13 00:00] Guard #3469 begins shift +[1518-09-27 00:46] falls asleep +[1518-05-19 23:56] Guard #2399 begins shift +[1518-06-02 00:56] wakes up +[1518-07-04 00:33] wakes up +[1518-06-05 00:03] falls asleep +[1518-09-13 00:12] falls asleep +[1518-10-03 00:52] wakes up +[1518-11-06 00:34] wakes up +[1518-04-27 00:28] falls asleep +[1518-06-04 00:32] wakes up +[1518-04-25 00:00] Guard #1607 begins shift +[1518-05-17 00:26] falls asleep +[1518-10-14 00:32] wakes up +[1518-11-12 23:56] Guard #107 begins shift +[1518-09-30 00:02] Guard #2287 begins shift +[1518-11-10 00:04] Guard #107 begins shift +[1518-10-29 00:04] falls asleep +[1518-09-08 00:46] wakes up +[1518-03-28 00:26] falls asleep +[1518-08-03 23:57] Guard #2069 begins shift +[1518-07-29 00:55] wakes up +[1518-08-19 23:57] Guard #1627 begins shift +[1518-04-01 00:16] falls asleep +[1518-04-11 00:37] wakes up +[1518-11-21 00:53] falls asleep +[1518-08-21 00:03] Guard #1171 begins shift +[1518-04-24 00:45] falls asleep +[1518-10-04 00:44] wakes up +[1518-10-23 00:20] falls asleep +[1518-06-19 00:28] falls asleep +[1518-11-21 00:27] falls asleep +[1518-03-31 00:56] wakes up +[1518-06-06 00:54] wakes up +[1518-05-11 00:41] wakes up +[1518-08-03 00:24] falls asleep +[1518-07-01 00:55] wakes up +[1518-11-04 23:59] Guard #107 begins shift +[1518-06-05 00:53] wakes up +[1518-08-05 00:23] falls asleep +[1518-03-31 23:59] Guard #523 begins shift +[1518-09-23 00:01] falls asleep +[1518-07-13 23:58] Guard #1069 begins shift +[1518-11-15 00:45] falls asleep +[1518-06-03 00:56] wakes up +[1518-09-21 00:03] Guard #2399 begins shift +[1518-06-10 00:55] falls asleep +[1518-08-29 23:49] Guard #1523 begins shift +[1518-03-21 00:42] falls asleep +[1518-03-20 23:57] Guard #89 begins shift +[1518-07-29 00:33] falls asleep +[1518-04-30 00:57] falls asleep +[1518-09-12 00:05] falls asleep +[1518-10-13 00:54] wakes up +[1518-08-07 00:56] wakes up +[1518-04-29 23:59] Guard #2069 begins shift +[1518-04-28 00:06] falls asleep +[1518-06-14 00:36] wakes up +[1518-11-22 00:33] falls asleep +[1518-06-25 00:42] falls asleep +[1518-04-15 00:52] falls asleep +[1518-08-28 00:51] falls asleep +[1518-06-04 00:52] wakes up +[1518-10-29 00:31] falls asleep +[1518-11-06 00:27] falls asleep +[1518-05-12 00:04] falls asleep +[1518-09-26 00:49] wakes up +[1518-04-19 00:25] falls asleep +[1518-11-03 00:21] wakes up +[1518-10-08 00:55] wakes up +[1518-04-16 00:14] falls asleep +[1518-06-06 00:00] Guard #1627 begins shift +[1518-10-02 00:51] falls asleep +[1518-05-05 00:07] falls asleep +[1518-07-29 00:38] wakes up +[1518-09-17 00:55] falls asleep +[1518-06-22 00:24] falls asleep +[1518-04-17 23:58] Guard #1439 begins shift +[1518-09-21 23:46] Guard #523 begins shift +[1518-10-16 00:26] wakes up +[1518-07-15 00:53] wakes up +[1518-06-02 00:53] falls asleep +[1518-11-16 00:48] falls asleep +[1518-08-20 00:54] wakes up +[1518-05-03 00:57] wakes up +[1518-11-12 00:01] Guard #2081 begins shift +[1518-07-09 00:58] wakes up +[1518-11-18 00:03] Guard #2003 begins shift +[1518-07-31 23:54] Guard #1171 begins shift +[1518-10-16 00:57] wakes up +[1518-10-20 00:27] wakes up +[1518-10-17 00:58] wakes up +[1518-07-02 00:24] wakes up +[1518-08-08 00:56] wakes up +[1518-10-17 00:52] falls asleep +[1518-11-04 00:54] wakes up +[1518-08-26 00:35] falls asleep +[1518-10-20 23:47] Guard #1523 begins shift +[1518-05-03 23:58] Guard #89 begins shift +[1518-11-21 00:55] wakes up +[1518-03-31 00:55] falls asleep +[1518-10-17 00:06] falls asleep +[1518-10-27 00:00] Guard #1409 begins shift +[1518-07-03 00:41] wakes up +[1518-08-28 00:32] wakes up +[1518-10-08 00:51] wakes up +[1518-06-01 00:33] falls asleep +[1518-06-20 00:52] falls asleep +[1518-11-10 23:58] Guard #3469 begins shift +[1518-07-14 00:34] falls asleep +[1518-08-07 00:50] wakes up +[1518-08-09 00:26] falls asleep +[1518-03-29 00:00] Guard #1789 begins shift +[1518-09-09 00:02] Guard #1607 begins shift +[1518-11-05 00:22] falls asleep +[1518-08-12 00:57] falls asleep +[1518-11-17 00:50] wakes up +[1518-07-30 00:54] wakes up +[1518-06-29 00:54] wakes up +[1518-10-25 00:34] falls asleep +[1518-04-29 00:02] Guard #1069 begins shift +[1518-06-07 00:36] falls asleep +[1518-05-03 00:08] falls asleep +[1518-05-28 23:53] Guard #523 begins shift +[1518-09-15 00:59] wakes up +[1518-11-17 00:11] falls asleep +[1518-09-05 00:56] wakes up +[1518-04-22 00:01] Guard #1069 begins shift +[1518-10-26 00:45] wakes up +[1518-05-12 00:48] wakes up +[1518-10-26 00:26] falls asleep +[1518-10-30 00:36] falls asleep +[1518-11-04 00:43] falls asleep +[1518-07-31 00:30] wakes up +[1518-11-03 00:10] wakes up +[1518-05-09 00:45] wakes up +[1518-08-13 00:54] wakes up +[1518-05-18 00:45] wakes up +[1518-05-29 00:36] wakes up +[1518-04-28 00:34] falls asleep +[1518-08-18 00:38] wakes up +[1518-05-07 00:08] wakes up +[1518-07-21 00:09] falls asleep +[1518-06-24 00:52] falls asleep +[1518-11-04 00:28] falls asleep +[1518-07-03 23:50] Guard #3373 begins shift +[1518-06-27 23:54] Guard #1523 begins shift +[1518-05-26 00:33] wakes up +[1518-08-10 00:24] falls asleep +[1518-08-17 00:59] wakes up +[1518-09-08 00:35] falls asleep +[1518-10-14 00:59] wakes up +[1518-09-26 00:04] Guard #2003 begins shift +[1518-05-31 00:40] falls asleep +[1518-07-01 23:48] Guard #1627 begins shift +[1518-10-22 00:36] wakes up +[1518-05-28 00:47] falls asleep +[1518-05-01 23:46] Guard #1789 begins shift +[1518-06-15 00:56] falls asleep +[1518-06-20 00:33] wakes up +[1518-07-13 00:31] falls asleep +[1518-03-31 00:46] falls asleep +[1518-11-03 00:19] falls asleep +[1518-04-25 00:39] wakes up +[1518-07-21 00:51] wakes up +[1518-05-13 00:23] falls asleep +[1518-07-19 00:39] falls asleep +[1518-04-20 23:58] Guard #1439 begins shift +[1518-08-07 00:53] falls asleep +[1518-06-16 00:02] falls asleep +[1518-05-28 00:00] falls asleep +[1518-09-15 00:42] falls asleep +[1518-09-07 00:04] Guard #107 begins shift +[1518-10-05 00:03] Guard #89 begins shift +[1518-07-26 00:32] falls asleep +[1518-07-08 00:40] wakes up +[1518-07-10 00:02] Guard #523 begins shift +[1518-10-22 00:04] Guard #2707 begins shift +[1518-11-08 00:47] wakes up +[1518-10-14 00:15] falls asleep +[1518-10-17 00:00] Guard #1171 begins shift +[1518-10-29 00:46] wakes up +[1518-07-23 00:41] falls asleep +[1518-04-07 00:03] Guard #2287 begins shift +[1518-07-02 23:58] Guard #1439 begins shift +[1518-10-26 00:08] falls asleep +[1518-05-24 00:00] Guard #1523 begins shift +[1518-05-26 23:54] Guard #2707 begins shift +[1518-06-15 00:53] wakes up +[1518-04-30 00:59] wakes up +[1518-05-22 00:57] wakes up +[1518-08-14 00:41] wakes up +[1518-07-20 00:47] falls asleep +[1518-09-03 00:48] wakes up +[1518-03-23 00:38] wakes up +[1518-09-05 23:46] Guard #1607 begins shift +[1518-10-03 00:26] falls asleep +[1518-05-27 00:03] falls asleep +[1518-08-12 00:04] Guard #1523 begins shift +[1518-07-26 00:04] Guard #2081 begins shift +[1518-07-10 00:18] falls asleep +[1518-09-12 00:48] wakes up +[1518-09-06 00:23] falls asleep +[1518-11-06 00:00] Guard #2707 begins shift +[1518-10-28 00:01] Guard #2003 begins shift +[1518-10-07 23:57] Guard #1789 begins shift +[1518-05-28 00:18] falls asleep +[1518-08-02 00:02] Guard #1627 begins shift +[1518-09-27 00:58] wakes up +[1518-06-10 00:47] falls asleep +[1518-10-08 00:39] wakes up +[1518-06-19 00:49] wakes up +[1518-09-17 00:32] falls asleep +[1518-08-01 00:02] falls asleep +[1518-05-26 00:21] falls asleep +[1518-05-11 00:36] falls asleep +[1518-07-13 00:00] Guard #2707 begins shift +[1518-09-22 00:49] wakes up +[1518-04-28 00:25] wakes up +[1518-09-29 00:42] falls asleep +[1518-03-29 00:21] falls asleep +[1518-08-28 00:02] wakes up +[1518-03-26 00:44] falls asleep +[1518-10-04 00:40] falls asleep +[1518-08-24 00:42] falls asleep +[1518-06-07 00:56] falls asleep +[1518-03-28 00:43] wakes up +[1518-05-05 00:00] Guard #1607 begins shift +[1518-10-20 00:02] Guard #2857 begins shift +[1518-05-06 00:00] Guard #2399 begins shift +[1518-10-15 00:57] wakes up +[1518-03-18 00:44] wakes up +[1518-10-16 00:04] Guard #2857 begins shift +[1518-04-06 00:33] falls asleep +[1518-08-31 00:41] wakes up +[1518-06-23 00:35] falls asleep +[1518-10-13 23:57] Guard #3373 begins shift +[1518-07-01 00:42] wakes up +[1518-04-21 00:30] falls asleep +[1518-05-18 00:56] falls asleep +[1518-03-22 00:01] Guard #2003 begins shift +[1518-05-17 00:57] wakes up +[1518-03-24 00:17] wakes up +[1518-07-21 23:58] Guard #3469 begins shift +[1518-09-15 00:27] wakes up +[1518-08-11 00:25] falls asleep +[1518-06-04 00:47] falls asleep +[1518-05-31 00:20] falls asleep +[1518-06-07 00:18] wakes up +[1518-08-12 00:49] wakes up +[1518-11-09 00:11] falls asleep +[1518-10-16 00:15] falls asleep +[1518-09-10 00:23] wakes up +[1518-10-13 00:40] wakes up +[1518-04-03 00:06] falls asleep +[1518-08-23 00:03] Guard #2003 begins shift +[1518-08-04 23:57] Guard #107 begins shift +[1518-08-25 00:06] falls asleep +[1518-06-09 00:48] falls asleep +[1518-08-14 00:21] falls asleep +[1518-03-24 00:01] Guard #1409 begins shift +[1518-09-12 00:47] falls asleep +[1518-03-24 00:54] wakes up +[1518-04-14 00:34] falls asleep +[1518-04-24 00:02] Guard #89 begins shift +[1518-10-18 00:18] falls asleep +[1518-10-01 00:57] wakes up +[1518-07-23 00:59] wakes up +[1518-03-26 00:51] wakes up +[1518-05-21 00:18] falls asleep +[1518-07-07 00:09] falls asleep +[1518-09-02 00:54] wakes up +[1518-06-14 00:21] wakes up +[1518-09-01 23:59] Guard #2399 begins shift +[1518-10-21 00:43] wakes up +[1518-03-27 00:56] wakes up +[1518-04-16 00:52] falls asleep +[1518-04-29 00:53] wakes up +[1518-03-17 00:55] wakes up +[1518-05-15 00:00] Guard #1607 begins shift +[1518-09-10 00:16] falls asleep +[1518-06-13 00:54] wakes up +[1518-06-07 00:58] wakes up +[1518-08-10 00:00] Guard #2069 begins shift +[1518-08-25 00:20] wakes up +[1518-05-22 00:03] Guard #2069 begins shift +[1518-09-02 00:06] falls asleep +[1518-07-29 00:51] falls asleep +[1518-04-30 23:57] Guard #2287 begins shift +[1518-06-22 00:01] Guard #523 begins shift +[1518-08-17 00:12] falls asleep +[1518-09-14 00:12] falls asleep +[1518-04-08 00:39] wakes up +[1518-08-07 23:59] Guard #2069 begins shift +[1518-04-16 00:00] Guard #1523 begins shift +[1518-06-23 00:49] falls asleep +[1518-10-02 00:04] Guard #1069 begins shift +[1518-09-16 00:16] falls asleep +[1518-08-01 00:14] falls asleep +[1518-05-18 00:36] wakes up +[1518-10-23 00:56] falls asleep +[1518-04-08 00:36] falls asleep +[1518-08-20 00:52] falls asleep +[1518-06-14 00:46] falls asleep +[1518-07-07 00:56] wakes up +[1518-10-18 00:05] falls asleep +[1518-08-21 00:50] wakes up +[1518-04-26 00:58] wakes up +[1518-05-09 00:51] wakes up +[1518-10-08 00:15] falls asleep +[1518-11-11 00:15] falls asleep +[1518-05-27 00:55] falls asleep +[1518-08-29 00:04] Guard #2707 begins shift +[1518-05-18 00:43] falls asleep +[1518-03-18 00:04] Guard #2707 begins shift +[1518-05-14 00:25] falls asleep +[1518-08-06 00:44] wakes up +[1518-03-29 23:59] Guard #107 begins shift +[1518-03-22 00:56] wakes up +[1518-11-15 00:02] Guard #2857 begins shift +[1518-04-27 00:12] wakes up +[1518-08-13 23:58] Guard #89 begins shift +[1518-06-23 00:38] wakes up +[1518-09-18 00:58] wakes up +[1518-08-12 00:22] wakes up +[1518-10-16 00:45] wakes up +[1518-05-31 00:35] wakes up +[1518-10-27 00:40] wakes up +[1518-08-14 23:52] Guard #1607 begins shift +[1518-07-20 23:58] Guard #1523 begins shift +[1518-05-07 00:14] falls asleep +[1518-09-01 00:57] wakes up +[1518-08-15 23:49] Guard #2399 begins shift +[1518-11-02 23:50] Guard #1789 begins shift +[1518-05-25 00:57] wakes up +[1518-11-12 00:51] wakes up +[1518-11-19 00:04] Guard #2857 begins shift +[1518-03-30 00:49] wakes up +[1518-11-17 00:43] falls asleep +[1518-09-11 00:55] falls asleep +[1518-08-29 00:27] falls asleep +[1518-06-17 00:52] wakes up +[1518-06-28 00:01] falls asleep +[1518-10-28 23:46] Guard #523 begins shift +[1518-05-14 00:02] Guard #1069 begins shift +[1518-10-13 00:27] falls asleep +[1518-10-01 00:32] falls asleep +[1518-06-08 00:36] falls asleep +[1518-04-15 00:08] falls asleep +[1518-07-16 00:17] falls asleep +[1518-04-23 00:22] falls asleep +[1518-03-26 23:58] Guard #1069 begins shift +[1518-09-24 00:48] wakes up +[1518-03-25 23:57] Guard #3373 begins shift +[1518-07-16 00:32] falls asleep +[1518-05-30 00:17] falls asleep +[1518-07-11 00:34] falls asleep +[1518-04-16 23:57] Guard #1607 begins shift +[1518-10-13 00:51] falls asleep +[1518-07-02 00:00] falls asleep +[1518-04-28 00:48] wakes up +[1518-05-09 00:30] falls asleep +[1518-06-24 00:59] wakes up +[1518-06-26 00:17] falls asleep +[1518-06-09 00:02] Guard #1607 begins shift +[1518-04-22 00:39] wakes up +[1518-06-16 00:49] falls asleep +[1518-07-20 00:56] wakes up +[1518-11-19 00:48] wakes up +[1518-06-13 00:02] Guard #1409 begins shift +[1518-04-03 00:57] falls asleep +[1518-04-02 00:39] falls asleep +[1518-04-11 00:32] falls asleep +[1518-11-12 00:34] falls asleep +[1518-05-26 00:54] falls asleep +[1518-05-23 00:00] Guard #2657 begins shift +[1518-05-19 00:35] wakes up +[1518-06-23 00:05] falls asleep +[1518-08-18 00:42] falls asleep +[1518-10-22 00:52] wakes up +[1518-03-24 00:12] falls asleep +[1518-04-13 23:56] Guard #2707 begins shift +[1518-06-17 00:36] falls asleep +[1518-07-14 00:45] wakes up +[1518-08-09 00:43] wakes up +[1518-11-20 00:52] wakes up +[1518-09-29 00:35] wakes up +[1518-06-13 00:41] wakes up +[1518-07-22 00:57] falls asleep +[1518-09-01 00:04] falls asleep +[1518-03-31 00:00] Guard #2287 begins shift +[1518-03-18 00:32] falls asleep +[1518-06-06 00:12] falls asleep +[1518-04-10 00:04] Guard #2003 begins shift +[1518-07-24 00:42] wakes up +[1518-08-26 00:54] wakes up +[1518-05-03 00:02] Guard #107 begins shift +[1518-09-20 00:07] falls asleep +[1518-11-16 23:57] Guard #107 begins shift +[1518-08-18 00:50] wakes up +[1518-04-20 00:52] falls asleep +[1518-09-23 23:58] Guard #89 begins shift +[1518-07-13 00:38] falls asleep +[1518-05-06 00:23] falls asleep +[1518-05-18 23:50] Guard #2287 begins shift +[1518-10-31 23:59] Guard #1087 begins shift +[1518-07-06 00:03] Guard #1069 begins shift +[1518-05-01 00:53] wakes up +[1518-07-11 00:22] wakes up +[1518-07-19 00:04] Guard #2399 begins shift +[1518-05-28 00:59] wakes up +[1518-03-22 23:50] Guard #1171 begins shift +[1518-05-02 00:05] falls asleep +[1518-07-30 00:06] falls asleep +[1518-09-04 23:57] Guard #2069 begins shift +[1518-10-31 00:22] falls asleep +[1518-09-28 00:03] Guard #107 begins shift +[1518-07-06 00:07] falls asleep +[1518-04-29 00:42] wakes up +[1518-04-25 23:56] Guard #2857 begins shift +[1518-09-22 00:05] falls asleep +[1518-04-08 00:47] falls asleep +[1518-10-26 00:21] wakes up +[1518-07-13 00:46] wakes up +[1518-11-19 00:43] falls asleep +[1518-09-13 00:01] Guard #523 begins shift +[1518-06-09 00:54] wakes up +[1518-11-15 23:47] Guard #1171 begins shift +[1518-10-27 00:15] falls asleep +[1518-07-19 00:55] wakes up +[1518-05-28 00:01] wakes up +[1518-10-30 00:54] wakes up +[1518-09-29 00:59] wakes up +[1518-08-11 00:04] Guard #2287 begins shift +[1518-04-05 00:22] falls asleep +[1518-04-29 00:52] falls asleep +[1518-06-30 00:01] Guard #1439 begins shift +[1518-07-03 00:58] wakes up +[1518-06-29 00:04] Guard #3469 begins shift +[1518-10-17 00:48] wakes up +[1518-05-29 00:04] falls asleep +[1518-07-04 00:11] wakes up +[1518-09-30 23:49] Guard #523 begins shift +[1518-06-22 00:39] wakes up +[1518-08-26 00:40] wakes up +[1518-04-06 00:21] wakes up +[1518-06-23 00:59] wakes up +[1518-06-25 00:14] falls asleep +[1518-07-11 23:48] Guard #2707 begins shift +[1518-05-26 00:45] falls asleep +[1518-11-10 00:39] wakes up +[1518-10-20 00:44] falls asleep +[1518-08-30 00:42] wakes up +[1518-05-08 00:44] falls asleep +[1518-10-13 00:03] Guard #1409 begins shift +[1518-08-31 23:54] Guard #89 begins shift +[1518-11-14 00:20] wakes up +[1518-10-01 00:03] falls asleep +[1518-08-09 00:56] falls asleep +[1518-10-15 00:07] falls asleep +[1518-11-06 23:56] Guard #1069 begins shift +[1518-04-09 00:55] wakes up +[1518-08-02 00:11] falls asleep +[1518-06-16 00:42] wakes up +[1518-09-24 00:17] falls asleep +[1518-06-13 23:54] Guard #1789 begins shift +[1518-10-18 00:32] wakes up +[1518-11-11 00:47] falls asleep +[1518-04-06 00:56] wakes up +[1518-07-26 00:48] wakes up +[1518-04-10 00:52] falls asleep +[1518-07-19 23:59] Guard #2857 begins shift +[1518-09-05 00:44] falls asleep +[1518-06-09 00:38] wakes up +[1518-07-31 00:16] falls asleep +[1518-04-20 00:03] Guard #2857 begins shift +[1518-09-11 00:58] wakes up +[1518-03-23 00:50] wakes up +[1518-09-10 00:04] Guard #2287 begins shift +[1518-09-24 00:38] falls asleep +[1518-07-15 00:47] falls asleep +[1518-08-27 23:49] Guard #2003 begins shift +[1518-06-10 00:57] wakes up +[1518-04-03 00:00] Guard #3469 begins shift +[1518-07-12 00:34] wakes up +[1518-10-02 00:45] falls asleep +[1518-07-15 00:04] Guard #2003 begins shift +[1518-06-04 00:57] falls asleep +[1518-11-23 00:53] wakes up +[1518-06-11 00:46] wakes up +[1518-07-27 00:38] wakes up +[1518-07-10 00:44] falls asleep +[1518-06-01 00:04] Guard #2707 begins shift +[1518-06-10 00:49] wakes up +[1518-11-03 23:57] Guard #1439 begins shift +[1518-11-16 00:24] wakes up +[1518-07-04 00:20] falls asleep +[1518-06-22 23:49] Guard #1627 begins shift +[1518-10-30 00:04] Guard #2081 begins shift +[1518-07-15 00:52] falls asleep +[1518-04-14 23:57] Guard #3469 begins shift +[1518-04-04 00:07] falls asleep +[1518-07-05 00:07] falls asleep +[1518-03-21 00:49] wakes up +[1518-04-10 00:57] wakes up +[1518-07-27 00:42] falls asleep +[1518-04-04 00:21] wakes up +[1518-05-13 00:57] wakes up +[1518-09-23 00:43] wakes up +[1518-09-26 00:13] falls asleep +[1518-06-24 00:33] falls asleep +[1518-09-24 23:59] Guard #1523 begins shift +[1518-08-05 00:40] wakes up +[1518-07-18 00:08] falls asleep +[1518-06-03 00:03] Guard #2399 begins shift +[1518-04-24 00:22] wakes up +[1518-06-30 23:46] Guard #2399 begins shift +[1518-09-23 00:20] wakes up +[1518-09-03 00:54] wakes up +[1518-03-25 00:01] Guard #1523 begins shift +[1518-11-09 00:02] Guard #523 begins shift +[1518-08-06 00:47] falls asleep +[1518-10-24 00:22] falls asleep +[1518-03-22 00:48] wakes up +[1518-10-23 23:56] Guard #107 begins shift +[1518-07-28 00:27] falls asleep +[1518-07-27 00:44] wakes up +[1518-06-20 00:59] wakes up +[1518-05-09 23:56] Guard #2857 begins shift +[1518-04-28 00:00] Guard #1439 begins shift +[1518-06-16 00:59] wakes up +[1518-10-09 00:03] Guard #2857 begins shift +[1518-10-24 00:40] wakes up +[1518-09-16 00:59] wakes up +[1518-08-20 00:48] wakes up +[1518-08-06 00:43] falls asleep +[1518-07-09 00:00] Guard #1439 begins shift +[1518-08-25 00:00] Guard #107 begins shift +[1518-06-20 00:31] falls asleep +[1518-05-16 00:40] falls asleep +[1518-05-24 00:55] wakes up +[1518-08-01 00:04] wakes up +[1518-07-26 00:52] falls asleep +[1518-10-11 23:59] Guard #2399 begins shift +[1518-10-10 00:57] wakes up +[1518-10-05 00:50] falls asleep +[1518-08-24 00:53] wakes up +[1518-06-13 00:52] falls asleep +[1518-10-25 00:04] Guard #1069 begins shift +[1518-09-21 00:45] falls asleep +[1518-06-07 00:00] Guard #1409 begins shift +[1518-04-01 00:32] wakes up +[1518-07-09 00:44] falls asleep +[1518-10-30 00:25] wakes up +[1518-06-14 00:35] falls asleep +[1518-07-22 00:52] wakes up +[1518-08-06 00:04] Guard #1523 begins shift +[1518-03-22 00:52] falls asleep +[1518-10-23 00:59] wakes up +[1518-11-08 00:31] falls asleep +[1518-04-07 00:56] wakes up +[1518-07-23 00:37] wakes up +[1518-09-17 00:51] wakes up +[1518-06-18 00:11] wakes up +[1518-09-15 00:20] falls asleep +[1518-04-03 00:53] wakes up +[1518-10-14 00:57] falls asleep +[1518-09-08 00:03] Guard #1607 begins shift +[1518-04-27 00:46] wakes up +[1518-03-31 00:11] falls asleep +[1518-04-27 00:01] falls asleep +[1518-06-21 00:02] Guard #1627 begins shift +[1518-07-29 00:03] Guard #107 begins shift +[1518-05-10 23:56] Guard #1409 begins shift +[1518-05-18 00:57] wakes up +[1518-09-26 00:58] wakes up +[1518-11-18 00:59] wakes up +[1518-05-30 00:45] wakes up +[1518-11-09 00:38] wakes up +[1518-03-20 00:04] Guard #2081 begins shift +[1518-04-06 00:19] falls asleep +[1518-09-03 23:57] Guard #1523 begins shift +[1518-10-05 00:59] wakes up +[1518-08-15 00:00] falls asleep +[1518-07-04 00:03] falls asleep +[1518-10-10 00:10] falls asleep +[1518-09-24 00:27] wakes up +[1518-04-09 00:48] falls asleep +[1518-06-07 00:15] falls asleep +[1518-05-19 00:02] falls asleep +[1518-07-09 00:37] wakes up +[1518-05-21 00:51] wakes up +[1518-08-04 00:49] falls asleep +[1518-08-27 00:19] falls asleep +[1518-09-20 00:55] wakes up +[1518-06-26 00:03] Guard #1523 begins shift +[1518-11-04 00:36] wakes up +[1518-08-13 00:45] falls asleep +[1518-10-28 00:55] wakes up +[1518-11-19 00:58] wakes up +[1518-06-05 00:35] falls asleep +[1518-11-06 00:42] falls asleep +[1518-09-03 00:18] falls asleep +[1518-05-08 00:59] wakes up +[1518-07-08 00:39] falls asleep +[1518-03-28 00:00] Guard #1607 begins shift +[1518-06-26 00:36] wakes up +[1518-09-30 00:41] falls asleep +[1518-07-22 00:59] wakes up +[1518-07-08 00:30] wakes up +[1518-03-27 00:16] falls asleep +[1518-10-18 23:57] Guard #2399 begins shift +[1518-04-23 00:00] Guard #2857 begins shift +[1518-11-13 00:36] falls asleep +[1518-10-12 00:31] falls asleep +[1518-11-18 00:35] falls asleep +[1518-05-05 00:52] wakes up +[1518-04-22 00:16] falls asleep +[1518-09-02 23:59] Guard #1409 begins shift +[1518-04-13 00:09] falls asleep +[1518-08-02 23:58] Guard #2287 begins shift +[1518-05-14 00:51] wakes up +[1518-06-16 23:59] Guard #1439 begins shift +[1518-06-23 00:22] wakes up +[1518-06-25 00:54] wakes up +[1518-10-19 00:47] falls asleep +[1518-06-21 00:39] falls asleep +[1518-08-12 00:59] wakes up +[1518-10-03 00:56] wakes up +[1518-09-16 00:04] Guard #1789 begins shift +[1518-05-01 00:26] falls asleep +[1518-03-31 00:36] wakes up +[1518-11-02 00:01] Guard #107 begins shift +[1518-07-31 00:02] Guard #523 begins shift +[1518-08-29 00:32] wakes up +[1518-07-04 00:36] falls asleep diff --git a/adventOfCode/2018/41.py b/adventOfCode/2018/41.py new file mode 100644 index 0000000..3581652 --- /dev/null +++ b/adventOfCode/2018/41.py @@ -0,0 +1,208 @@ +# Guard falling asleep +# Example: +# * [1518-11-01 00:00] Guard #10 begins shift +# * [1518-11-01 00:05] falls asleep +# * [1518-11-01 00:25] wakes up +# Format: +# * [year-month-day hour:minute] < begins shift/ falls asleep/ wakes up > +# +# Logic: +# * Parse each line and group into a dictionary +# * Data --> ID --> sleep times, wake times +# * Create table and populate data + +import sys +from datetime import datetime + +def parse_data(input, data): + for i in input: + try: + if i: + # Parse data + + # Date + i = i.split("]") + time = datetime.strptime(i[0].strip("["), '%Y-%m-%d %H:%M') + if time.day < 10: + day = "0"+str(time.day) + else: + day = str(time.day) + date = str(time.month)+"-"+day + + # Guard id and activity + remaining = i[1].split(" ") + if "#" in remaining[2]: + guard = remaining[2] + activity = remaining[3] + else: + activity = remaining[2] + + # Fill dictionary + if date not in data: + data[date] = {} + if guard not in data[date]: + data[date][guard] = {} + + # Minute + if time.minute < 10: + minute = "0"+str(time.minute) + else: + minute = str(time.minute) + + # Activity + #print data, minute, activity + if activity == "asleep": + if minute not in data[date][guard]: + data[date][guard][minute] = "" + data[date][guard][minute] = "last" + if activity == "up": + for min in data[date][guard].keys(): + if data[date][guard][min] == "last": + data[date][guard][min] = minute + #break + except: + print i + #print data + return data + +def andOp(s1, s0=[0]*60): + test = s0[:] + #maxi = -1 + for i in range(len(s1)): + if s1[i] == "#": + test[i] += 1 + #maxi = max(maxi, test[i]) + return test + +def create_table(data): + max_sleep = 0 + pattern = {} + max_person = "" + print "Date ID Minute" + print " "+"0"*10+"1"*10+"2"*10+"3"*10+"4"*10+"5"*10 + print " "+"0123456789"*6 + dates = sorted(data.keys()) + + # part2 + maxim = -1 + maxim_ = "" + maxim_time = -1 + + for date in dates: + last = 0 + ranger = "" + + # part2 + #maxim = -1 + #maxim_ = "" + + #print date, ide + for id in data[date].keys(): + if data[date][id] != {}: + acts = sorted(data[date][id].keys()) + + for act in acts: + ranger += "." * (int(act)-last) + #last = int(act) + ranger += "#" * (int(data[date][id][act]) - int(act)) + last = int(data[date][id][act]) + + ranger += "." * int(60-int(data[date][id][act])) + + if "max_sleep" not in data[date][id]: + data[date][id]["max_sleep"] = 0 + + data[date][id]["max_sleep"] += ranger.count("#") + + if id not in pattern: + pattern[id] = {} + + #if "intersection" not in pattern[id]: + # pattern[id]["intersection"] = [] + + if "pattern" not in pattern[id]: + pattern[id]["pattern"] = andOp(ranger) + #if id == "#1523": + # print pattern[id]["pattern"] + else: + pattern[id]["pattern"] = andOp(ranger, pattern[id]["pattern"]) #pattern[id]["pattern"] and ranger + #if id == "#1523": + # print pattern[id]["pattern"] + #for u in range(len(pattern[id]["pattern"])): + # if ranger[u] == pattern[id]["pattern"][u]: + # pattern[id]["intersection"] = u + + if "intersection" not in pattern[id]: + pattern[id]["intersection"] = 0 + + if "max_time_sleep" not in pattern[id]: + pattern[id]["max_time_sleep"] = 0 + + pattern[id]["max_time_sleep"] = max(pattern[id]["pattern"]) + + pattern[id]["intersection"] = pattern[id]["pattern"].index(max(pattern[id]["pattern"])) # pattern[id]["pattern"].index("#") + #if pattern[id]["intersection"] > maxim: + # maxim = pattern[id]["intersection"] + # maxim_ = id + + if "s" not in pattern[id]: + pattern[id]["s"] = [] + pattern[id]["s"].append(ranger) + + if "max_sleep" not in pattern[id]: + pattern[id]["max_sleep"] = 0 + pattern[id]["max_sleep"] += ranger.count("#") + #pattern[id]["max_sleep"] + + if pattern[id]["max_sleep"] > max_sleep: + max_sleep = pattern[id]["max_sleep"] + max_person = id + print date+" "+id+" "+ ranger + + #print pattern + # Visually Interpret Part B answer from this last part + for id in pattern.keys(): + if pattern[id]["max_time_sleep"] > maxim: + maxim = pattern[id]["max_time_sleep"] + maxim_time = pattern[id]["intersection"] + maxim_ = id + #for com in pattern[max_person]["s"]: + # print com + for id in pattern.keys(): + print "=====> "+ id + for s in pattern[id]["s"]: + print s + a = [] + for c in pattern[id]["pattern"]: + if c == 10: + a.append("A") + elif c == 11: + a.append("B") + elif c == 12: + a.append("C") + elif c == 13: + a.append("D") + elif c == 14: + a.append("E") + elif c == 15: + a.append("F") + elif c == 16: + a.append("G") + else: + a.append(str(c)) + #print "".join([str(c) for c in pattern[id]["pattern"]]) + print "".join(a) + return max_sleep, max_person, pattern[max_person]["intersection"], maxim_time, maxim_ + +def main(): + data = {} + input = open("41.input","r").read() + input = input.split("\n") + input = sorted(input) + #print input + max_sleep, max_person, most_times, p21, p22 = create_table(parse_data(input, data)) + print max_sleep, max_person, most_times + print "Answer is "+ str(int(max_person.strip("#"))*most_times) + print p21, p22, "Answer: "+ str(int(p22.strip("#"))*p21) + +main() diff --git a/adventOfCode/2018/51.example b/adventOfCode/2018/51.example new file mode 100644 index 0000000..8637b35 --- /dev/null +++ b/adventOfCode/2018/51.example @@ -0,0 +1 @@ +dabAcCaCBAcCcaDA diff --git a/adventOfCode/2018/51.input b/adventOfCode/2018/51.input new file mode 100644 index 0000000..66a5c80 --- /dev/null +++ b/adventOfCode/2018/51.input @@ -0,0 +1 @@ +wUuXxrRbeEaAuUMmJUuXxvoFfMmOTjJmMtVvmMVWpdDPwGgAalVvLKkNmlAaLMnpGgeEcCcCBbpPPHmpzZPAaPQqkKMSsmuUpJjMPpNnhHhJjrRpIyYBbbBiMmPxXMgGsBbSmxihHIXIijAaKkZfxoOXFUunNntTNzFZrhCTtSshHcHhHRlLVvrPpsSiNaAvTtmMVIiYyrhpPHRUvhHVunIXxHhaBbAewWEsSrYyOpPlLoxzZoOiIZzXYFJCcQqjxXfNJjNOonnDcCddDbFlbBLfByRNnRMmXzZMeEiIUpPEeuRrGgHhMmlLqyYQlzHhZMmztTZLrRtTkiIoOZzKmbBeEvVLlxPpXWwcCxmMYTtyIixXdjJDHsSPphHzZBbkKrYyRhWMmiIwssSRuUrPCnNcpSWZzLlQqwsFCcNnbAaBfOPpVTtviIoCcZXxTTttzjVvrRJRuUbBUuYSsyLlrSZzMWgGDdYywFzZfkuUvVKdDllvxXVXxTtEeEeJjfnQoOpPOYJjyQqoqNFwWAzuUdAaDHmMhZaflLFmuUMBolUuLhHvWWwwIikwWKVFdnNDYyvVfaHhVvAVvODdQFfxXHSsCchHcCRrhjJqZzrdOOobBaAPpoDbBAPphHasSvUUuuVPhEeHvVUuNpPSxmLliIqiIQMTtXVvJjlFwWMmfLhCcHhZzLbSsDdByYyYlJWwjgGHrqQRsEeRNnrDdtTEQVpPvBbFfFiZzIVvfIiPpuwWUqHhJKkmMWwjefFKstCcTZpPzSoOMoFfOvVmHhqGIaGgAigcCQkTbxfvVDdQbBqsSYyvYyxXPpEeVFwWAeEaPpxBbXXxhHJjiItTyYrRRgGLlHnNhhjJaAcCTAatyxXYjJvVGgLjAaPpXxAZzaXxzZJVjuUDdJvlsSwWHXmOoMHJjrRcCuUajlLJAuUECcKiyYIksSeQOovVQqfFqiIhqQoOYMeEnNQUUuuqmybBbQLlBCcXxbqBHhlLqQbBnNxoOznNXxRriImMZPpRErqQtTRpPeZzYiIyVqQvjNnoOJtHheETLltTuUrLQqlQiIqfFtyYTjJRrBEtvVTegGVvhsSHThHgGtPxgGRrXRkKrNnpTtxXnNLWwDCcdtwWQqTwZJjEezKhHuUkRrWmTtwWHhAaQqMqQllLMmnWdDcCIiMVvWwUsxXJeEjSCTtcumwDdsyYStThHAiIwsSOYyoJjcCWMUumPODbBdPtOoTWBbwLpPlpzeEZoOoOJjFfrRNHSwlsSLWsHhDnzZNJzZaAFDdfQqoEJjHhhHJjeWRriItTXxwupkKPPoOoLlOWwqQsSDlXHhxWwLQqLldWJjhHwGRrqQhHcBbCBtTbeJjRrNxEeXnCcIiHhNnEpPPppPewWEbBwaANDLldnwDdDNndzZWzZksmMSFfKPJEejPppQMmqWwWxqLlSsQtfFcDGgdKYykDdYXrRLlbwCcWBzAaIaAjJxXkKirRZxyLFfjJltTQqpWHhwlLPRrdGgTtDEjJeEuFfypPYUSBBbbsXxcCOoCciIBbQqexXCFfolQqMmuULeEBtTuUbmTtAaMUuxXVvVvLlmzwWZMOJjPfFRrFflLpAmHhNnYlLPpwWywWbBpOoUuUuQqCcPeEyYManNPXRrauUAZznNKkYylLrRPpcCqlLPpsSQxFJjRrfRSsWwIivSBbiINnEDdkNnAPGgvVxXpNcCnIZzfFiExXLlzZjgGCcfFSiUjJFahxXHZzACcfFfYyuIyYPGgEeZmMFeEflLzpNnfFsLnNHwWXxWwheEZzlHQrRLlsSfNAapdDAamMQqUcCuPwWwWWwCNncbZnNphHPoOaAugOoGgGKkzZUGaDdAgXxzMmrRvVZzfFOoVvLlBKRrkDdSHNnBBKkcAaUuoOjJCMAardfwWzZhHJjVvgGkxXjJjRrJKezZRrEwWCcWwFDZziPpInPpNoOnNHabCcIiBPBbpIwfFfYyFMSsqQmiIzXxZiIYygGeoOEPpZzuUZYyzEedLlDWdDcaTtAwWNnnQqPpNSsCiukKUavyYVyMmYjJEEeJjeuUxXYpPeENnVrRvtzZDdSsoOlsGgSLPpTyzZXdDSsxAAEGhUJjuQqcCHWaAdDwliILgFfhHjJehHmGgYRrycCcQqCpPidzZDIITtiWKdDkKkbEeLlBPpwOoXxcCRruBtTkKXxKkUQBSspPjJEsSsjJShcpPCQqXGgxilyYZzLIHIiqQwWFIinsSNfsSsSrRZTtecCGgHhqQEQqWwmMVzRrqQZdDZlLwAaWcCWwgGzvvnNRtTDdwWrYyMmYbBXxcCIiyvVvVQXxNnqFvVmMsStTfGgvVGoOYyKkowrRgNYyqxXDdYyJjiILlZfFiIDoRrBbOdMmcCvSnNsqQyYsSfFVDdIivnFTtIkIiKiIiTdpUuZzPNuUnHhLlaADyqQSsShHvVsYtqQnNoEeEewWOBbBbiIRrfBeEbnYyNWwCBbcQqNBbmMDduUhFfHhHIIihHYOoyihHmbBMADdwSsWaVFfoOmZzDWwhHjJyYcFfCRLSslNnAmMzZaryYZzdsSaJanNAjyYqQpPDXxDdzZxXyYdVrRFPpKTtmRKkrMkZzfvFMmfeJjpBbBqQGrhHRuUyKFfPplLkSsvdIiDAaspgGPShHWwJydJDSsdHtTibBIlLYywWZzhZzjbDdBZzDZuzZUPpkuYUuyhHbBkPsSpFLVvlfWIiwrRLlclwWLrRtTbZzBJjHhwWgyYGXxCKUKkgNnCclWwLGgLsSlGxPaAfFPbBWMmwpkKqQwWwWpcCXRrVAascCSPpJjJoONnjfgtTGvVtiqQNglLGnuhodDOHhDdKkTjJtgGaOfhHFGgofFAHUfFzLUuvVrvsSVwVviIlLWtyYTtVvTQAaqhvldDLsSVoOHYymMcQDdqcZzCeEvVEeeECRGCcQLLlllLAaRrZzQqCDdcqQqHrRhlidDuUWWwweEIvVBULluiIRrZBbcCJjxSsXzIijEpiIPpPedDoOIoOiuTtAaUqQCcJXQquUwWqQxbAamzZMqVvlLZzQZlLNEefFnIiMmTtAabYZzyzZBhqQhHpYycCPQXxqPwWgyYWwZwWKoDdOhHkTtjJaAQqRrlLlIieELJwUKkKxXEekcBbCRkKvSsVrZzfzLlZxnNXFTFfjJyNnrEeRYpPwDdWOoizZeEIOofmWwMmMFtKkuGgKkWLoOlMmxXIijibBrYyRBbOmMDVvyYdohrRFfHfFSsukKuUzZUAahHIVvzMmZqmMxlLlLXGzZmMmXxzZhqQGgHiICcXAhHaVvtDdZzhHDAahHdTydDxVvXaAGgYDlLdjGKkuUOoAFfZzxXRrOoagJJSsLlOoFJCGjJgGOoAmMaiIuUYgGsSylbFpXDdxPyYfnNEeZzExmExXAzZnNsSaeDdCcMuYyUhHKEeEefYKkEsSAaGgeyKkGqQgibBxXIFkKvVNnIzZilLYyYHhIiDdyrXxRtTksBbtTMmBsSbBbSBbfFpPSsZKIKfFkisiIZXxqQzSkVvzZlLtTzNnCzajZzJAZmMvVQUuzZyYqczZxPpXtrRTiIfbBFYBRrbybiIBNnPpdDVvbRrkwLTthHlpPWsMmYyIiZzzZnNzZcDbBKkLlyaAwWYYhHyAaXJjPRrpkzZKxzxXZgGhHdKzYyZkZyYzxjJXTFfbMaAmMIimKfFYOoywWkHDdzZnLlsYySNBAiIjSsJabgGwbDdBOsxXvVSnNCcXxBbHHkvVlLKGgdDaAkLlGgRrRrjVvlLeTtEgGHhqQqQwWJrRrRZzloOLzfFZdTtJjDHLlhgGsStqQTtokKOOopPTtlcCLBaAfFTtTtCGgMmcpPLlNnaZzWwfFShHspPUurvVRfFwWqXxQMphHPCcbAaSHhmMyNnYeEiIgsSJjGmMKEekZzKkwWVrCLlzZTtcRLRrqlLcCQGgiIGglZMmWwzrRnFaAfFJtAamMTHhbLleEBjRKkWwrJSsjsbBSOpPLlojJuUxnNSseEXnNmKPugGzZmtdDgGyYTnNDdxsSXMxXdDMmaCcsnNMmSAEelLhqrMmlLqbBQQqRicCINnOoPppPyYQqOwWajfFEeMmSsHcChfFJBEJjeCcOopOoPwWkwWKyYuUWQkKqwxSgGKkUVvfFVaymMAadpPnzZZzsSzZNfGgkKqQFVvtTDlLqQYHhzZEeLGglaAJjAcCaHhHhJjyJjzZsSYAPpaUufBbFeESsxalLVsSvAxXkKiIcCEujJUilLIEIbBMEvpcnNRrCRrRDXxkKtTtTEjJjVvJQqArPAzZTtfrRSsDdsSnFfNbdDXxfcCrRScnNNnrRCNnszZnJgGhlLHjNFeEoBbQmMyYqnNQZEKhHkpPeStZzsSVKXxkvhHGYIiCTtcyKSdkKBNqQnbeBbmMEFFffIiDaAiIUcCmxXMuUuxXuLlUgGEcCekKEAaeXxkKRrshHtTuxXrRkKUoOwWPnPpNZzlRrAadDDdkiIRcGgmMCBbiAZVIiBoUuObiLlxXUuMmjKkJzZIAapPjJvDdmKjJHhXBbxlolLOLdWNnzAbBaZwWgDdtsVWcCwjJgGBYyRfFrbRrtTvPeEFfpqQiISjzZcCJlDdVvLltTLaAKWwQqkpXMmAaxhPyYpPpxXEeHPpPdxsSDNnNBbqQndCczZBIRyYrTtapPAkcCEeAaGgKibwWDxDdXdRZzSIisriIjJrRLjJFgmWwMRrLlJjBbGcCNKknXxcNnCdPpVvwWrRDeJxXIijEbMPpvVYymBUubBbAEekyDdYBbXxBbeWwTtERKkFfeErUwWAaJMmjuReSFkaAlLKfswUuWXaAEYyexOoLGcCglEezZSNorRvVcCOjJvVnbBIiWdGmMVvTtlYyLrRgcCSsDhFfvVHvdGgsSWwsSxIHKkiITFDdlLKkmMtTwWflXxOoLXxtBkKnNvVuUBbgBbKkdYWlLEtTeTtwvWwVjdDJSslLVIiTbMmBlLsSkKUiIHhmyYQqMPpRrYVvyneLHhlENnNIiVLUulvkKvIiWqWCcwQoGQqgofRrTJjZztUDduAaFgyzZHMmhrRnNJjYgGHgGAYyaxQbBqXqQaaAoOzZdDnWovVODjJFfdOowdDNmzZwWvYyIimMmjomMNnjYJvNBbrRKEekLlnIiVWXxuoONzuUZnlLKkXEBbNnexuIiUUAvVaBHhbuAPrRaAYNnyuKkUZXxgWwGqQMmKuOoUkkKUlpjMXxmJPqWeEHhOxXoxXCcBNnbvVwQHjJfFbBuKkaAZzAOgGoTtixXINzZnaXxwWUkKTtdycCYcCVvDvVhSzZnCAacaIiFgFrRfGNnkKcgGsSrRCcluULiIkKFfCIOoiIHGgDoOeKkETtPLDdXOoVvxLlfwWkCcKOoyYgGgnmMvVNIimjLlJMZzVwWrRvaKkAUVvuJgvVtThHqQGtTjBbmaAsZwWzSJjMyYTtkKkdDKlLbBNnTvgGVmkpdlLDJjPVZzvaAFOofmwoqtTQvVvOohZOmCcMmMoknuUZzNbbZzBUubVxXvZztTBqycCYeYYSRrsxhiIHXccCsSJnNpbBMmKuUWwkQMmkKqsRrSVvuUfzZJjdJjpRrdDWwWUuwYyJqQZzgmMGqiIQjBwZztTtTnNJjSsqQVnNGgjAePCBbRrcEeGgzHPpesSPPTtpHDdoOuUhSsHjNWwnJvbBfFvYPALlPpaWDxtTpPrSsWMmNnTWwmMtUooOOoCcvkKoOpoODdOWBbwomkKNyYnlLyuHhUYEeronNOiIRrRNnoOQmMqCfBbFymMnwWNFqQarRVMmQHhqDdJjPpmMBvVbRrWwiIvlLVxTtKEsZxswWSBbXzbDdzZRrexXCcsSxXEUuBkikdKkDPrCcRFfUXkVgHhGDaAnNfFSsxfApPkKqQXxayBYyHhrdDRbtzZCWwVvckkKSsebBEvqQVrRanNaPpAFsHHhwWrRTtTANnatKKPOwsSyYWiIBbXDdxWlyYPpkKlLLdAaPZzpLlDJjIiPWwAaUgLlCcGfFBfFbuTqQtAapKkSsHhUulXyYuUQqGlsSjXxJLgFtORroTaKDCmDdegGEdScZzyHhYCMmgGscgRyhtTHKHSfFMmlpPLAaKklmMjJbozkKZoOnvwWpPYydDCeyNZzZJjDdzDzLlZxXrRvVNnmMdqQZHhzLlndDbKkkKBtnNTsSCDSGgqZzuUMmRUurQbaMmAgGqjJfVvFwWQFEKkefKHhYyLZzodDaACcaIaALNnKkMmlGgNnhXxXHHhhGoLlOoudAGgaDjbBhHyYJhHLlVeMmdTtrajIiAaEeBNOonbJMgxXwWGgXxnNCcFfOBJjbrhHbBrRfaoOBsSYyIinNbABbFRQqhXxHoPppPgvGXxTmMrqQREyYeJrRjkdDGgkKrRKcCVvWQqwtSsFfgVfFsUunNTtUuDdxXSXkXxHhLldSsDKkKuBbWwUpPHaAlXqQFAafxKkdDXxLlrRNnLaEDdKoOVvkeSsPpMmAAaGBlCcLmMOobcMoSsmJjPyYiIpDjJdMLlLlCFfxXKkpPIicFbBuUdbpEeNnEefkKjJTtTtwmDOodPpnNlLtrRlzZsSUuLNndDdgGDZMmieEILxXlcCuxXDdGgiyYqIiIioOHEeYzyJvWibBaKcCNnkKkjfFJhHCAaTjJtjJPpckWsWqQwrRzZOnNoCoAaFfFiIOoJjBbZzIixXfoOHYKeEkQmlLGhHBbBbBOwWWzZzZWwbdYwWyvJAajCcbBlLdBcXxrRTtEeGgDdqQrRWLQJjqlIHRrUzZuhVEeIivEWwsvbBVMmIQqQpPLOqXDdPtxIiXTpxODdoKkaAOoLlKkVAayYZzkwTtWrRpkaAKsCcMlLfFFflLLiIXfFRrywWfFFfYCchrRLljJSnNsEeYiMkKGgghzpzHhvVFffGgFZCciIVvWvcCfFVrleEvMmVmSsMDcWwUavVAdDSsRWRruTtPpTjJtpPmKkeXxFfGlgGLvVgGaALlRrQGGggocCOlfFLqgvVhcCsWwXxSHGghcZzCHHhLzZlWgMmmMEeGdDAnNRrVvwnNGYygWgPekKEbSsVHtvVwZXxzSwQuUUYsNnsSSnMoOTWmzZBbMvVvVvCcVRrLGVqQtTJjYyRrzZvWwqurmMwWnNRrAoOhHIDdqGgxwcCWeEQqOLlqFfAavVQoXTQcZzCkKjJqvVvVGgtqQvVQizZEeoxqQfQqhHBoObFThwWbToOqoJhHjPpOFfFfQkZPpfPNnvHWoOLlZPppnOzvVPlLpMOomiIRraAhrNYmIiMptAatTUufFTLyYFfYylmMSMmsGWwDdFflTtLBbgPxXxXysShHiQJIijxXRBbqQKBbMLlbBRrhHpcCPPfFpquUmQJjGgcCZzqMmZEeuUzSsOoLqQPFXWPpPpwtTZYyUuzDdjJDdyYcCzyIGgXxpUuPGgEqQJbBqyYVHxXrRhRreQqEvevnUuZzbqyYoOtpPTQJMtTmsdDzZvVEeTtXxOVjrRJuOMmafFJUujAsSIZziJjtThXxFfXSeHhLlEUudDsxYyMmBqQhHFCirRxXSsvxXVPpRUuVYsrRYyzZTjHUuAaPoOtSBbsTQqKNazZHYyhRrAtRRXxxjJXTtHhDwDUudEnNZykKYQqzUuoOrYyxYywWTzEepPCccCkKZRrkTtKGeKxUPoOyBAagGBbOgGoKnNkNNDadJjNnDNcfFxnhUOouHjJfJjFnBbZzvVNrRCceEJTtlLKkpPlLktTKexTtXEtTjJFfxceEAaCvVThIZziuzToOAaXabqQBbCiEeIbBaMZoOqQzEemAJBxXGgbBDotTlUuLXCcvVEyYeEwfxXARrmMaFWeecCEOhJjkKhHHPcCHhpjuhQNUiIunqKkNeEnHUCcOHhouBfuUMmQqtoOjJTPpKRrktFXxBFfLGglMmbrRtKkNnDdcBuUWwDdlLqQEeZztTbNHhniICMpPAwWNUunaUuXxXxdDVZRhHrOohHzXxKaANMLlmnkkKCcyTkeEBOowWbbOgwxXIiZVGgtTvzEmMIiieEIsblMOomoOkhcCHiNnNCcIimMnyYvVAWgGFfpPwaGlLPpSsJQUuqsoCcOkrSsRqQZzBdFfDVvbfFHyYCRrbBctyYVvNRrnwWvVvKkULlUtkKTpPTtfFuEeatTGEeuUgAZzuVEesSCcBefFwWXxXxEpcCtnNgCSAasnNQTtquxJjXxXXFfQqlLtYypgKknNwWKMmmALHtGgThOjCNncxhrojiIGgqxOWmMwoXQJnNqNnQAsOoAUuatDWwdRrkKqQsWXxwhHgNnNzZnqQHhXxGasSAjJSsPsvtTVjJDqQwWdSxXSRraAsdbzvVZXxBDBbgGHeEAbBaLAjyYJkKapPEiIhLlcCuUNbNLlpvVPXxFfRrXxYJjzZuUysSgJjGAgoqQOTfnNUrRAaZzINniuZiaPpAYfNEePBbpXxkKPAvkKSqQspZiIUuVIivhHuUVjJMkKhFfFqQRrxdqlJjoqQVvaEyYKGxXgXxoeEWXaAxcCwVvpPnNsSOeEKpPrRknRrXbAZzaBbBxEeRuUbBOAaZlLiIzgGjJKuyYUDdkorbBPRlLQSkKseEfsSFIirRHxSsXQqbBhQqpzJjhHPpZGgnMmcCVvgGNtTolLsSOTIihvVFfXxDdHOKkoAahHXvVVvxToOWweEOotoxXWwwWBYtTybEenNtTQAQcCjJPwWbTLmMRSsJvVMAoOFfalLhPpqQWwQZsIiSBbvxSFfsKPRiInNGgqQPprpFaWwmMAamAaMIaAcyqFoOIRrkKIiiUUuufiguqQxUFfaArRMmhHLlzTPWwpoObBozZyvVYzUqKkbXxoOiIvbWZzVvPFfBbbQqBKhHflfFLFyCiIcGgQqlMUtTMjJZLlJSCvVYycsjUYyuOKOoQlLPGgymzSXcCYUudDKZzUuUulLQqbbBkKSsaPpYyAOowVvbpPkKbUOoNVNQzZHYyTtTSdDsSsTttTtWwhqcCDdEjJxTadDAtXkKeaBbLlAneJsSjkQqHhKrRkmMcQsSzZqCxAaXKkKEYyUIDHXxhxXbCcmMbSMmDdHeENnhxXEeoOLljtyYTagPpPiIrRCceEFfUurRjSsJXxBbkWwGPfLlFoiFfIOaAvVbBsSsiIdDqQGghHrRsSVvLwWGhHNOoUuYynlLlXfFzDtbBTJBbdDjhHKFBbUuRvtTygGFfJqwWsfFRWwrCcSsdsRyCccKkFfvPpVCHhPpuHhUZzQGoFWwfiyYtTIwWWwrEFfwsWwfGgFwyKkFPpwBbqfWwNCIYyKmMGgzaANXxnXzZeXxbBsSDdXxEPpMELlAaxXsgQqbBGiIXRrBbiwWIlgGSsYcCCcyLAagpPmCuUcMbBpjJuFktVNnvnNJjVviQqUeEukKIPpTBbkBNiyVvmMKGMGpPdDghlLHKQUuqdEgUTtuIiGwWzIIiiZfewpPWDdzZbBkKLWuYyUeEXnNgfFbowWZSEeehHszZKkSAIiaEoOWrIQeEqUuitTDdvVShLlTPpoaAOUxXutIiBbCclBbxXTtLLlENneNnSsbDkKjIiaAEetuUTJxEeKLlmMeKkEuCcUqQRrkWwBZzARrBUurRaoOAmMMbOXcGYygCxVfFaAvwHOoPvxXVSBbsNnnVvAaSsNqQDSjJMmooOKgGkAaWxtTabBUueEhHFQqvVnNkpPkKaAKKnpwWYTtyiMJnNbBjQqtisSEzAaZehMmfFHeEuHhWwmMUFJjInNvVjvVNzJjuUBmoOlHhdsqaQNnqAbwibBFjJfIzAaZDdyRubBWwcCzZLrbnNBwWjJsSJZzmAasSEOorRxXeKkEeyYAaOoOoUygmMBbsSzhHNnxZzXcCUuNnPmMpmOoTMmtOodDCcTYyuGzZgtvzZPrRpsKzcCRrxnNXRYyYyrHhZkXxJjfTfssSkKhHiIIiAxXojCceEJOSsnNlLcHhChHmaAPpiIoabnNBwNnNnvxXIpVvnNPpgGAaCYDdgGykIKzxXZrRNnvVcyYCNnDSGgstTDdBbkkqQKYyJvyYrhrPUukvVuUeyQMmcCqQALIFKUbBNxfeEFzhTtHfFWwuLfFcYybNCcnAZzaMYGgWwyGBRrTtbgGgRrtTKFfnnNKkNdVvvFwWbBSsffFnNVSgGHBbhsKcTNnxXtJJjIiJgGsSgFfGIinveEnNEeTtJhHjznHLlcCmMVvhlQqLHhfFSsMPpgVvGptcCFfyFfaAsndDJjNgaACcIiIApUuUuSQquUdDsaATtkhLpgmMwWVvkqQKSsOoKkcFfCsSRrXMmoOorJjlYyLdDeQYaNnAyWwqGgRrpPwkKtTWINnGbUxpPsYyBbSQEZzswRrMmWcuUbrqQRBqDdNPiWrRKYLleEQqyYRrDdMjzZfFJmxaXxsWWUfuwWfzlCCHhaFfujoMmOJooOOeEikKIsKkRYyOoZzEezZXxyYwdobBObBDGgWuVviIjBbVviJavVARsSdkKkrRcCBbyiIdDGgfmmMMFRrFfHhBelLRrloOQqhHZwWmMgGHiFfIhtTPPYKVvjJJjpTtnNaUuNnBbmMWqQzZmMRHhWwlLlZUucgdDGLllwWLIipjJPClzZSGgfFswWLtTkKzTgGtMmLWwVvGgNLlnaSvVuxXrAEewyZWwwLyYmMWwqTHhtQyYcCjwWKkJJjlBbXAaxbEeBjJrRWwxYbBJjcCFlulmMLkKULuUoXxOfeZWlMeCiJomMOJLlNnjcCQqjSsAqXxzaMmbBAZAarrRgWwrRLuUjWwYyJGRrtRrnnzZYEHlLHkCmMcIisSlipPnNbBKLpPlvVyYPpILluBbkrjEeUuJROclLwtaAYyFfwbBbBsbBSWoOzZyYkKEQqkOhZzGWwgsBblyYLqQSMmnCcNsCcArKkTSstsSmMTTtQaAAaBbJjqlLwWplnNsiAaIDQZVeErELuUMzUNnyYuFfZlpPDQSMSsZGSBcCoONnsbnHimfyYvvBNnmMbICcsNnkKnKkSBJqVeEIivQjUWwpPzmwpPWOEhMSseElqZeVqZzQveLlEEeFODCewWfIiwoLlOTlLRtFfWlLwQpPwWEeqxXBFfDyYdNKOogUdAaDEfUuzZjJUNnuFroHHvVwWiIhfFTOoGcCHMmXCcjrRJgmMvgbBQwWkKkKiIlLqQwWNnlIGgRrXxKkLoYyOlTtVBbSYyslrqiYvVqQCcyIEObBofFqQfFgGQpPqlSsLbbyGgaAaoOAPIEDdaAUuegeEzfnNZzSsyaAYLLXuUXxWJxXurqyVvYvFCcfFnLlBiIbzUuZzpPZEWrRwfVvtTWwqYvwWVyfQwWrRCcrRrRLIiiIzhHpPWwBwoWokKOVqpPOyYUuqifFJitTIrRYyPpeEgZzXxqAaQYLldDIhKknNHlFQTttFfHBuhHUjTgGtYyJPYypLdDUugGSiIbBpIiHhjJPYGgdZzDTbdDlLSaAsBtXERrmnGgNTlKkLHJjhprRPtMsOIUuQqTiJpPjZzFREZwAaSWAaZtTIinGUIiXaAmMNdUQqcdDSnOSsIlLNJjaAsSrRDdQqEeLgGvVDdiWwWTfYyFGXxgacCaATwWwWBbtDmMaKIizZGgrRZzDdnNqvVHhRMmUDSsUuaDYeWwEJYyKkKkjXxSRrsXxjJsOGgZJjhyYIigGiIjJOoKkVvVrCcpPUuRSwSxXsWoSXMmwWmMiKpNvMNnLlCcHuXoOVvnWUuLlwVwaABbWuUoOygOoTtGawWDdAoDdpPQqJjnNOYbBZzBbbBvNxXcnMmoOJjhqQaaSfFtTpIilhjcCJxQqXHUSsuvVaAtsSPpLlGgLdPpnyYTpsEeSnNkFCcKIigHhOoJjDdGEegGkmfFMcCCcLhHfFNnSqbBdDQsSvNFfnFOoSZzAiwWlLuXxQqUIqQYySKkwrRSicCIXhHXhHovBMmQgGoqQpaAcneEwrZzRhHwSOCmNoQVvPsScCrRsScwuUWfFCXrfFcXxQLTtlyYFGgtxXTTNeMmIiYFZRnNrzpYnVkKyYJCcjhdDEeqdDCczZabRoXxOeJjrKkStPpTWCcewWGgSwWDtuUXxkkWBbwnNKKZieEoRrOhuUaAGgrTiOMmXxoRrNPpdDnNiWwRrEDduHhbBqmWwnTtEeqQwWsDdMmAarjYySsPGgDMmXeEfumMKvVkcTdDlLuUGgpAoOKztTmMyrRlLYFjsBMlVvLFfHNMmnhgpXAIUunNCcuUUogUuQIiZSszNHhrRVQqvdDiNnzZDZXxHjJkNTPpHxbMPtmEeSsbSsBoOCcnVuCqQbEenPGgiiIIKjJHSlLsmrTtRMhOwiFfIWcsIixXBESeEsUuahcfFpUuKcCCcCcSvSqQmKkMsEYcCyqQeqUsSuPLlpiGgZwWJmMtNnTKkKkQqzZGgjvvVVyYeEBJLleBbEgGfFMmMYtTyoOuuUBbUYlLbVZcbNvVaFGpPgKkKkOYyXfGgFCvIDdiVWBvOoeEnNlTtIHCcerREYyXWwDEeAaeiLlPbiXxInNpfFaAPEeWOosSwDxFpohPkBbKhmuUJsSEezZkVbByjfFfHwukAaKvIUuKkiOCcoeakziIDBqQgGrQStTCcJjknNhHipmMYeEFyGgLfvXyYHhloGgOAfFxXdDYyMmSsSxGgReEcCeEedDAaEIVvLlqQipPPQTtcqQZzyatKNnsywLnNlhZoaaAtTzlLZoNnJjOiIZzuUfdDFguHJQcCYyJjqkqQXReErxzFBbwTtWRDdGuMHhmLFflrRIiJjrqQnFLljaArgcVvDOodmVvJjkBzoORrKKkkZbiIKpEerRngnaANvqQVrplRrCUJjmMEeiXxrbMmdDxXHhKkrROoTthUuHZUueTtWKkIiwnNblkKlLLjkxXvwWqYwTPQqEendcCZQqznjUuJNnsuLlUSSwWzZpjbBUdDEeGgrUuDdirRFqQZzNYynzokKOZiHhRrIfyKoLlxrfTlhwWHLFWpeGGggErZzRrRbBoOcCPdDwWpeEsjsKJjNSsLmMlgectTBbWRrWwwfFepPCcMmbvYwWyVRrBECTfFhHUtnNqckaGESswHhWnNeyQqJBbZzBIiBmdtsaumRggGGroOeEJjxXVCcbITtiaAmMBwWsSlmUUJjvQqxrNKkxhHGgPCNntcCTFfJOflsXhHdyYdDPpsSsqQIepcCXxjSLlsSBbNnsHuKkrbacCAmhHMbOJhgGHZztfMmtQAjjJJrRBbsSaqSsTDsSqyYJjVEevQPpqQTtDdDdZoOAaJQpbBbiHhDdzZiHrRZzKHOesSEobBjJcCfFtTEfDdFlLxbgGDdtTwUgGLozZOvVEecdBbkKZzrtXxtrRpPThXciBbtTTNflYyJvVjXxPPppinNAaKLfZwWzOovVuRhgGGayYAgZzHBbDMvVlLnWwbSsBxXTtNXUuwWDdBFiIBUzcCGgnWwNclxXMAamfLlbhHhHpPjZzZlijWBiDpPstTSDdrLlJHhkeYISsiteDdiIlWXLJsSzXxJZzbBRrxBvEBevVnTteCcjumMiwdDWbrRFcRXxegbBjOuUSZMYyUuljUudyYXxyMtTeEmQpSrhHCsmMHknFBbzLlWtEfFezZdDAgcCfTZzjyYOMmTtecCCGLlBbglbNDdnGCaAcnNhNcVxXTyYFfAambOSzZskKpPyYQqVvfXeExAaZNfDiIMmdubqQlPpLEyfFYJQqFPWTzZgBbGsPkrgBbIjJMmddDDleMOwWooZzYyZzepPJKkjaAcCNswWVvfFxoOXsSFSIisHhqQxbgGqNRrvoOtszZeEYyiTtzZIxBdNnSpPsOPpVeEAhHaASsXtTeEBMmkKKkaAmpPENMmdDfFneTPptdTtFfHhTaOFKFfUNdVoOWwGIiUGiIRvQrRqGgEpDAamMdvSdcSsWSsLlTTdYkKyReMiIzpxoVWwjJvlLkLlzZEeuKYPpykrRcCrCcWUARrVvlLNcArRAptUumGFPCcpJjutTUMmwDcqQCCHhBhHbqUhJjYyYyACZzZwAaWYanNAtTyosGgOBEpeuuaJjlAaLAtPpFlLLlQkwWKqZDdusercyZoBdKMRrzZVYyfvVAZtAIGQwVvFlLfAyYqQpPqePpIrRbmMBsSopgGcCXDzVeMmNzZoOnEQlOdqQpPDbBWwYylkKLpUwTtWuPZDLBhXTKTtktSWbKamYWwOWZznNrJMUJoOjuuUaAHjJLCclhHtevcCaHAauCzkdZzDPHBvVDEeHHhgGhjnNcUfgTEGPBbVPpfFGgMDAatIiTdEeENOoawWAdEuoOvGmMgSdXDHdNPpPpnNZzVXKkxxXHhLqtLhoOnNmMzZoOenQqbBHhQuUuzZaAUecCDQqdxXxlLNnVzvVPcCFdvHhhuceEsVQqqlLeEmlfDdFvVFXTzZWwRmOCcoMYyXjJxqQINniUdhgpPAztTfFapPfhhOoyeEYhHUUuhnNgVpPIiKkAnNLlalLGgWwkyfxtqQFfTPuARwTXxlLtRrWFfFfmMOmZzMoPmdDCPVPpvSspBPpSsrRaADmHRRrvVroaaANnADdqNwWDhpOogiEQIiSsCFfsWQaAfrWwRyYntXGgxirZmWVUuTtPpRgECceaABUuOovdDVZwuUkKtNnTcCjUVIihILOoJjUiKkJcjLlYTtyJxaQPpqrIiRAswMVvmJJOoauRSsgXvyVBbBMEQwWlPatHYgLloOlnNLjtsStTTsGgUutgXdDJjxWwWwZsSbBvDJvpPVoOHvKkvMwmMBbroiKkEsPpVtTXDdRrRtqaZbBzAbBQEFSaoOAapbQqyWwYBPCzniqPpQjJmMGhXxiIKkiCcNOonIehHYyjTZUOSsHFfJSccdoODqlLiKktNgGlLnyGtQqzgDfFCcXKmkKkiajJAwKlpPLkpAfFnoONWwUuLQbBqlCcLKThHOowWQcCqhIiHHBlzZQqWXxPpQnNqCiIitTvVLcHhgGenNcCdDbMmQqJTHwWhceEGgqQcKcCmMDgHeEhpZuUzvVPGcCcCpPwLlqFyAQLlNnfjcCJFOlLdDkKdIiHiwdDrRroOReEqUTtcQqIpzZPgGgnHQqhZZBxXXvMtRrTEdDUAaADtTqAGgVQqcCqNnQSAvzjGlOoLBnFfgYyojJxGgXOGMCNncgSAXxaRPYyprERbZMcmCvVnxNnCcaBbATtHPneaAlTtlLRrkijzjDkTPxvVtZNccCCpPmTzZtMkKvQgGXxqVfdIYyBmZpzZcCZzoRrqjOoLQmyTkKgaAWPDdnNPlLpiIpwIxXNbBnHDHYhfFeEebsScCBeKLUVNZgPnNhvyYwmMiHhuUjJLXvVAAadfFmMqLJttEebNpPjJQVvqQMdDvVdDGgmrxoOqQXjkKNnmRruqSsQrRAVlLuUuPpsSYyNmMASVHdivQqJaeEAjVTUjJfFnNadMmUuhxXldDGvoziIJYHYyOomMgGgrJNngGjRgqQdDGdDjMZzmhHpPIrRLljJwWHhXXkEFfPyKkMxXWwVvwWLltTqyYGPpWuBbyeEGMmwWdiIIWeIiEwiGtTggahhqOolGgLiafNYBtMOBbjzZJhjLJFouUwWOCcjFfJnTWKkFJQTmuViIwWPbmPUupxXMRaAYBbuUmbwWBgQqchHxXCoOGVYzaQbBZxXMJuUdDdVvrTtXxzFIiqjJmyFfYeEMzoMsSiRrzxgOlkTtKCngGgGRrizjHhVYyyLbBKgWEQdgGrRDMmTwpPQBYHhkgGhHGgKybjJqLlWtJcCjqjAtauNTtAAAwEIiIiescNqMxqQXmxXIiTILfKkFgeMmXxUuxykajluULCckKXnAEMYjPxpPBIiDdhIDkKtTdiXuUNOonWBbfMmKyCKkWwWBbqfFTAGdyYCcDxXgJVqvVQXsMmRBblYyLUynJjxXNkXxUkKuKoaAOKkRfJtVNnXxvYygGJjvxXGguNoqAakkvqQaArVxlrpOfFbhiucUuCNnXicCIeEmvVRYhHZeKNenNprRGoOgfFPDdqQEOHhpqQPpPfFCcWwYyDdoeNEMmJGgnPFfxSzZSseEKkCamdDeELlhZzHFrTFfYpPydRgnNnNGmqlLkKmuUcGrJyxXYjPpRBjGgKkvVueEUJbVvDdmXxFfdbCBiptTmhnNRqQvGNnHhFzZFyQQDqrRKXbXqQxWwDFfzBAaANnWvUkKtTuVwlbWwBozRGrlHXOodFfFVwMmOGyjfvVqQtTFJIwkwvVWidDINndCczVYcCdIiDtnVvNgjJZzoZEeXpqQfFXYXxyWwvVxPiIDQXxpPqpPXnNJcCjRrpqQPzrRrMKkwjJxFfSRxzZXOVMQlLVvHhFfofTWwdDQqmMWwNMmnJjMwMsSCcmdmrRSizZBfFnIilLdrRaAhtvVtCUbmTtMGSsgFfJtTuURrDfTmWyiILTxEerRXhHYyTRrtyOoVfQWcWwCwuJjUqnNnxprjSsjQqJLlzyYTdDqfFYCcybHhgGlLfilLIPzZDdiWcCPiTbpoWhGvRItnVvNgOSsyDIaAjJURrUrRuEIiAuCBbNhHsSnzyAXxdDQrPWwpKkVRrBbvaAUuPpxzZdjJbBUMXxTLnFfZIAaisnqObBlzTFfCBcdEeMmCOlKkiFOooObBJBbNnjRvVgxXnPpvViZzSsINdDWiIHlEeJHlLhTBNicKkPpBkgIyhVvHiIYmEeIIiiBBmBbUXBbxKMZOVRwwTtWzYyqvzZzeNDdyYCcTRrtOorgGRWwTtnUuNBbkyYyXiIxuUYUIGgMmpRkwWVCthHDjsSRMUuosSHQwuUcZGCchAwWaGgKbHOvVoneBbaAhQqTtHyfpPhoGUuOcCeExJVrnNZYyzsSdfoOhCcnTtBbjJNQdDWVrRvRrtToOcLQqlsEeGvVgaAfJjEvVbWfOoutTVnqjPRrpbcCTHhPjibBUQRrfVUtTKkSjWwJLTtZzfdDIhHrPpRnwqQUucYWlLJwIieERvXAKGqOozcEexNngxZzGholNnCbVCccCGBbEhHeaGVcxXCHhHXhHxnNxvykGgpjJPKYVgRrmGsjKkuMkKmasxdfFDGgXJjqQRJIinNSNgXpyYypPHhYBkpPTNnGgyykJjpPlpplHhJjLZzkjJXuPpviIgGYRaArHQqOolIfFljJjFTQqCcjsSwWJtDdGXZzxEpkKwgGbMDdiIALlLIQqYyVVvxfDdPZzGPpxcNnCWinvoOhiuNnLlOomGgRrDdqQBqQxWsSrXZzxTVvkazsnVbyYHwUXxufXrjaAALlYyYycCEeaJHeEwzQaizZTluUBqQbQsSKkhpwQqVdraHhoOvvIiHhwEKItTiVvqQzfFjdiczUBbVGQkfiIuDdUTTSDVuzwWZwutQFpPNBIiFjCcnNXgRzEqWbTWwUoOQqgCjJNOoGgRHGcCdDgnjRrSADdvuUVtnsXxYZJDMGgLfFTdDbPLIWrpPbBEpnNgwGTDYVviBKepPVBpOoKskKChLxzviSszhzWvdYyhYyiIiEecwqoMWwonHhNeyYXOozTtMTtlQgMuoOQqWJdmxXiDLlJNnjIiOoIAuXPPpeTaYyADdmutTiCcIfFbqisSIRrPpRwFSSKkCNncsNJjJUuzZjbBNyPpPBbpqaAuFlLsCzZLlcwWUMTtFfmYybMmdLNnRrkKeEcCjQxovJUvVLyYsLKuSoOsYyFFfFXXKkFfzZfFgaAcxLlKkBxmWwWRrGgwGPFzdPaoHbBlLhnVtTvNSLlTcxwWngGeENWFfhHHsjqQpyYOoZxeTyIiYtnvXHKGSYSsKpPXxkyehHAaCzFfdDaKFSkohkKTSTtJEeWqQwqGWUnlFfcCAarJDdjyYVvWPpCSsOCcvtTVPRspPlCcrgKEwWyCxXSscJoOHhjluUUuQVmHdIkzpPtiQVvqzZzYyzPHhjgRmIRgwlLWNneTtEqkKClFfxeNlfFeDMmxXRQjzCsMmqJjCcaGSlLYTtBbVkEekKojTiSfNHhTtnKgJZzKBbmXUuHhdEeuqQdDdDYyHWQWxLdcEXkkJjQwWefRrFAKQxtIiTXiIqmqQMkaEqBFBPpeVvYmqQiIMyYuUVhEeJdDnNndSXXxxgwWoOvzxXUuxxXIudYgGyDGDUnNMmsSbBxXCRZzrZzmMMDPUuwHviUnNyXxYFHHhVvYywWGEcCTXxOpPoRUedgDsSdGZyeqeizZIRKDdVvBGHJdijJDxNniIcIiCWQNnSUoOrGgXOlPpdONnYpeEPbTGnCuUOHhLNnDtGenNMNFfVvWJJjxTtkKOzFfXApzOEjtfFhHTWLIAXPpDdDdnNPDFHhfdoOKZHhoQtTnRrDlLZuBDkKAJlhHnropvVhHlXVvVvIdDAuUxQDiIdNJjnBbfFGxDsvYydDlyYTtBbcCjfFmQVvqTtgXxGYSvVxRjiIJezYBuWmMevBjcCcjHKkfdwqYyQWxDywQqHLsSloOFQqdCEtTdDeKOxibLjJdDkxpPTzZtMmoWXMmKkcsHoLNbDdkKnNcCjFcdYTkVEcCEeshHtTEdAahHPpBeCcEmsWqhHPFfBSBbssnNRtTNtThuiFfqTlLtoQvVipPIMmGgpPEeLLIHKkcAaCjJBZzbfkJpPkjJwWvdDLlVYEumKLlXxkMgsHHhhSGUgGgGgVvbfVrRBbxmMjVSXxVnNvAAaMXiIxhHHhSHEehgGcRrhHozZHfYCrRXqhzZoOvYdDyVdDbbjJBZsLsXoalLAeEUikRNFfTthLlQDdqTAaeEHhQWSTtbBswWwqzZNKjHVLloDdDdmWelzEevVEVveKkZLLlBbPplFhHxoOTtzjKknyGucihwftwYylCrRPpcLwXxWFfWwwdDzCZzvledDlLWwAatKkTyuUwcRgCJHxXaAhZDdzEfpdPanNUutTApzUoOKkuZJMsVKQWGGgRdXxJjUjJsSWDdxavVAOIiuiIYyZBbelvVLEzUNMXxXxWMgGmbbsSqxPpVvTFhbvVeWwEyYhHBHjVvJGcCkpNdhrRHDwpPVmdUuTLMzCCcwgbBGmDDxvGYIDdohlmxTiGuxXQqpPvtTcCJHhwWjVoOvMcCZSnNjJdDjBbBkxwZuNSsSFLncYpNnPgGWLVvnXEAMGggGFJjsSOMGwVvqFfzAayYSsDbBdhHaADjGlLZvYbuUBmeAOCcbFfqQBNZzeOoEPypPrlLcwjfCSugGCcirRcvVFTtSJiQqIpkdSnRrKbAnuUscPpCYyNaAoPIpuCchIaACOoJbpQzZDWEeFhyoSxWwWfgGFuVxPKvVReEdsFdbFxXFXKkxAaTtZzwWyrfFzSsHcCYGgyPphxpPXZRYxXhwWHsZzChHcAaWUuwnhrGDtTdgQirjJbvVvljJAvVeEawVHhtbhKPpRrktTQkKEeWwqAaboUBldDXImgGqGgQTyapRrtnvVNrTJjsSlLtjJdxRWwGCwWMzaLWJjJDMANrcaPpAVLlpjnNqQEfMmLWwVSzZTtPpBmMzDbBdZWRrjCcrRWwtfQwYyWwZBYyoOPpReErYMmilcEeABbZzsSmqQfXCcWwJeviztvwFtnNbIiBbBaAtTxtTVEaZzgGllvGvVgMmlLkKznWwNnxdIiiJjUuRrfYyUNwWwHvNneMaAFfbUuaNtNnfbOoMItyYMmMPWoOwiLlvwWoDdbvVIybBfIiFQOIiYyddHlsCYOoGHYyAahFtTRrEjmgGDpntNnTrxHhiVRJffUyXgNnGlLqwWxqQfkKhHJVWwSQqnvVVvYnucCCFDqJDgGqXxUQqNnuQdSCcZzsPJjAUuFoIvrRVZhLlMmVdDYDdKOokOoSlWwLgvssSFLlzZMqXxQKkarYyJjsFfSWwCRrhHjJmMwuSqwrMeWwEmSIBbuUAacvpPxXHhgJjMlLPHHYRuyywcnxjJbBGmMwWIdyfwikteOSMmIrkKCnsUuUupBbPgcCGEIYmzaAJMmHXdMmhbpPuUBfkKrraAJWBoYUNnJhHzZfJpdcCJCVpVFPoSsLlcYyphDdHrGtfNntrRiITszZXxUNOHUMCRYysyYSvXdUuAajJQbBEeqzxlQqjHZzhXtglIXSaANnNkKuNnUuUNSswaAbBWjJkIXCbhWYyUugqKsSYyPPXxvVfFtxwvVzqsSvHhoOwXxMTtpQhHqqjrRJwyYKXFqeSsBbryTtQqhsSfQlLDiIaAxzCcrqdBjJSQRDuUdmCGgcuVMVJAQqRrZzmMaBbzVoOqNnGgrYKkPWbroJjGgFVteEjJFfuVbSsXFNnvIiFfSLVvayYdDSyQqYsGiRrNmZUDwmMGgFfKoORyPiMIycwNSUWwjayYCcJjIiCcAaWwgKaAkTcrRCPhjlsSLkKnafQqBmMUuoRHhgXFfhHEuoDAjJQzBuMeIiqQFwEZwWoCAdDrRvgsSflLFGGQqgGBbgKsYyJjsqUuekHsSPlmMLMrmIPBbpjaAqMsCcSVMmljkbQqnLSsajFfJSIidUNnkgcpTDdCcBoOJhZyGSVvPYqMiKOhHhHwGoAajhNuUnhzvVZxXHwPpWZzgGHYVvHECuUVvcMlbPUAKMWZiIuNhHDyYIidUuRHhHRrhrnZmMgBbAbOEnNVvLUNAFfLlYyHXmzZrcCDdvVyVvhiIHSrRmNnsSYGZzuAgSsHEtQfFjJqLlTUukKkDdKednMJZYRRhMZzmdDjUuUuJJjRrjiIaYuYyUvVfHyYIihAaUoQwGeKTbQqBLyLYyGEmNnLAopPlTbBbBtOozKkjJegzGgfMmccjJIhHijYybcCIZNnmAaHhnzZyPcCuXxLFflrxzZqRrQXCnAQMmLTAatlnNlgAozSICRhAupwCccCMrRfFWwIvZJjvmMWwVzxXKlLkZzHtrBbTtGgRQqTvPpYyAkKFfHhfHEQqEeekAbBGHefFkgkRiIDNRPpwWrFfRfkuxXUoOjqYLlMkfFKyYuTtvBaAMTBHISsiVvyoOfrABpxhmgLzyHAdSsDdPDVzZWQqRfgnNQVgGgGOaApSFjEezZsSPpUdDGghHntTbBkKNzYDdkppPKkniIUuaPpMHMVvlZljJrRmmlddRrBbsSNuYkkmfmFfjTzVzHhZcCUHnIixXNuiNnzYyzInSYhTZzJAaqQDdxHpXxLlMnNazZawdCSsSPeKpPCoptQqmvFzZtGgnNpRcPxBkKsSqHJsdqHWwhOozUQKkMSkgJIjJlFfLoOijJaAlfZYCcrFqQMmfRmbnNZUwtqQrRAalaqbaAoAaljgGJgyYGXbTtpPFDqrDKNnPHhFVvfIiHzZkKeGKkxInHhfFBLmrUABuyYqIHhpPENHArRfkltTWwLqohJXNeSYslLmQvVGfFIiJNxRuTxXTtgIEsxyYLsgGSlzOoVsqxADdaXQSoOsSFWXxlQvnNVJOogjJjJsWwSbcCBnfcOAarOohWwUSwnBJyYAazDwMmrRgqANyFfSgGpcCqQLQDTtwuQqUxKzZpgGtOeCGgcvVhliILMaAMWwmNnmlLTaAdDPpPIiwWymMRybhRZhHINniQGWibBekNnkqQtTKEwSsWnxXhzlLpPYUgGlkKHfEsNKruUsSRzZeVvepRrGKaJbyiXoOxTGxcCYtAaHhvolVttTGgbBleyYEHcChRHhtGgBKPpnNFRSBbSIZBmXqQRrXDUuNmTtyJXjJODVpPzoONnZvnSkVoTtaJjAaHCKkcOokKtapxXPpPJjAiNnrRUuiNbBZzpPiSVEaAueEUBEiIXynhHNFfFVvQqGSEPpQcsSbCcwWRvVrVLlOGIigofkpPeGNuFXxizZQhsSdNkHhKnRzZkKWwiIRrdUuYJJtTjVDUQHkhwWeknJjLsSfrRaApPkzxXckKRjuwRNnQqcCCskoAaOsPYhQJjqBXVvMbBYnLqrIjJRToOtnNXxrRoBbBEebvViIuUhVJjzZrRvefFbkKLFyEeYbTOosaASGFfuSsSEeHZJvxXeHhabnTtftzZpPTywnKefjEDqXAKkdBFctRGlLtUJWoOZzrMABxXbaSbBsUOoutdXsXnrDVvEtMmrZBbmgvVGleZAmAaAadqQEEeNLQqDekZIiOozZzIZzOVvmMaXpLloOZzyYwWSpLJVvjBbwVmgGMWwCmrGkYyKiWQqwBOsLlSifibvmMPMmRGyGYesSEzOcEeVwxXBohHZzAKwWngGQdDEePtTnOdTSFlBbLfutRrZzzZUTtCBbNoxXFHqQOomFfCHTOGFuFWCNVfBdrnNRDbcFlagmMkKRrjJLCxuUCDkBbQLzgDtSDfFTpPtfFrLEelGeLJjDVSwDdiPHKkPhHiIpjZyvxelGrrRBbeBKkMpbdDgonNzvVmtncUPglITxtFcVRKkQolLEmMrMmyBLgIwZeEeESrWlfdzKCcTzZeEtYtTozZXHeqUHeVmUNnxXhsBbSfMBuqwfoYyUWhHSxqVKPpbWcCPYCcrWkKJytsSDUuJGoPplLKkoVvkKdDIOWGlLoXysPDdpTRruHvVFOlLmhkTiRoyqeArhzZYMjocyYTnNOzZcKTtvCAhHFoCcOZzfbsSZxPfFeiIEeUuIHPvnNXnbRcCxaZwDcngSMfSDtNkhHKnxtlINnGVLHtkIJaIKPPpnLkoAOFypHlIabJBMnNmUppgGPsLDyYsRXxgWwGdnkIiRRkKXWgGwacCZyYZcCGFfLUYMZQqhfFpPLnixpPEcXxjJUujJPdDKMmmMkvXYGqbBDHxXmMaAYayPpVvZzHhknNKWZrDIgVvOcCDdwWKjRrtFfYhHKQxXeEsQHVvLqQdRjwgTttIgobSJPqQcZzXIizeEMAJVPpvJQhKkXhHxNjDdJgGFfHAahIkKaoiJtTEzZtWUUuuDcoJjiLZyYhKzVeTBYyOBKzyDdYZeEnroqqCRHhrfBbwHtHxXKkjyXrRRhYHhfEeiANSvpDSEcgTtosxXIDdidyYeEDSUGPpDLOoAUEeXKyoOjJYJzZWBrdUuDMmFvNnUuLBgiIyjJjDogCZiIYXRQYmMUPqrmQCdkoTtUwgwWXcNnCnSsBIAKLoYyOQZGgzrRGuRrpfwApmQHReErlPNWwBOgMmauXxUOYylYaqyYGQEeCACLxXKkTArbpuCAahHktTJlJzNiInKkjZzSACcCsQpVpSXsOXiFZJkyiIKkZNlcCRKkDaRNysIiSKkYynYyEevsSWwCCcSuaAYtGdREerDgrFpFiICnTQYYSxnlJjdwWHhQMmqTchNzZnrkaArQqVvRjEACGiInhvfldDAwWXQqHfetTEGeRrEstDvgEqiAaGxsSODPJjHhpGgoBKeMmabhTzZkKgGLYypIibUXrfcsaAOonPpSGzZboUuOrRdDaGgAFfFfrRJTUutRPlLAOsSdgBbGiJUgoOiIDkKIibMmRrJjiKixXIkKIiIibUuBcUuWwAAaoQqFfgtFAiAGcCrDdnNXxbeixPpXYAVdDCFfcvmnNuTMmpRPphZLltRacvgLNEvwWDxwSoOXxHhsRdyHVvvabBXKiwmSydmSsSAagqOrWwRxXVvcgktiItTTENnaVngpPqOqriYQRjDlLdJFOfIiRjJKkysvbBwfFcChpAakKkKINnFfNoqFBMvVPprRVBHHcUaAuntlLqjEUjmMJYxDIiPkVNCcGPGWfzZVmFfiITAatPjdDuPZlLzlxHEpVXxblaKnNqINGXkdWwDKcCrDzzceeXLlKjhQqcCZXoOYXxlLDddDkSsjJjeEYSYhrRruUCVajJkIvVzJByCcDENnRrRfFsSVvonNOoYYylqlJoMdDWwHUusSLrJjnVBbvmyUcjRhXgNcnNCqQzZUujJKwbgMeOfoOyGQzEefkAxXkwhPCeNprkqQsXMdbBElqUuEIbBYXqiILfFveqpPSGPzZlLpgDdgzZGUkwWATDdsKkSTYytrRwYyyYToqQIYQgeOcsSGDuXTMmKEenTeayhmMWoaAsSIPpiOGMZBpWwiiUmnumLVgLliHPpSMuUsJjXxRnSudYyDbBrvWnvJtttlLWSahHAspPkCnNcesRrlkoSsdDYWTXwoZzOZyYyxHIYpPyirRisSCRrcKXUzFisXwpXoOgGxqTeBbMxuUzHHllwWYTpcBylJjtkKuUUgGvczAdKkODDBbdodhIHhiHdMbemRcBbigqQwLKbLlBtBbTEoHeEcrVBzLIVwWRgpNPrHSfFqTiPjKkJMDdPhzLlZAaMIieECJjDdcichdfqFSjJZzKQCBqhHQyLByYTYyjAxXKGqfFeEcCQgfFkqqSvVGMmyYSRrKHEehkIcrRCYoEKygwkqnNQnfVVEVvptOBgrIqmroORMJlueEUIWwSZzCWwpiFgGSsdQMmaXEXxYMmysbBdiuKkDwWBKaHgiNdDtTMosFfSCkKvpsFHWyFbBGiIEmMDfSbBsZmzTCGJGjHjzjbsreFfMmPHvVPolLVDrDzypvVjeEXIgGiNnJoTbRrMwWNcjONnLloaAJGrrRRdzRfngxwWYfFmMMhEeWFlLUwHhxgEnzoGqRNgUupmJcEeUWCgOnSMbBmsNHtjNntTCsSrsSAXxaYyvsSWeKBbGgiRlLYyHdPEktnNpPcnkEaHSsPcFDGIhHoOLyYEexYiIyIXxCpIBbgGNUkcIFcCbeEBkYhBmEzZEFfdvOASnkrSsQxjJDoQiySNnsRTtrYIqOddIiuUpOXDGggGhHUsSuXyLIvVXQsAriIkaAeEQoObbnOWFfwoVSBiGfkKFgSrRtbCcwWxaCDxFhHmWfYwBbWdfUchFoKkOnNfHmLtcsrRDVNIhHuwVunIiNSrrRmMOoasSxpFLlRlFTyAjJIQXOwqZzQWRLnyYDdxxXzWwcBmMEVSsWQqTtkKkIasqQStbCDTwnEeNFfUOOTtoSfFfWwRmgwPpWGMrFgGsoTtutTgGtXxTWTttBbdcBTAiKenNEwvebCZXeENljJtgGTroEQqexqQqiCcaYkkKKtfmMLrQqDdfPFfXQqARsuFfFfUUvWrRUKFfkgGinvdSCCcOoTtTlMCuFDyFwMfXdcANnXSsxXTtBTsJjIWwbsvNZzBaABzZqKRaGgSqxDdilYLlxduUxoPeEDJjJjXlrRjJLlLqRSIisKNTtsaUuoVoRalLArODRrevVeMRrqDdQbHlOoTtLyKkKfiCKuniPSsciXyvVyYYligdfGLkHVvhKlKkgCEsSephAeKNCTKEeepDhMmrIkEwVRcJrRLpPORThQTtqHFftgGrSsAaolTWwhlBbZzLomMGcwWwuZvVpPzCjMPGnLlrQfdDKkQMwWwWmgwWcCGMwabBAWmdDvVoOcwYyBWCqFTtbBlLwWgOZsZzSNJjeGXxXoOWulLfwEeHmyXEeGNFrZDgQqCZznmEeBcCoOtnNOjpPKkxDdJnNTyYtPYtTZdgGRYydhHvlLOGgpaAmMhpmMEdDRSBJZJhJhHgjkKLlTtgctpPZMzFdnNUSsuQZzqeHhNnVvSXxsgfYrRwhfSPVcOmnIJjGhAkrRbQKkqdUIDbBuUSoOAaexAULleEuqtTDfhHoOIPcGgNnsiRrgGLjQiRGboTPevvFNKQwWqWGWwYkeOyisgiAaIsQQmMaJYNnlLytPpblYUubLlcqkxXsfQFDHCIyHhYmiIpPHpvVmpZzItQsnHhYyNhRpMmnUuPGkpPKaANnaArFCcfvilZbyYvXxRChOiGgJjIeTtklWGICrMEZzBmDPpDOzExXVveYyZdpPfFrRoKkDaZCVuTWwjJbBLHhYqjJQPpbCPtyLLhhZNnXmEROortQPZzWxSIfZuxnNHhkIhXYzMmWxtwyOKLSxXEIimMjzrRZJKwToOTTjoOVNbBwVRgGwWUsjJSsNrWnNwJjSmsOohwWVvRrIGvlMUNMuIIPWwbzlLmgOoqQlLwWwjBZzbJIinijJKXxkIiSsINHYAnNEtNKkkiItxUdgRrkKCoEGqyiOtWtaKuuUsQExXVlzZQHhdtTJjKkDxyieoOUjJuQLeDUumxYySKHhRiIPnEcpHWKvVaKFZqgYFoEmGBWkmMzZxXnGsSxHrJCufFYMNnNRlhmOjLPpjJQLyOQqHhgGIiredYbjlLZiKAvcRHysyRrQqpPfFJKyCcxMmzXxvVHJkxEWwEtoOTCZFfZYydRxgniQkALwWBvPenNSxXshXLpUHclLChJpMvFwSsnNgpgnaANnlLvcWjJjJwtTCvVKpaAGgbBPpdXycCueJQUwWuTNChhbvoOZnNXxiwWIIibBzmbNnfmMtTQOniPWwHiIWVSYrFofrqyjJIjJRQoQTtOopZzPOoGNRrvAeSsKGCIioQGspiNnIWwPMUuDYKksMWIkxAVEWFfwYyKeEkehYDruUWXdVenUBDdeEbjJulxXrRGVCArTzHrPtUMayIEBuUSsqQfFRgaIafTGRrOaCTwXxWtkNnIBdGujIDBbWwoaprNgjnNJzZGnTtjONnoixXIXxlLBrRxUuJjeEDdXgsNAaSCYyWwFRxqQuBoOjJGGggPqQlxXKktHGSsRrgBAMNnmEDdkbBbOTtdoXgJlLjaAIQeGZzVdkKRzZrTSgTtQqFhxadDPpLFnNVHNgcaeJKTtRQWwqsSHCIitDLNXsyyjJqtNGgdDcfPUufMmPpRCcqQTyUsCcfFqQoFfOqQUuYycViINYnrAzZLldrLnzyYLllLYKjzfAvVaIJjxoSxsrRPVpPvvPqScaAasJZjLjKxXcUMmPBRatyYcClcaHhcbBqgQAyLpPoKkNBbnAGobnpLCchqMPaWFrRPUgquUELlelkaibNxGWuOKDcqMRQpuUuytTqrxyzcGOdJYGblQqVfRbCcJFfjwjYyyYkxualdPpguOTtgGlLGCcCesdPVnNshHnaIMYymFyHrxYoOJzZhThWdDFaAcQQORNkbouUbtEvZkHzlIOEeCdwTejaAIOAimMbBnHqjjamZxaAOJjoAaCnNypvVPYpjmMUusBOkKGiTGWJwWrzZDqdDQlhqSxwWXyYIiqhHhyYHtTyeEkKYkvVygGzcCZTJkpPQqoVdDvfFGidRzwYAyxXhHZzhjJdQgytTxVpJjCeXIFfNlRrHzmyuLllcCgzzAxrjJrKNDyBbYIUqQqQCcrRuiQqrSdlSHhPubjBAiLhPyYYfoaOKpPlNpSsAakiAjiPpNnKTxAaqQDdXhlvgiLTXTdslLFmsGfFNCwTtMTtbyENnAaQqeYBmWdWSsTtzyYUPpuAXrBNVvxVCcphDdiOgGoEpXzRrnNBacVuGgUkChCcHotkQqKCOJmyHSsRaEmmMMQrRYOrItKHMofhEeZzRrUcCtSTtYwsSWxOgwoiOOLlgHhGgjdTYjwYyaARDeEdQbiIaABqsGgSWwypwBPGgQqpkveEQXswuuZlLVvzUOmMrRFWQUbmBbFAaHuMvwWEhuQkKEbBPpLljhHJhxOykOoZDFLwRPpCcZzsvVzlLWaAMmiGlbYReOqrQqvBbCfTXtiLGpJjuCNTMRnNroRrOZOGTtBvVPuUmbERgLEXVYKkzxXJPpOaAohpIWhHSssvBbdMmpPyYlEgTtREeOMmodZzsTdGZlCcqKUuRrxXdcXcYylTeEtNrRqQnGAfFVvLfCFoOvncwfUfqQgMiImothcMbBtTDhHdhUuyaAYyYyYRrfIiLlOncuFfTUWwRrxXYyQqstDDdJjoNpqgGNkuoOUaObjJoOWvNLlnavVACoZbBygtTctOoKkLlRrTCYgrMmpVBQjDdQqbBJqIFIobIgVvRMvTtVcFRrmMfvWlPsPOoxOoAZzoOoiKEdlnecCDdDYyAZlLKkzaMaAazELMzRTevVpPdRNxSxDeETmWwRwoBbhHODdjuXneEKkNxTgrTCfbDgGaBbJjxQwtzZTWdeJFEkNKkWwWYFjJNBAPqQUEenNupEHyYkNnKkMmKhivUuVjJIVUuNnbBpPqQjzmMhsUTtggLlGpPtBfuuCcUUljJBkKJjEIiHuUwWOXcCxTtmMriRQlNMmymfFxbHQqpPyyYBxQfFqEeXbzDdZpSKXwWxScrWUxgGXJrCOoZKFlNKgGEUeEuHKbEenfHhFNGglLBhqudvjyDkKrDHfFqFfIfUngEZzdDKFvjJBoOCqQqesgfYBbxinNGoFfyYOgzZIeboOeIivsIqQqQnIXxIydDYOoHhThAOvKsNdoTtoOiIxjEeYMndxxMzZbaBZzbAzixEeXIissrfkcXxCbTrRJjiIrLTiIHhvLIiOOoVTyXgtIbBnNYBjAMmkgPEEwzYCaAcyQqZWVvkpPnSetRrTFBbhLrbJjBEeGgQqDdRuyZHyYNwCBtTbRrcbBWwWeZzKEsSbBNnLltTIwgqzTfFWwtrHfDdFBYrYpPIihRrHpTttHEoTPJRrsSXxjuUBbpPkXWdqlGgXxPsyCtTSscoOTtZzYYnaQQqGrhHRWdZjDdbNWsuHRAaoYbByCFPpwWgGNgGGjqLwhIiHfvjJUuKkcCZGgnNgGXSeiGtGgUrfFXnjzNnZgqMSysEmMnVvyYxjxBbXHOQKFbBahnerLlReEcCiQUbauRMlbDdNNvVniXhHgoOEhpkdQqsSsSRQdWwfvVyYBxLvVOZzBQALvVTWOGgouzMmBMyIizFLJjjGqQKsmOoqAauZkKQgGqOoQDcCSjhQEebXpCaAoOrPTMmfbBVMTAaPOcpPkEiIRrpsLlJZzjcDWrRAkKALlMmmPhXjwgGWtHysNiZZIUhgrlUuLRTtGMmulVvLoOvZtJMFMKKTtyUnDDLMEeMLzLmhmZzAtTLlNlLPKyZeFLGglUUtBbTCcuAaiIuoOoOfEuIiJfsXxPQqovqJjGFrwvHhdplLDahfcCFODsSdoYRrZlGMHXqQPbaRVvNFfnFHhcCYDKkdDaAdbBhbtmPpbVUmyQYdDHhGgNnyPpJKFrnTtdiIrXxKGKERrhPpgatTKOohsSiIBQJjqbFeXxEaNWhpPHwnVDdhVimMmWPUaHyYrcisZOaIiJjGLIiqaJjoONcRkuUKMmtTtTUpYoONMkKAazWwiJjBJUuCCFvVZGEJjZLOalVvoOMeglIiKkYlbBtkErRgWqJjOukKWwFyAJIiyYxXHrFfrnNyzjmNhHDsSDdhGalLUgyMsYyYDlyYLnNdRMMmFfxhanuldDlLeouUBiItTaGzeENnCcUzwCcmkaKkWwupBFfiILmAaetThyYyCcUoOuJicCIOIzZirRgWMxXcCjJLlmoBbkdDNVvnImQypzZsgYFfzHjbtPCGAaXxdDKuDiIsAVvxXEeVzZPpvGglfFNBxXKJLvmzZQJpPiMRmZzphKEQSUuSDdkVgGacdDKkOEegGzeWBbfEECcemUQqpPbZqadOUebBzZxpqQPGPprOiIbFAUuNtTJHptGbBaTtAVvAJGgusnWbBClpPLYimIpYrkWduzMnXuUUqQuxICcgmMSsApPfFlsVfQqxBvSlLsUUucCccCCfvVFDLldTvyYfPGgpKkUrRusSOTbeEvVMmBtRthHTBwBbdDpfFylLRrRyYQvZtTjvNnmvdDmMUMZZzzrqsbDgGYyQRZQqXdqTtFHQBbqYgBbGREQfHhxOokKdDkvNnVWnoONwmMWQPmWVQSsZWXBbTrRprRrRpkCcQGeELljJqQwHzZYtYyTyBUTtucxiGgKnBbnsxiPpLGjJgGTxJQThHtqWwLXXxZjDMmdJDEexVoOwWspPIiSwWlLrcDdXUuxmnNuhonuSaJjwWAFTgREMNWwnmePhmAatTMHCLlibBIOGgpdDQqfvPvdDcWwjqQztTZgGcCDPjnNIiFLljulXLlmMxbBvSszZVLUuyZzOSsbjJNnwjTtRRFwWHDxTWwtlqQLhjMmZAapPMyiDdbBkKkKeaASNKkcRaATtiLlsAaeERroETKIWFXxYDhFfHigsSkKXNCWYYULlryhhpCcgGmGVWwCKoODCcdGgkisRWNfFnQsUIiWmMcRAmoOfSTtVlLGsySsvHrRzPpiOTtfapcdDCuUcClLJjjKkGgQdfAiIyJjbBUuYacUNVvwpNneEPgGJjWyNVQqvsvjFYPpnNyXHWwhQEexYuFFUueEjBbrvIXAaRNTtPpPdGgMJeqQfXSseExHqQkKhgyCccSLhDDkKoudDCSQqFvVfmMUuscmOYyoMUqfFTttTYPpiBOGgVIuUcCUmMupmXxTimBFNnKkTRgGrneUuiIEAAaBmEVhWnOouFZzIiMmIDXNXxIKkiZVHhyIiXxYtTLLAOXHhxoaAepPvXEeTfCcWVTZIVEsSjpPQqQEqQqxBbFMDdaEeeEsSCLIIiNnsSybzWqWwFTJwbAasvlGgiIFeJPvyYCRnaTyYtmdXxBiImMbjxXwlACcOoZmcgrXDKkRjJtTTPAYQqtlLkPpKGgMmMvVixLbuQjJqOBgGHBLWwlTvWLVBRyYgGIqRHNwWCcSmPpMzZffBmMDfSDriIkIizZpPDbBdJjpXvUwXsOgLlGYHfuUwdqPBjnNciwWHUPxCcXZzpPipOoAgGaOncGaAgCSNasSBMmlLKknNyYIiksSNgkKhHPqQpGwGgbBtTGguIiUWsiBbIDYyKPBtTbjsfCIjJUscFlLIrRXxiJpPWCRYiIkKpnWwoXdJjDqQwWqQIixaEMytTBbZzViIoOzJjtTWwgeEkKJdoONiInZQaWUuwArRWgaAvVPXxpmaxXAoiISjJsfKkmvVaexNlwnNgGyCNlkKfOoZzsnUQqzIiEeVvqgGQWXKQqbaAJsuUzmfFuUVUgItXMLjJHOiUuPBbpCcygCcVXLlkKddDdMAaWcZmltDeExXMvxUUuuXWnPKgftRTLlSsSstrXEeQBBweEmnIKkioXwuCcDrgwqkvSmjPpDPFewWPpjcGrNnCWwWkeEKYpVvPWwEZnNzPpLVtTcZlmMLWWTRrFWHIzpPZCUgYNaANnRrlLJDdZItTiXfsTtScCLfFExXgGwMOHiIhZzOovhJkQqntHnrKItTuOxSlYyxXSzBQqNncOOoNOonZzoCmMyYHQxcAaysSFUuhOCAPFfpPsSpSsaszfxuUXxXvVFfFRrZmasvJmgGMXvVvFNnFffFfFBpPGFfeyKjKvVFhdDxXiUQquSslLlAayPpYswWSClLclHhqOQIXxUwWoOHnruUjJSbhHpNnQwPpSMPpbHhThHtDTteSEemMevTtKtHjJhyeEPpDCfRrFfJBHhnlOhSCxwOaAvVUgGAaUuuXKEelBIXoZzkciIxXnNDfLlhWcpPCYyYdXwWXxuUKkDkdDWwKJjFqQhtTJAKkaPpCJStaATsbVEwUbyQqZzZErXsyCcfFgGMcCAaJKkSsNnZLYylzLfFVSdXgqXDdbBaixLPHhOzZRNLSsjaTvVtsSdbfFMmUqTtQzdRrNEeqOzkzXxZpxLlaQGgqAaivVQqniRrIAaNljJtTZzwJlLeoZPaVvxZoXFfFfjwQqtTnmTkKtLlbBEgZzTdNaAGbBgYynfFFVvfDdlDmMdocNvVPpVvgtByoXKkVvxDLoxRukKsqQnNqwoMmOXdfFIDjhMmgbkrPpEQEYznNDEdDJVvhEejJtTHjZzXxuGgrteggGhfuIyYRrVTthWUupaGgdDAxQqXdmgGFBbfcudIigUiKkXZVGvRrVsDRDdrfFNjXxQqHvyEbfbFfKKFYSsaAeEyfxhHeCDlXwqwhfFUpPheSQqsENnXxJjHlLDUuyYxkKMBbdDkjWwGkFsIDfFkKdtfFJONKknttTTKvyLlsXxgbBpPAQfFKJjknyaAYqHhQBbLlNScZFfJqrFfxXbBdELnEXBbLoOcEeQFZzfGrVIivZzixCcXdaATBfFbDdoOTttDMUuUuXxrGNnJpZuUuUmMZITfFZKiDhCcCcMvqNPpCcnLYrReJjkGRLzZgGPDcCdJjyYpzZSrpFfocwsSiIfFRPpAaXBBbLlbhHxLjJNBbuhHwgrRCcQArREeoEeOajsiTtImMtIiHVvOKsAafXxiIkQqNmMnAZcEsAaSsgkhxVmMNEXzPqQPpbBhHJShLpPFfYylwXXcfFCxCtvrRVsHXxiIZzhOApxXRrDZfJjpgMXbRrXuUCGxxfyNnYfUkeElSluUBbuyLlYdDWwbBjPplLkKkKVOXqgkKkKGqZzQJKkkEeKlOotTDBuSfUQfFBbYNnnuUnrRsfWGgrYhHyQBeEUMTttEpxUfHhFYPpyaQqipPdOoIMDjDGgdwUmGEFfeqpPLmMgqQGXJjxmZxEOjxUuGIigXJmOQDdWCIHDZzVwZHhHZIVZXlHnDdNiIjJckaAtTTtKSkOoPbBVvbMoOjJsSmwrRQqWvYyEkQqbIGDdCcuUgyaZVvzGgAdncCNtHHhhgWtZzTGPeRoOwilpBtfiIFFfjmnNMJFflZzmdjzyxXSNoOAzZaTpPasJNhrncGutpPBwpXxPQeZrGxqQJJjiIfbnfqTUWqQUvdsttFLlKqgvurRZCBkKbIDJZEeUWwukeJjWVVUoOrRuKkHhbBARDveEwhHWWPHAayYqLsStIaAgGAMmqUVLlvuLlZWhEeoORxFWfOoFhTtBhHvNSGgzZZMmpPLlMmAKgGRrOotDdRwXOHCJjcheuUobWCcwxXMUyYwmMWIrlLRHvVuUVNIiIJjwXgpFXvioOlauUvDdVmBvVKkWPegFLlfTIitfJLiLhyVCeEclLlLoOyYeEUxKlLQqPoOPLKifFIYYIitLlKZkKEeziMlLmIbkKgGPxGnsOojkKrSAURrNCcnDdJSgiIMGOTtjJoIivNkKnVXbBhgDdppPPGvvVgAzZLAaGglaUDzZduygGYAgvBcLOHgdDXGXCZIiWYQqywQgrRkaQqxVrWBbjwyCMdDmWNiFlpPsdDuecoOCEvFquIJFfpyYjJJjVvtBJQFfNvUuUNkKLIiGgMmlnFwBeFSCtThHwMmqjJxGgXHWwFBYybDRvuUjXTtavWwVWJjwfFvVJjBbAogRfFrOwWHkKbBUuFYEUuEeJUujNhVvBkaAlLoOHdDSYyqQsCcuUgzmMlLVvCWrRqpPeEhOmaArJXYycCxdTwRVvKTtyYkrbBWplLPcvKrVvOoPinNuIiMzEeuUZmCcKwWnEtTwWZfFVQZWrvozmkXxumMXxzZaGgKksSAMbbMfFiGXxHhKbCInbtjLMmhwpPGrMmfILocDCbfBbFctZFfLbBoQcfFqQLlCxXNSzNGgjJltxXmuDcCeEXvRrYLlyVRrRqaYZcEeUVvaeuUuXxVvGmKkMgidtTJjYVILliaiITtoOAtTGiIgVvvoZzGTiRrrzZzGiLlIcCgYyZVgmHhMBbHwOPBpPTsStmMtIpGgwIeEpFhHyYhyYHBQkaAXxKtZJRcQRrqCPXNFbBvYXxVvvVtlYwkKMHhtFpPdjGgBucdDTXPWwpBbPpoPqQPpaApOxTpPsSHRrgGDwSsWzIieEZlLNbfFIsMdbBDDhYyHWwWmtdDFOjJiIqmvoxXrQqqQXxsXWmRxXZJAajxvwWVCcSsdxoOzOgGuUclLCMmzZGAGXxgwRrWaaATyNeqYyPmiIMpQqQcCEnvjJfqQFhHWwZRrfFDWwKWiYRrlEekKLgDdoWMvVmvfDxhUuLHsShxXGVvgFfRgrZIiOLaSsbfFZmMdPpBxkmMQdRrqqYfjJOofbfDdFAaBrTtRHhgVEeGDdgrHMJjfFTUuyGgQqYyYtCcSsSszZPIbcBDoOMHhJrRjuUgBbCMCVvcYyQMiIYyrqQDkKMiIHhmtRfMYydDUUuPpRruzZMmFfAcsSshHXFfpOoNKdDkaAKkOoqQjeDtTRrdnNnEnkDdsSEOoeYyEUuzyraArTtRMxZIizUuQqUIHwWBmMoPqQDdhHqQRLmMXLlvBbRVKKzCcZQOnUqQVTGgjUuYyFnNcCrPeEpYurSsSxvjdHhDGgjJCdDczZtTqQaZzzZtQwtTcYkFEeHhIiwxISsXxiHbXpJWIiwyFfYGgnNyiITtmeMmJjaNxiIJkKeEAKYXZoOzBbEGlityYQngGCSZzWvVRrJjaaanUuUAToOaKkJyYfFKknzZIiNXxewGklaAYvJZINcLiIoGPpUzZuWwXBbZINnoOoOmOOoAaZOKsSkQqoQfVvZWwRDMmHhjmoOziImMQqjJqAZtTyvMlIiLyrxXnqQNgGtTBpVvvfFUZzMsnNStfFqjfwtNfjlLICcilJHomTbyTtnFAIxXQoOCcHHAGovVODgYFfUwgQuUmYLlpeKxxiJBbcCVvCYycPbBpOoGtThyHhjZOVlLgLnNnNHpPBbDAgGutIDhvUusamMiInUvBAaBbbSsaUUufqQhHCcFSsCcMJRqpPmSsUuHhMnBTTjxXlQmMDaDdxQqXdDKkJjxcClJjIWVHvQlLqVcCZWwzpfFGzmMSsnezZEvuTtlkESsEHyNAaoOnhdDdeEhiVdDvGtAamMYHhxXnjVvbYyBvVJNRrMqleEZzjJOFfoXxJdDVvQyYOrRPzMbiDVvFAanNnzTXpPptKeEdJTtZJIKeELJeEjxXEIiNrRphxpPFfCcAaXXhHNcMCmdDzBresGjJmNbgJnNpPZVZzaJjsYyWkKwvazZQNnIidaWVvAawaGgAcXxCKkuemVxRrbzzNGBcCYIiybitTCWwuQYydzZfCcCcFqUuQaADnNWsgGTtSIYyhOoDPpoqaqQxXYfQWkKnNTeEEetdkCCcCtjoOBfFYyJjECzZUzZIQqiRrurDdQqdDRlNtTnITtcXxBbwtTLbDdhbBtkfFlQqaPWIwWKMkoOxbBZzdRrGJeEjZKkTgYTIBaAbQCCsjhXxouztwWJJSsAajCcwWXxyYwWiIENnHgcCTtBblLHnNeEhInNNhHMmZdDgSsGctTMmtTYykKEeCcAJBbCcjsfebBTrxvSefFIORhHDfFdrzrRnNZRJjWmFwWfVVKpPkyYzZhjdAaQqxXVzGPpXxwWkfFKTYkKJjySJGycVvChTAIipLqxXembIijJwWvYVQqPTtRrDdpxCcUBbuGxXIiHhIirUAjjjXxJjJWSXDaAdEeHhEeCjIuXxcsSCtTsSlAQqaiHvfFuCcJSsWzbGrvwDdMzVvRAfFaIYyFwWfTtTNJjfTtFFqRQUuqrwScmMLYylcCqvVeIGPcCNnHDdwWdnQDdiIEeiZzVUuvIZDCcdzOoOsVvShgGaAUuMXxdbcMpcCtQqTVvnDmnNMRaArdNjJzZdQqDHhrabBJjUBbHUuhVvfFxXpMmFkKtTfhHXOogGFYKGsSBbtAaTMmgvGHuHHFAXwRrWxZaQqGHDurMxXyYIiBbmtHhxfLhHMoObBQvAaSjJewWECnNUVvHOoIiVDhHSsfooOOeEeEpZvDdkKXmMYyELzKkZlbBOmMoqNEIRrXxitTKkbBHaACcZzlEeTQlvnDhqeEKktTQdhHxzIiZDsVUejdDJDnerRmbBiIvgGpgxXecCtDjJdEybBQqYwhHWeGFuCCPpcvVHhfiIFWwJdbhpyYJjKZcOoOLloUhmMApPZzOoVPpEDdwWrRThmjRwoyMuUvVAkBwsmMfhHFxHOobLllQdDcCqdzeEogGIiqGgQLqecCEvZyYfWwbBFdxGVxXvcCgtTPOVsyYrbBRSviaAEmMdDQaWqgiaFfTzzZalEzZeLFGkKgvmkbtvVXxAaTYyKQqkBDmMiOoIbFfLEelOKKkkzsSYXxhHCJjRHhlLRrEOoSUzfTdAIiaSsDTtUJDdsSjUgGEVvPLletTwWbaAoaASTtVFfvOzcJjaHuQNncXxyYdWTtfgRrMSsTPaaCKkvVnUQquKWwqQkauwRUKOXPVvpZzPZcCmEeErDttRyXxYmMrwCDbBTtnNQqsUuOpPoGgmsSMOosSoOVKkPeQqVisSIPpMmrDdGggugGhHaAgihZzHIDdvlLDKkIPpiSqQsnmMukSsfoASstJjDaALlMGgnNKkEVviIemMKyVvYuUkbxlLXxpPYyQqXxavuUXxoDbXPptTSTJjXeExMmXxVfFngGSsRrJjQQqBBbXlLPpfSPMmpvVnUuEuQlLqUDdOmEvVLiGRKpSzZzZjJxXzqQZtwbBpKkfoOGgCcjbBeLANnaVvlzZUujrRJBUFnzFVvbBoBEVvDdeMtHLlhvCnHCcUugBLXxcEYyhYyHoJtGgFJEejuTtUGaTwZwjJWMmtTLluUfAoOoWwOaNxXnNKnNhScRsPWaAwqYnNiuUxXIDbbBBMmJSsweEDiRrIdWrRJjLYyzZmwWzsoIicCJfFrRXxGEuUrCfpPBIUJEeEnNNaINniAEFyYfbRwWLxXyYlreVbOocCXjIicDfFlLvVdCLlEeZsSjlxwDZzdAaLbRrBSsECnNYyMmcDdfFnNTyEKjRdmMIbMmwJEeILQqzJBFLCYyZuVvYycCpPZzbqBbQfrRbcCIixVvmhHwWWtTwdSsrUFlkIzZyYPIiprRLFntICUkKSsuxJjoOHTkXxnNAEeaGgKGgCcRxrRXDCluZzWiIZzTtDdPZzpBHhLNnlXUuNnMmwWehkhjXxJIwWiIoyYOHhSRrsIeVbBIqQivEBPqIvrRTtViZJjzjzDdtTsSRrdUHhujJBbFBbKkxXTsSjRrEeoTiItpPPpBhHtTmMBRCcMmcCUWwAUhHJjuahJPEeEiSDxEaAeAaSkcCIiKIiYIxXKkkKiyCcXcCxRIirLFojcENnepxWwXTtXnRXkKzZVuuBbHyYhMLvTtmMfFeEMMmUuUASkKjJTWwDMJjbPlLmOoMhHpbjXxHhYCcZbUuBgGzgAKCQatTAowWOPhHphSsTtMmHSsTuhHtEsMmSGnkKkSiIJcCSPwiIfPpsStFRnPpNXzZmMLlJjxXOQquUGgkYIRuJPNnssRrSuUZlWwLzaANDNptWytTQPpVmMKKkJBEzBRLlzZIaAIiEeEeugGcLSqQsPRGNWwPVvLSOoUuslMmMLleEeECGMmRfFTteEJLlfrRNRjJrRXxQuUTRrtqUaAKkgrfZXxKyYDAaLldjhTtTtgGHhUqNnXxQGAOzdkKDhOouUHHWYSkTzZAsSYCqprXUusUKkuaLxVFlYDeEdfXxjJAaeDdEyPIMmWwWwUunNKsFMmfRqQRrPprqRbnNJjnNdZKOoABbHhlLPDdpEGgEsSehHVkKSsaAeEcCYyUWbBhFJCcYzZIiVvvZzkKVvKjMMTtmvVoOPpHpGguIiTtxIinNXUHOPfXmMdaABpVvIiIEdxiIhiLVbaAwcboMmHqQhOEeYWwXTtxyqQBxonNhQqHvPpyYoOVfAniIkKxXjJBCzvByDdmjHhbDdJJjjzIlLOowGhHgWIiGgQVAaoLTtlVvWwVzZvOfFmMjJsWwTOJjNDdnxsSXtvVnNbBTotxHhXkfFPCHAeXhHuUNkKncrRCxpFwWHhvVfOoPbSgGCNnIoOiDVvEedrRlLeEonNkpNcCCcBRrRregGkKYyEwrRWcgGxelLEXUgGvNeBIibQqgGECJjuYqQWwyUmMcMTpmBHhXsShtnsSdDKQVvqjuUJhzdInqGcCOuLYylwWEUueiKkgGKkWwYyaxCvVfFJjZzcPvVPGgfFpGKVvrRVhHvAaDdkpPmbBbSzZJsSfpLlNnZYCcykaSsIicCPmjJKfFkxXAaMOoOoRrtCUFHvVPphxMgGkpPKlhHEeLlLmdpJRIiSNsjJuUSMVzZWwvrqQRQJjBbUJjjEeJeEdDeIyYnIthHRHIzLlBUuHhGgVvKrRkrqaAQRbhHTdsEYywXxHhiIuUCchHzZYyWDdwsnNNnREKQsSqbDdBkOorBEeWwSsAdEeAaDQCdDcWwHvNmlLMyPWlAaLwSkdDRrKkKspPfFeEfdUuDydDEntfPpQLlqqlLCRxpqOEencCMyYgvVGcoVFfvxXsWWzZNlLCdDtTPOqbRrnCcNfFVObBnNxxyHbghHmMYyGSsiIVvLlnbUuBwWNByYKjEeJkhYsMmWvVsNncCassaCXxlLcdDASfKVvIikVyYxXszZlqQIiKkCPpXxcuUfKPfNnFgGpPtNjpPsSJDJKkjhHZzlGgTLnNHYyjOoJqQhPXxoeEOsADdqQAHNOoxXwWCdDlwutTUnNqQWLyYCcGgxUTthbBrRmtTVxXZzOonBbnVvNRrPNnkBbIxAasJjGghaAHOLluUsvoPpTtjeKkEJQqOvTkKcCXxtVTzZtHzzZoSUuyeEdAduMMZzmmqQVvrQtGgTFfCZzcwWkqQjJAlwWLJjHCrRUQquchdwWlLhBbLlHAtHhwIEMmelWSsGgaAwnbBZzWwHhNIinirRUuoNsCuCfqQFcDnOoxuPpgrRiINoOzicLlCIkKFhHaAHfFeaAECchmMjJIHfFhifFTFNnBbaAiIffkKFHhtpPfSswrRSsPpsPcCpYyOgGVvovVWdDzerfMmItiJjoGgWwHcCZlOoCTtcLhpPgGHoOzhzQqDDduUdZhHEZUuzeSexAaysYyTtIiOKkolPqQtTeEpRrmMbhxXTqYyfMmLZziVvyGYIiyzZjqQgGxSwWszNneEZVvXwWSsIQoQvboOBwOWXxbjJWsSJjwZxXlqFQVvgGFewWNxXfVQDcKkCdRRrUjwOomMyYyYTtxcClllIiSsLVvFZGjJipYBMmBeQRHhJfFjLviLqGVGfFsSxhoOgLCcvuUdTDdtDVAalvVtaFfAiIhgHhLlGeEOReuwWBoObKCckGknCcbTVvGgQqroOtIiWFvVEfDdFwvVWcdofZzSsMmwWEzakKrxXRAeEdDIDditTGgQpPLmDmMNndAwBeEuUnNbYynNWjzZLfFlJuUjJfIitTFaHeoBbzHhZzZnNAapPMMmZsgGSHhWwubHVgTtGvxXhBhUdDmMuHaAbsQqNDXxVvdSLlbBCciVDdVFFLDdlYyfcCoOMIHhhHhKkCcPnNpPpNEeNnaApPBSbASsasgwWgGgGzmJZzjVvsqdfFDdRrLmjJlKkjJeRvzRrqdoHhOSLgGPEdDeJjcCWLlwtLlRpPaBbSHoSgGsKeQqTnYyNqQWBbCoKNnUJjcCikqQtmMTILGUWwugKJjhheMmydDNNiIRrTglGDdRzZQaIcEmMmDdUuLNnowWOwCczEFfqnNQIZziTrlLRtzZyFfXWzFfbBnNLlYWaRUsOoOvVovXxVPJjpdVwWvDAacCWwAyQqYruUhHwwWxXAdBbDPsPpSkyppUufFFfnhHNuUGghHaAIWwiHOodDhzhHgNnGLEboOtnNXxYyjJVDdDaAdHhvzZTIilLcCPpYMEGPpyYfFVvrRgemSXxsiIKnNDDdUurjIJhTtHCcMmUzXxRrCcpPZrLlTtQqQqHhdDOoeEFfSvRrVfFbBzHNnhfFyYZsSUJjAFzGgZfeTtAaQqxXEccLZFAaUFucCwwbOoByYSAXHhqtTQysSIFfikwIpnQkKgcCsSUuwWGCWwoVQqvvVPpORroOoOEeSelLiTBkKbmhHMtIqhHBbgGkKCciIQqaAuLlxXDdUXumMPpBgiGqQgqQNnHhVvcCLlDdZzqQakKsEeSAERYyOxuUEbBeuLlUakKAGPgGCoODDNnCcddcvVlcCcCHVvyYQqKJjMmdDPaDdiGyhbBqQHhHYSYeEwWwWTwWNnPNnAacCtVvTYymmMoOmMSsNZVGTtgNyYiISsjbBcCCcuUrRjCkWdDwhsSMmGgwWDddDZzHhHgGIJjiDWwDZzdsSkVvvVmBEsSeCQqMmCSsrRclUZXsShHQqVvnvVOoukBFfbfyYikMmMmNnqQKlaqYtTEuUKxXnNpRHRoOVdDdDjtXxHhTNnKAadpPmMkiILliKFfaKkPyYpAHhPpcPcCiVWAOUupPMaCcSFxXLAalxXtLllqQLwxXbBvVWFSVTDdEAaGNriIRnZzgiIEeedxIeEiXdvJjZzfFVDwWDURrtblLBTbBfIwWiFtMZlLLlGYuTtMzZEejMmRMjJmpPoqBbQOlUOocCrYsSSnNsljJLWBaAeNnEQqAsSfPpFgGiIgPpvNnVGHhaQSfyLlYTtFQqDeELUuuUWgMmGQqPpwAaMOobQqZnKkJiRrfIQqTzZmpPTfLlzZFtSsdPpDIEAaeybBYrRPNkoOFfVqQkKvfkKjJAZAkKaXxKkzuUXTtwOjJKkXpPxmMMmujJUsdAapYycCJjJjTNnCcthWFzZfqQoBmbapBbqQPbKKwWkkwWmMVXxvXHiIWwuJjjJeEUKkhdBMmTsSyYtHsRNzZuUngbBGMoOWwhHIiCcmwssSAaAaCczOsSUuOPqQpjJoBGxwljJHhAlLacCdNnDIiEZzgGNnFzZmBbaAsSMvNRrHhnVVvwaAGgYyeEWiIeDkmFfgaAkDdUubBYXxOouUIXxnZzcCMmpSgGyYhHoOsQqPbKrRbfFBKfDDddUxXPHhaAGxSemxZOokiWwhHcnFQWWwdDdDdDRrfYYyWpPoOxXSWeROIigGgzZRrqcCRrYrFgGfIcCLliSJjDSxFPpPpyYZWwzfXqQxXQQqeEjYtTVlLXxzZrQzZiIFfzlLZzZqUuIyIivVYifkjNnYyjJJdAaMmLlZsSxjNNnnJLgZzlSOotTaAsSpLlgKpUuGBIibAYyrRRrsStTJssaAAaSapPABtTDdVvBCLlyYcdiuxXcbBZzCvngGuBMmVvByYpPQqyhHYWcCuPpUxXBkcCKsSWwkVvRryxsZMYpOoFfAaRPprcCaARfYyTtFtzZFfKkvViITrQqqkozmumLHhhHeEkKYVvtdwWDlLThiIHWwAQqakecChHaAEmMpwBcxiIXCVuUBVvKAaktVvTQuytVvTsSBbYZzZUurREIiJrRjGsSgAaAaeTtoOObBSstZIWmOoMwvVLlyYiuPpgGXHhUxXGUuUukKIOotkKvVEeTNnEOoebRrBGboOBDdgaAQEeGgYmMCibBHhzUuLyYvVlGgZAdDfkXVfgGFUNnQquzcCqKkHmjyYOorlRrBbPiIpZztBeExDdQqOoXnNpIisxXSqPpakKIgGiwqQWQqqUXxulRrtTtnNTAaLEeCcOLKklyEeYVvpPtpPAVvaoOPjrRJLlqrpdDNkEeqcCiIcCkzZKFfQAFfaeAeEmiIMoOOLQUuDtTTtIiNnXAkKazZfANnnoCcOwWNhHjJpPaHvVmYyvzPpiVcCvITtPVapndDWbBwQqFGgyIidJjVvDIzFtGanBnpdDPHewWPpAazZcClbfFBeEhTthZzHJdDiIjLqQlgGpIiGgfFSTQqPpALlMRrmCiIcaSaKkmdDMOMmNnsSPpTtRrrRRlLHRbBrXJjJoAatbBTHGiIgyYNzZnQqrRnNhlxOoXHYyhfFaMEelDdmMLkGPWmnNMwsLlSTxjJUcGmMTPUuhHYypUHhsSJjuDdNFfnjwWQPpgGUuXXxEexqUuJPbnNoOeEbmMbBBTjJgGjxKzsSZkaASTtsXJsqBbsSQfFSIIiipPhKSwWjEFrRfetTDWYywqQdgIAaZKIikzQqZzKQqDdQlLqLBSMmefaAFFGgIifMmZzKkWGtToBbyYBGkKVvgKtYAagGSsvEemkKTYzxXwWqQLlZyfTOnxXNoVeEfFvrRYlLyFbUbBLlJoxIiFyYBbfOXxdDWaAwdbEejcIiBAxfFPptoOZzZUHFfVvJfFjGlLeEgtaAXzZAgmMMmVvzZXuUaAxnNKkQxXJyYjmMRUurtTqGrRkknNRrKhHGqQgJjKaKsSnkKNBlLboeEFfyYOKkkdDMmrRLjJljOoiIWwTtPpWPpjJDdKkwUuyCcYbBNoOlsSjJLXCnIiABbRrdnnZgGzbYpoOwWuKhQqHkddDDXktewWETKkltThHzZLdDEuUhbBHgQqtXRoOeWFfXXtTAaxxKkHhnNuUdAapPHhIzzZZidgGdDDHhqEekKQCcqhHQuUOorrTnYyibBoOIkwWpleEsSLhIiJuUfFtOouUBbSRrFzZfyCcvrfFiIRrmKkMthBbiIHhaAHlWwZzLTIcfSEWwesaqQutTUDddDAbJaAjYyPwWpHZtjMmMAafFQqmXxJuUTzCcUuDdoUgGuUfFvoOAiIauUPHhRhHrVvZzpoSMmjOoiUuIDRrdBbCcxXBNOoVoOEQjgGAMmsSalvVLepPGdQqDgZyYzkKtlLTdpPDkKXxSsiGgdDztTnNZwWYZKkxjJoOIiCcYycCfpXxFflMoiIiIOLlzPpNnLlzZoNbBnrRWwCcOFoBbCcZzfFzOoZwWODdAacRlLfAaYyFUuCcriICfuUdDZQmMJjIcCIiHhCHhBbcnNinNmkKDeEdtTzZEecCTtkKkrqIRsSBbrsSiImMeCcEPpnRZziINnmMecUubBCEEerNnRXaAPpCcxHqQZoVvNMmPzwhyOoYVKSskZzxXpYXxyWsSwFzfFCyYcSrLlRFfsEeSpPsKtEiIeJjyYcCBrPpRHtuMmUIiaAIiJjTtXLliIHhOaoiIJjODdRvIibBVUjJsSeEvCcVbyYBxXbBQwWVrYyRvFfWwgGtTGpPgiIOoAafFgWwlwtAamEezIiZiINyuPjsBbSJrRRrpqKkVvDdZzsSWjJsQqnNTtWwWThvVNnvBpGEeVvtOoTFfawSTjJtsBpPiIbSsmMHhbBoOWrnCcNlLpPQqRwfQqFEuUMUaxXAwrFfuhHbJjEsSeBMmCrbnNRdKkLRJjwPZONnoNnHiIEezZGTtzZtTmIFfsDdrIiRqQSyHzZxNqRrQeEtTnzkwWzZKUfFuZZEeJfFGUugjzlKkaAbBmmHhMCYycSPjJdyHhnNYZFGgfzKktTemMEJZzjDSsKvQLVvlolnNqiSsoOSeiISsOnNoiwoOCbQqWOSsowWwVvDVDeqlLQEDmMOokKFfdBqQjbBJwoaAVZzFfNnaAfFJjbBExXpPeaWwAvLlzqQZbgMzaAZVMmvqyhcCgGOctTslLSQqyYSeEwSsFcCfKtTdDQqCctTANAanKTtkRZzrIwVvVAaLWwlLDdrRlpPdDjYYyZyvVhQXxfFSWwDdnNsILlUxXGgzqQqQrRJjCfFcOoLlwWYyMBfFccCCbmuUMQEeqDOotTdnNmMmJSsjTxiIXzZMvXfFxPpwnOoNWXxPpswWtrRTSgMILliTtmGVpPFfUuWwFmMozZOxXfrwWRrRbBWFjJRrpPnNPhHPIiBxTtXLlDuNnUfPDdpNgGnRrOmgGQqJbBrRYywWyYyYUuXxjOoChkbBKHzKkOoGGggVWwvHheELlcCyYZzZgWUdDMmuwGgkKoHhOAadbBDIDdiyYHhheDdDdjJEMmxnNEENneeDKkdnNmMTJYyKkCcjDdtrRjJRrnNGNdDnhQqHBsSWwBrRwkKWcWwCVgGvtaAOojDRrdJTuUfKkFBHhbEebbGVvQqfFmnoOaANAWwXxRDdstTSVvLltTYPpyUunNDZzaAsSMmbBErRvZzUulLUaAgGELleBbuUNbqQgGBncCTtnPgGpjJmMeENbBkCcKOQUvVuLlqjqQtTJglLjGgaAJyYEYyekqQKNyNnYUunfFwmMNnWodDuUGNngOxdDHqQqPpQinNNnEeAuUamMAOZzlPpBWwbpNnPkAaqRJjdDrXxQbBOonJXxjNBczfFZUiIuYaAyMmCsDdoOfFdJzZjcpPyYYEcVmDdMNgGDcCdZzBFffFCyYcFfbODdZIizmGgMtTcCBQqFwWNnEcCetUuTfuULlGgLTtImMiRrFfxXsNlLnhkmWwVvyYMYwWrqJNnjQOZzVvohZBbzKtTkmMNnHhHGlLCDmMMcyYdDdhHSsKPpGgkqNnQBbkKkSqQWwSsuUsCqQaAcAiKkfFIfxHhPUupyWwYDgGuUdLyWwYwopkxXoMmgGqQhHOkTtTnNtNnfFhJjSfFfAKKkTXxUunlLBbEeNYUuFJjXVvbrRBdvEeUZkKQqPpzuuUEepPKxSsSsfFSNnytuUTYrRFfNnOZzQqozZNuUGBbgZznTtfFaaAbBxXAsVLjJltTMmjJvWdDSswAaXxaAuvVvNnsQpPqGcCVdDvEegScCVlLMqQmpOoBbdnNDpPKIvfFVKSekLlXaAaAxXxXcCvJjAIifpjCcJPYcMmOTtdDoMjJRrPsSXxWwgGAaVOuwWFfkKqOoQwLBhHbllfFLvVRXEedwWjFTGgtfJiIFmnNMwWmvVMspSqQCcsPkKSfmuUzZNnZGgeERrSwWsRrgVvGzmxlLYyXVvMmMAamWqQwMMohHcCBbpPFfOTtOUuxXowpyVLlVSjJHhrRPphHEeshSsEepEfcCLlVvFNnNnOYyoPNnpPpNBbnhZpEFfRrauVpPvUJvWmWrRhHzZwMKkGgspPSoOEeIiPppPbYyJjyOoYPJjbBDMmFeEDdbzZBKkBbUuaauUBbbBCNncJjrmMGgREeAhHNjJcCPpnRrIEeYNnyiCcAPgGjCyKGgkpAgGiIeEaiIPymMSsAaHKkqQhEZzXcCMmxuUJjhHxXMmjJrREeVvXxQdDuBbeEUBtTKYyoOzaATtxlLXeEVXxuXxUvRrHzZMmNnVXxmAaMIiOPpCKkcAzZNnaOozZWMKzZMiIBbtNUuRrjJONnonnNqQGLrRlWwFsbBrRSlkKTmMNntwWWwcCpIibBnNJNTSstnjdJjhifIIzZnNizZioOANaAsLuFfgGgGcGgqQCcEeCzpPOopDdnpPNiIaqQFfDpPdAaSsIadDqQAiUkKcCIiTtEepPOovdEeDVzZSswNiXxtTwWUVvJjdDycbBCLlYsSuIoORrCXxcnjpPnrRNynNJLmMlhzZHyYDdZzxXsSQFfqgGGgCgGcOMmdrRDbhHBiIJCIicnxXCcNjJlLMGlIiLgeECcBbNpkVvOoKVvPnVMoOHiIuhHGgUhWwHhZDdzgGDdEetHhJjXxkKTzZAvVLlaAziIYywWrYAaAayEeWwRiQqYyIzZZGnNxXgEeRrMQNnqmCchJxMmXzZjAaSsAaeEGZfoOoOFzbSsYyBgaApPYtTqXxQFfZzyCOofFcqQGJjJjGQqgcCHmMJjAKJjkaHiZzIhyYHIihhOOwVuEeqQtvybBcCRoOrJjbBmmMhHSsMDNbBneAabBEQqyzRrZYbDhgDdGHBaAbdBGbaAPpZzqQhgGiedDgGnNEBbQqXDpUuGgPsSjMmaAJXxMmVzzZXxMmmMDdmPwWpMKkZwswWFfSzLlqQZJjBbsRrOoEStTsfFrKaXxIiBfqQlNaAnVvYyQqDdLlqQiIuUdDRrQqjJQuUXxqXrIUuiRAaWwDTZFfDdzGwDUnNudGOBbogDJSsSsjKkpyYnNdDPsSpuUPksMNnmsSSKISOrRosdDiPpcCxXDdkHhuUeMmyYEKkTbBYytsjJFfjJsSQhHqSWwHxXhMzzZUuZRKkrpPjsSJzNnpPFfQqqQhHynNYXiIxHhvVFfaWwIRrfuPpxXUaAmMMmFkKrfKkaAFuUDQqfFdYTtwWEeyKJbBUujJjMmVvmMDdDKUuiIkgoOGqQdLyYptTlaAlLCoOPCcpcGgLkgTrNnyYRIFaAfitCjJcHZzhsSfkgGKOonNFSyYiIfFsTszqOwWoOIiyYgPpGBRrJjyYdtToUuOCcAarRQqhHEeCcKkCcRrRrDFVvkKaPpUuoOpZzRgGatSsTxXfxxXAaXtPpTUutTFerHhRfFRrhHdmvwWtxXTVMgGGgFfbBpPrPVyYXxIzZUuiqQtYyTecCKpPQqkmSsiIieeDdsSSsXoOzzZaAZNnlMmKkLNwWnUjJCiIcnNuvVqQAvuUNnxXFfuCcdDsmMVvzZQqiIqQMnNmaAiIYoOFfyXcCuUVvTtbBzZiIpPmnFfGBbKZzkgAavVNoOdDXFfvVxMiIFfFfuEeUDdcGgCuUsSgTwOoDtTdmMWtGbAoyQqYAaQFoOfLAalBTKkoOtcCbHpPUpkXxgxXGsSbByxKkXYvrtTRGgUuVMMsStTmZLSslzQqjJIifNuUakKAdUKkuDnNvVvbDdBslzyYaAyYZLmJmMjlZzLMcCBoOSsjDdJNnaAfFmMDdmWwArRpPbleEXxyiIkKYDbBqQdLCcCcAaFfTKVwWvkUAaMmxXjJiPpIdaADDdGgzByYWMmHhwpHhLldDZzPDQqddDRrbdqeEQGanNAgZzDKklLkKCcNnZWwQQqquTlLtKdDhhGgxlLCcXmMpVvPqQokKWzVvSsjJDUuvVdZjJAaKkTtQqhGgBoOoOSvVsfFtyYTtfnNFUuZcCzsSCSuZPofFOnNKkpIixEeXzUiIKqZzQiKkwWRJjhydDYyYhHNnHrxXIAgGWPpwaxjEYbByeJLlXvVkLlxPrRpAajAadYyDZzJJjXZSszKBEeAahHeDdmMDdnvVSbBAaTtspKxXkPNPpYyVRrcCqQvvVEXIieToOtYpPzZyBVvDNnHNnhdzQuUqZbZBbcCzzrRZRrOohxKkXgGkaALlBTtCwWcbKHoOcCBvVHhpPfFUmMuLEUudDAaWwtTaAdVtTvrZUuzIiRYyDgYyGPpFfDdenNaAnNaAgVvGeESsgjJCccCevVEWuUFfkKTKktwDdpPOoSgGsxXlCcLxXVdDvQqvVWvTtVeECcwJjcaANnwQquUWuUeiIGaAgxXEHhjKjJkjJNQqnyYgSsGfLlnNfFpTtPsSnNBbfJjFjxUuSsoYqQiIyOKkCPpcWNtdDnNTtTnwTtnNgGPpMqvVQmMWqQmMwuUglWwLDdbBMmQnjJYyNznpdDTtPNRhLlrRZzHFfOeEzZSsorIiMmGZzWyYhHwEeuUpvKlLkVHnNzLYyiZbBzQqIglFfZjJrRITSDTtdeExLlOoBbXsYPphHwWygaTDdtAWweRLlriIEGpPcDdDdaAeYyCcWZzJjwYyrRIYyLlicCECwWzZwWFveeEESGgsAafFQKOokqpPKzbBzZrRKkYhzZHMwWmFfjhHuUVYhKkHkKQvVqHhtTlEeSsLwWLMRrmUuloOoOGggmMMmbPFfeEEbBKkAXbqQhHBNnxwIiWnNAgGjJaMUdDpPuvAaVzKkJjOGgyYoZkVvKzQTOotTtYySKksJmMKaAkjnGAaWUuumMUOGDdgTtuUgAoOxXeEKuUvqHhQVGhHgkLlDSscClLdaGgpPVRrSsYfFBbyzgGedBbZDdztcCJjVvsSpMmHhPdDIxXiTWwuHFfhUpiIPvzZMNnmnNVDhHsSJjbOgGSsgGTttjdDJkKTzZtToXxtrRrVyYvRiiIItTlqQLTLdlLDjlPpLJuUoOQGguUAaqIikyYKElLiIaABbbpPBDeEdWCcweEedDsUurRyYSJjTEetTTWwtXxeYoOYyyEtWwTtOrRoWkZzDyZzYdKwluUqwbBWiIubMJjhHmCchHDlLWSdDiIjJsmMuUlLEewQqqRQqnNrQdtTYyPHhSsrRARraoLlvVOpUYyhHwmMWMzZdDgGDDdJjdPCcppPAZzyYBbahwWRliICJjcLmlLIimMRAarQqljgGbOKhHkofFBTtGwWghHJLBpPbblLsStEeTPpbzZAaIiaAhdDDdsyYCwWlLcnFKkKkHKkhUuZCczWmMwukKUwWacCAqCchFeEBQqbrRfoBbCUuGgcZzSsaAOmMQEeBVvbhOopPHKHbBXxhkqHxgGCTtcTDdxtTXuUtXEemMnNIihHoiIJjUWwuQqONSsRrnNnhRrUukKJCnNOlLoceVmMvrRsSrdDRhPpZzHFIiGgfaopPOKeFlLWwvVgGqzsSwWZQqAyYaQFffzlLVPpvZlLZzsldDLtTSsjJVkFfKRgGruNnUKVqnNQvAamMxiIXPpqQLlkAxXeoOEaLbCcgQQqqFfGBfFlqsSQEsuUSerHYyhtTDdpZzTNneELlNFfxhuUHXnhHXtRrTUuTXxsSpPtuUudzZiIPpAaDkKeEdDMRrmdDmMDqQXxQzZqmMlmMLdrJjRhuUHQoOqNnhVJjvHEesQqdfFDSUAaqQiISbBYydDtToOnRrNLlswWwWTtvVhHxXFfpPJZzXPpAaucCrRFDdfYyUgGoOxGKkRrgScCsqQiTtgGoOIbRrBdDzFfPiIsSAapZvVBbeaAYypPQmMqmMEjgsSaAKsSkpwWiIlLmluUuUuULmMAaMPiIdDoOpdDUOjPpdbBvVhRdsSDvVrqTtQiIzwWKkEBjJbeyqQYSWwsNTtPElLepgGdDPpFfnuSsUrkKRyYQqZXxkKfPpOoTTvVuUttOoFnbyYBzNJjnZopaURnRnpPNrNrRrWHqQhHhwHcTtFfChgGMXIixmnNuOoYyahHJjAHhOoQqxWwVvsSDdXNCrRrSsRcigGxXhHIDdBbDdsEeDoXxOORrodXgGGgxSjJqJjQdDIzZPpihifFIOoiIHlQqFfLHjJyYypPYAahOobIicCtTmMGgLlyYAcCkKaZQqQqIizSsrAaYjJFfXxqQdDUSsdDLzZlubBNnVvyRrsShHOoopPOQbBkKqepiIDdPkHhKErlXxLREeCcxXlLXxXfuUFYyBLlcCvViITUunNoOpDmMdfeEFIiPMZzekKEmyYtHcLlCQuUqZzLRrlhHhQSyYsyYXoOxqkPpKBSGghHsdDbhHtnewWEcCeEfhHYkKYybBytTSNnxXeEwtiIVvTUouUOupPSspPWTtwWZzpPtTgUuBbGvVQqNnrRCcsNnOSsCcoWwFgGNnUPpuGgakKAywWYPOoBbpuUpVoZzWiIwKkPpRFfrODpPPpPpbBdTjJtJgGgqQGgGjsgQqGmdDZzMSAatTUuWwJjHhzgTtLlrRoOhHGwGgLlXxWsSzZwPpWDGgJjddDDRrdZvVJLljqQvkKbbBBjJjJRrKmMBTtbkVdoeEXxtTXxHhrVvRoOqQODvzZzeEeEvVmMmMZziIZRbrRSsIiOoLLsSwWeuUEzZiIFaApPXxhiVvIPpZzHfFtTfmMdDwWRrLlKbBTuaFfAqQhHUaWwAtvAVvnNaBbVkxVUuvXtTxXtvVWwrRDdTfxXFmpuUPJjxXhHhoObBHMmGgJnNYyjzZOERFfrPpYyeogmMOdaApPDnNooOjJVvOsSoSspPMBbmUuPpGEbzZBSCcsenNfFJjAaZzpiIPdDKwWFfwWwWvVUukzsSZHVSsvVKEekvfFhKkQSsAmMabBPnNpzZqmAaoOMCeMPpmEdDqtToOrRQciLlkKdfFxXCkKcYjvVCcTtOoJyDNnNnOoYVveEyhHXNnxnNIdwWDzdDJjQqAaFfJfFBJjbjJjoGgOljUuJLzZiIUuFhHfuUCorRLiIEelOzZcjJmMtTeEfogYyGOfFWweEfFnNtTIiuUToOyYtWwlLYmMynNGgfFYypPyYvVNMmJytTYjGgDxXdnyYPpKkRHhAaBxXCcIiUubPlLprYkKyUQqswWSuoOnWgGxNnXwTtgYyGAcCaNeEIUuilLMmBKEhHeLliBbpPIkzZJrczvVwWwWKkOoZCFfnMmNnNwLlWwNbBnPqSsQaApWizZfFIEaAfFZOozZOozeRmPpMjwRrWJbBUuelLErRFfEeHmMIiWyYwQqvyYVLlZjJzMmZoWwOeEjJzheECcaAqcCCcTtLlQkKAaHkKhXuPrRpIiYSsyqQUivVIVrRyYFUuQqfvJGgjFpPkzZQqcCfFKHhIizZrOyYotTAaPpRTtqzZQfMmmMyYsSfNnFJjxDAadqcClLtTQRPpZzrmoOMJSsOuJjUVvyYoxXbBXxqFfQjLzZMHhFDdGgfmcCcfFClTtmhHMZsyYuBbUfFNnNNnSsncCSQqTtzjfhXxlLHPKoOkdJjDpFfFdhHDjJDdEeQTYytqAaEelLwPpWhrRdVjJvDHEeWPuUpwnNW diff --git a/adventOfCode/2018/51.py b/adventOfCode/2018/51.py new file mode 100644 index 0000000..10a0064 --- /dev/null +++ b/adventOfCode/2018/51.py @@ -0,0 +1,49 @@ +def reaction(string): + lstr = list(string) + i = 0 + while i < len(lstr): + if i < len(lstr)-1: + if lstr[i].islower(): + if lstr[i].upper() == lstr[i+1]: + del lstr[i] + del lstr[i] + i -= 1 + else: + i += 1 + elif lstr[i].isupper(): + if lstr[i].lower() == lstr[i+1]: + del lstr[i] + del lstr[i] + i -= 1 + else: + i += 1 + else: + i += 1 + else: + i += 1 + return "".join(lstr) + +def remove_problems(arg_string): + orig_string = arg_string[:] + Ustr = list(set(orig_string)) + mini = 600000 + visited = [] + for ch in Ustr: + if ch.lower() not in visited or ch.upper() not in visited: + visited.append(ch.lower()) + visited.append(ch.upper()) + string = orig_string[:].replace(ch.upper(), "") + string = string.replace(ch.lower(), "") + #print string, ch + if len(reaction(string)) < mini: + mini = len(reaction(string.replace(ch.upper(), ""))) + return mini + +def main(): + input = open("51.input","r").read() + input = input.split("\n") + for inp in input: + if inp: + print "Part1: " + str(len(reaction(inp))) + print "Part2: " + str(remove_problems(inp)) +main() diff --git a/adventOfCode/2018/81.example b/adventOfCode/2018/81.example new file mode 100644 index 0000000..4279f52 --- /dev/null +++ b/adventOfCode/2018/81.example @@ -0,0 +1 @@ +2 3 0 3 10 11 12 1 1 0 1 99 2 1 1 2 diff --git a/adventOfCode/2018/81.input b/adventOfCode/2018/81.input new file mode 100644 index 0000000..1c679a1 --- /dev/null +++ b/adventOfCode/2018/81.input @@ -0,0 +1,2 @@ +9 11 7 3 5 4 3 6 1 8 0 7 4 4 1 9 7 1 5 1 3 2 2 3 3 2 1 1 6 0 9 9 1 1 7 5 1 2 6 1 3 1 2 2 2 1 1 5 0 7 4 3 7 1 6 3 9 1 1 1 2 1 4 2 3 2 5 4 3 6 1 6 0 9 8 3 7 7 2 1 1 3 7 3 1 3 1 3 3 1 5 0 11 9 3 9 1 3 6 4 3 4 6 1 3 3 3 3 1 1 8 0 8 3 6 1 9 3 4 1 7 2 1 1 1 2 1 2 3 3 2 3 1 5 3 3 4 1 8 0 9 1 1 5 5 7 3 5 9 5 2 3 3 2 3 1 1 3 1 5 0 9 2 8 8 4 1 5 6 3 4 3 3 2 1 3 1 9 0 6 7 2 9 1 2 9 1 2 3 2 1 1 1 2 3 4 2 5 1 3 6 1 5 0 9 1 9 5 3 2 5 2 1 8 3 3 1 2 1 1 5 0 9 6 1 7 1 6 4 7 3 1 2 1 1 1 1 1 6 0 10 1 1 7 5 1 9 7 2 5 6 3 2 3 1 1 1 5 2 1 3 4 3 3 7 1 8 0 10 8 5 1 2 5 4 4 2 7 9 3 3 2 1 1 2 2 3 1 9 0 8 9 6 1 8 5 2 3 5 1 1 3 3 3 1 1 2 3 1 5 0 7 4 9 1 5 8 2 1 3 1 3 1 1 1 1 1 3 2 3 1 2 6 1 3 5 4 3 4 1 9 0 7 3 6 2 5 4 1 4 2 1 2 1 2 3 1 1 2 1 9 0 8 6 7 4 1 1 7 6 2 1 3 2 3 1 3 1 2 2 1 8 0 10 6 7 4 5 2 2 9 1 1 6 2 2 3 3 1 2 3 1 1 4 4 4 3 5 1 7 0 8 6 1 6 8 1 7 2 6 1 3 1 3 1 3 1 1 6 0 10 7 3 6 7 4 8 1 6 1 9 3 3 2 2 1 2 1 6 0 10 1 2 1 2 9 8 2 4 1 7 1 1 1 1 3 3 2 5 5 2 4 3 4 1 9 0 8 6 5 6 8 4 7 5 1 2 1 1 3 2 3 2 1 2 1 9 0 6 8 8 1 5 3 5 1 2 1 1 1 1 3 2 3 1 5 0 10 6 2 4 7 8 6 1 3 5 1 2 2 1 3 1 5 5 2 3 3 5 1 9 0 8 1 6 4 9 2 1 5 9 1 2 1 2 1 3 1 2 2 1 9 0 11 5 6 6 2 3 8 4 7 1 1 8 3 2 1 2 2 3 2 2 2 1 6 0 7 1 4 6 7 2 9 2 2 1 2 1 3 3 3 2 2 1 5 3 4 1 8 0 8 4 1 1 1 4 2 8 2 2 3 1 1 1 1 3 3 1 7 0 10 8 3 8 4 7 4 4 1 4 9 2 1 3 3 3 2 3 1 7 0 6 7 2 1 1 9 9 2 3 1 1 2 3 3 1 1 5 4 5 1 3 1 5 4 3 6 1 9 0 10 3 7 1 1 9 1 3 8 2 4 2 3 3 2 2 1 1 1 1 1 7 0 8 1 2 8 2 3 9 4 2 1 2 2 1 2 2 1 1 9 0 6 4 1 1 2 5 4 2 1 2 3 2 3 1 2 1 1 4 3 4 4 2 3 7 1 7 0 11 9 8 7 5 3 5 5 7 9 6 1 1 1 2 2 3 1 1 1 9 0 11 8 8 9 2 7 3 6 8 1 5 8 2 1 1 1 3 2 2 1 2 1 7 0 8 1 4 4 5 6 4 4 3 1 1 3 2 3 1 2 1 2 5 1 3 5 4 3 6 1 6 0 11 3 8 4 7 4 7 7 1 1 8 9 1 2 1 3 3 1 1 5 0 10 4 8 2 8 1 6 2 1 7 7 2 3 1 1 2 1 7 0 9 9 4 1 8 7 2 7 1 4 2 1 3 2 2 3 2 3 2 1 2 3 4 3 7 1 5 0 11 2 1 9 8 9 1 8 5 8 8 9 1 3 1 3 2 1 9 0 11 3 1 8 3 4 6 4 3 1 5 2 3 3 3 3 3 2 1 3 1 1 7 0 8 1 3 7 8 9 1 3 7 2 1 2 1 3 1 1 4 4 2 1 4 4 1 3 7 1 6 0 10 6 7 2 1 4 6 7 1 4 4 1 2 3 3 1 1 1 8 0 9 2 1 9 1 9 9 2 2 4 3 3 2 1 3 1 3 2 1 8 0 7 3 5 1 1 7 7 6 1 1 3 2 2 1 1 3 1 4 1 3 2 4 4 4 7 3 7 5 4 3 5 1 7 0 8 6 5 8 9 1 1 7 5 3 3 3 1 1 1 1 1 7 0 7 6 6 6 8 1 6 8 1 1 1 1 3 1 1 1 5 0 6 2 5 3 7 1 5 3 3 1 2 2 5 2 1 3 1 3 7 1 8 0 6 7 3 2 2 1 1 1 3 3 1 1 3 1 1 1 7 0 6 7 7 4 1 2 4 1 3 1 2 1 3 2 1 6 0 9 6 8 6 6 1 1 6 1 8 3 1 1 1 3 1 3 4 4 3 1 4 1 3 4 1 8 0 10 1 6 8 6 2 1 2 3 8 9 2 3 2 2 3 1 1 1 1 9 0 7 7 5 1 5 3 1 3 2 1 1 3 2 2 1 1 1 1 7 0 7 1 3 7 2 8 2 5 3 1 1 3 1 1 1 2 5 2 3 3 7 1 5 0 10 6 1 4 7 5 8 8 2 7 5 2 1 2 1 2 1 9 0 9 3 3 2 6 6 2 7 8 1 2 1 3 3 2 1 3 1 2 1 7 0 6 1 3 1 2 1 3 2 3 1 1 1 2 3 2 4 1 2 2 2 3 3 6 1 8 0 11 1 2 2 1 2 2 1 7 7 5 7 3 1 2 3 1 1 3 1 1 9 0 11 1 2 1 4 5 3 1 4 9 9 6 2 2 1 1 3 1 1 1 3 1 8 0 9 8 9 1 3 9 6 2 7 9 3 3 3 2 2 1 1 1 2 3 2 1 2 4 7 3 3 2 4 5 3 7 1 9 0 6 1 4 4 2 7 1 3 2 3 1 3 3 1 2 1 1 9 0 9 1 7 4 5 5 8 5 5 4 1 1 3 2 2 2 3 2 1 1 7 0 9 1 7 7 2 3 4 1 1 1 1 1 2 3 2 1 2 3 1 1 5 1 1 3 3 6 1 7 0 8 4 7 1 6 6 2 5 7 1 1 2 3 2 1 2 1 8 0 8 1 9 9 8 2 2 1 1 2 1 1 2 1 1 1 3 1 9 0 6 4 6 1 5 3 1 1 1 2 3 1 3 1 1 1 5 5 2 2 3 1 3 5 1 7 0 10 6 3 7 2 1 8 9 3 1 7 1 3 1 3 2 3 1 1 6 0 9 2 1 6 1 3 7 6 9 6 1 1 1 1 1 3 1 9 0 9 4 5 1 5 1 9 3 6 8 3 2 2 2 1 1 2 1 3 3 5 3 1 1 3 4 1 5 0 7 9 1 2 8 2 1 3 3 2 1 1 1 1 7 0 6 1 4 2 8 3 2 2 2 1 2 3 3 3 1 7 0 9 1 9 1 6 8 7 3 9 7 3 3 2 1 3 3 1 3 5 4 2 2 1 1 2 3 5 3 3 4 1 5 0 7 2 1 2 7 1 7 7 3 3 1 1 1 1 6 0 11 4 7 9 7 8 5 2 6 7 1 3 2 1 3 3 1 2 1 9 0 7 6 5 5 4 2 1 1 1 1 2 1 1 3 3 3 2 5 1 3 3 3 6 1 7 0 7 9 4 1 1 8 7 7 3 1 3 2 2 2 1 1 6 0 8 8 4 2 9 1 7 2 5 1 1 1 2 3 1 1 6 0 7 7 5 1 2 2 9 8 2 1 1 1 2 2 2 4 5 2 1 4 3 5 1 7 0 9 1 5 3 1 7 5 1 9 6 1 2 1 2 1 3 1 1 5 0 11 1 1 7 2 3 2 1 9 5 7 3 2 1 1 1 2 1 8 0 7 1 4 8 6 6 1 6 3 3 3 1 3 3 1 1 1 3 5 1 3 3 7 1 5 0 11 1 4 2 8 9 1 7 5 1 1 4 1 2 1 3 1 1 7 0 6 1 9 7 4 6 5 3 2 3 2 1 2 1 1 6 0 7 9 7 1 5 6 7 1 2 1 3 3 2 1 2 1 4 4 1 4 3 3 6 1 5 0 8 7 1 6 1 8 6 8 1 3 1 2 1 3 1 8 0 11 4 4 1 6 6 1 1 8 1 4 5 1 3 2 2 1 3 1 1 1 5 0 7 1 6 6 1 2 5 7 1 2 1 1 2 4 3 4 1 4 5 5 2 5 4 5 3 7 1 9 0 8 6 9 5 5 7 4 2 1 1 1 3 3 1 1 3 2 2 1 7 0 7 5 3 6 1 1 2 5 2 3 2 1 1 2 2 1 8 0 7 1 1 1 8 3 5 3 2 1 3 2 3 1 1 2 1 3 3 1 3 1 1 3 5 1 9 0 7 6 4 4 6 3 8 1 1 3 1 1 2 1 3 2 3 1 6 0 10 6 9 7 1 4 4 4 4 6 9 2 1 2 3 2 1 1 5 0 10 2 2 1 8 1 2 4 6 9 5 3 3 1 2 1 3 1 5 3 2 3 6 1 5 0 11 1 2 7 3 2 5 3 9 8 2 1 3 3 1 1 3 1 8 0 7 9 9 6 1 4 3 6 1 1 3 2 2 1 1 2 1 7 0 6 4 3 9 1 3 9 2 1 3 2 2 1 1 3 1 4 2 5 3 3 5 1 5 0 9 3 4 9 9 6 7 7 7 1 2 1 2 2 2 1 7 0 7 1 9 5 7 8 2 9 2 2 1 3 2 1 3 1 8 0 7 9 3 3 1 6 5 5 1 3 2 3 1 3 2 1 4 5 2 4 5 5 3 1 4 1 9 5 3 6 2 4 5 3 7 1 8 0 9 8 9 1 1 3 7 5 8 5 3 1 3 3 1 1 2 1 1 5 0 10 8 4 3 3 8 3 1 8 5 5 3 2 3 1 2 1 5 0 8 5 4 1 8 1 4 5 8 1 2 3 1 3 3 1 2 4 2 2 3 3 6 1 6 0 10 1 1 2 1 2 3 1 2 2 2 1 3 3 3 3 3 1 7 0 9 8 2 1 3 1 8 1 6 3 3 2 2 2 2 1 1 1 7 0 10 1 7 4 4 5 1 8 8 7 1 2 1 2 3 3 1 1 1 5 1 3 1 2 3 6 1 6 0 6 6 1 9 3 3 1 2 1 2 2 1 1 1 5 0 10 3 8 4 7 7 8 4 6 1 3 1 1 1 1 3 1 8 0 10 6 5 9 1 1 6 7 1 4 6 1 1 3 1 2 2 2 1 3 3 3 2 3 3 3 6 1 8 0 10 1 6 4 5 1 5 1 1 8 1 1 3 3 1 1 1 3 3 1 9 0 11 1 2 8 9 8 2 1 2 6 8 4 2 1 2 2 2 1 1 1 2 1 9 0 11 7 8 1 8 5 3 5 1 9 7 1 2 3 1 1 1 1 1 2 1 3 5 1 1 3 1 6 4 1 4 1 4 3 3 4 1 9 0 9 2 3 5 5 1 6 4 6 6 2 2 1 1 1 1 3 1 2 1 8 0 8 1 4 2 2 5 2 2 7 2 1 3 1 3 2 3 1 1 8 0 7 3 5 1 1 8 6 1 3 3 2 3 2 1 2 2 1 1 3 1 3 4 1 8 0 6 1 3 7 4 9 1 1 1 1 1 1 2 3 1 1 7 0 6 4 1 3 4 4 8 3 1 2 1 2 3 2 1 8 0 11 4 3 1 5 4 1 8 2 9 7 5 1 2 3 1 1 1 2 3 1 5 5 2 3 6 1 5 0 8 6 6 9 7 8 4 1 1 2 1 3 3 1 1 8 0 10 6 9 3 2 5 6 1 4 1 7 1 3 1 2 3 3 2 1 1 9 0 6 1 8 2 4 7 6 1 3 3 2 1 2 2 3 1 4 2 3 2 2 3 3 4 1 5 0 8 5 7 8 5 5 7 1 1 3 1 3 1 2 1 7 0 10 5 1 3 3 8 4 3 2 1 6 1 2 1 1 3 2 1 1 6 0 6 2 2 3 2 3 1 3 1 2 1 1 1 3 4 2 4 5 1 2 5 4 3 7 1 6 0 10 4 3 9 7 1 8 1 3 1 8 2 3 2 3 1 3 1 7 0 6 2 2 8 2 9 1 3 3 3 1 2 2 2 1 7 0 8 9 9 8 8 3 9 6 1 3 1 1 1 2 1 2 3 2 3 3 2 1 1 3 7 1 9 0 8 1 6 7 1 6 6 1 3 1 1 3 1 3 3 1 3 3 1 9 0 7 1 9 2 7 5 4 7 3 3 3 2 1 1 3 3 2 1 5 0 9 9 1 6 2 1 2 8 6 6 1 3 2 3 3 2 3 2 5 3 3 1 3 6 1 8 0 8 1 7 8 8 5 4 9 7 3 2 1 3 1 3 2 1 1 5 0 6 7 4 7 1 6 3 1 2 1 2 1 1 9 0 8 5 6 2 5 7 3 1 5 1 1 1 2 2 2 2 2 1 5 3 5 2 4 5 3 7 1 5 0 10 1 9 6 3 6 9 9 2 4 3 1 1 1 2 2 1 6 0 8 7 3 9 1 7 8 5 7 3 2 1 1 3 1 1 7 0 11 4 8 1 1 8 5 2 1 3 7 8 1 2 1 3 1 1 3 4 4 2 4 4 4 3 3 6 1 5 0 9 3 5 1 1 3 9 8 1 5 3 2 1 1 1 1 7 0 9 2 3 1 1 5 7 1 1 1 2 1 1 1 2 1 3 1 6 0 6 3 6 7 2 8 1 2 2 3 3 1 1 4 5 2 1 1 1 2 4 2 7 5 4 3 6 1 7 0 9 8 6 9 1 6 7 1 9 5 2 2 2 1 3 1 2 1 5 0 11 9 8 7 2 5 8 4 6 1 5 1 1 1 1 2 2 1 5 0 6 7 1 9 3 2 8 1 1 1 2 1 5 1 5 4 5 5 3 5 1 6 0 6 5 1 1 1 7 3 3 1 1 2 1 2 1 8 0 6 3 7 1 7 1 2 2 3 1 1 2 3 2 1 1 6 0 7 6 2 4 1 1 6 5 1 1 1 1 3 2 3 5 3 1 3 3 6 1 9 0 7 2 2 9 1 1 3 4 2 2 1 2 2 2 1 1 1 1 8 0 9 5 7 6 3 8 6 2 1 9 1 2 2 1 3 2 3 2 1 6 0 9 7 8 8 8 3 2 1 1 8 1 2 3 1 1 3 2 5 5 1 3 2 3 7 1 9 0 9 1 9 4 5 3 1 3 5 2 2 2 2 3 1 2 2 1 1 1 6 0 10 5 9 9 4 2 6 9 3 5 1 1 3 1 2 2 1 1 8 0 11 6 2 8 6 3 9 9 7 1 3 2 2 1 1 2 3 2 2 1 4 5 1 3 3 3 4 3 5 1 8 0 6 8 1 4 8 5 5 1 2 3 2 1 3 2 2 1 6 0 8 1 7 3 1 9 4 2 3 2 3 1 1 2 1 1 8 0 10 5 2 1 1 9 2 7 7 7 4 2 3 1 3 1 2 1 1 1 2 4 2 1 4 4 4 7 4 4 3 4 1 8 0 11 5 8 1 7 8 1 7 5 1 3 3 2 3 3 2 2 3 1 1 1 6 0 6 8 3 1 3 3 2 1 2 1 2 3 1 1 9 0 7 1 9 6 9 1 5 3 2 1 1 1 2 2 3 1 2 2 5 2 3 3 5 1 6 0 6 2 1 5 1 2 9 3 1 3 1 3 2 1 7 0 8 2 8 1 6 7 8 6 4 1 1 2 1 1 2 3 1 5 0 6 1 3 5 1 4 6 1 1 1 1 1 2 3 2 1 2 3 7 1 8 0 8 4 4 7 1 2 1 8 5 3 2 3 1 3 2 1 3 1 5 0 9 4 5 1 7 6 8 1 5 7 1 1 2 1 3 1 6 0 10 7 7 8 1 5 3 6 4 9 6 3 3 1 1 3 1 3 2 4 4 2 5 3 3 4 1 7 0 7 1 8 6 3 9 4 1 1 2 3 3 1 2 1 1 8 0 8 3 4 6 9 5 1 4 1 2 2 2 1 2 1 1 1 1 7 0 8 1 2 7 2 9 8 2 6 1 1 1 3 2 1 3 5 2 2 2 4 3 4 4 5 4 3 4 1 5 0 8 2 8 9 3 8 2 8 1 2 1 3 1 2 1 9 0 11 4 6 6 3 2 7 5 5 1 5 3 3 1 2 3 1 2 1 1 2 1 6 0 11 9 6 3 3 9 9 5 4 9 2 1 2 3 2 2 1 2 2 3 4 3 3 5 1 6 0 10 5 6 1 5 1 9 4 6 1 6 3 3 3 2 2 1 1 8 0 7 1 6 1 1 6 8 2 3 2 3 1 1 1 1 2 1 6 0 11 2 6 4 9 3 3 5 1 1 6 6 1 3 2 2 1 1 5 2 1 1 1 3 4 1 7 0 6 8 4 1 2 2 6 3 3 1 2 1 2 1 1 7 0 7 9 2 6 5 2 1 4 2 1 1 2 2 1 2 1 6 0 9 2 3 8 9 6 9 1 7 7 1 3 1 3 2 1 2 1 3 4 3 5 1 6 0 7 2 1 8 9 2 2 1 2 1 3 1 3 1 1 8 0 7 2 4 9 9 5 5 1 3 3 3 1 3 2 3 2 1 7 0 9 2 3 1 2 1 2 5 5 3 3 3 1 2 3 3 2 2 3 1 4 5 3 4 1 8 0 7 5 1 6 8 1 7 1 3 1 1 2 1 2 1 1 1 8 0 6 5 3 1 2 5 8 3 2 3 1 3 2 1 2 1 6 0 7 6 7 1 2 5 2 7 3 1 3 3 3 3 2 2 1 4 3 7 7 1 7 6 6 2 5 4 3 7 1 6 0 11 1 1 4 5 4 1 5 9 7 9 5 3 1 1 2 1 2 1 5 0 7 5 6 1 6 9 7 5 2 2 1 1 2 1 7 0 7 7 8 3 5 1 1 3 1 1 1 2 1 2 1 5 4 5 2 4 1 1 3 4 1 8 0 8 9 1 1 5 1 3 9 6 3 3 1 1 2 1 2 1 1 8 0 9 9 5 8 5 4 3 1 9 1 2 2 1 3 3 3 1 1 1 6 0 9 3 9 9 1 2 9 9 3 7 2 3 1 1 2 1 1 1 1 2 3 6 1 7 0 9 1 1 4 4 9 5 5 7 2 3 3 1 2 1 2 2 1 8 0 9 1 9 2 9 3 1 3 1 9 1 1 1 1 1 1 2 3 1 7 0 10 9 7 1 2 8 4 1 1 6 6 2 3 2 1 1 3 1 5 2 3 2 2 4 3 6 1 8 0 10 9 6 3 9 1 4 8 9 1 3 1 2 3 3 2 1 1 2 1 6 0 11 9 2 6 9 2 1 6 2 1 6 1 2 3 2 3 1 1 1 8 0 7 1 9 4 4 8 9 1 2 3 2 1 1 3 3 2 1 4 2 3 3 4 3 7 1 8 0 7 6 2 1 2 6 3 8 3 1 1 1 1 1 1 2 1 9 0 6 1 2 4 8 4 6 1 1 1 3 3 3 3 1 2 1 6 0 6 1 2 2 7 1 5 3 1 3 1 1 3 2 3 5 5 3 3 2 4 6 5 3 4 3 3 5 1 6 0 11 2 1 3 1 7 1 2 4 7 3 7 1 2 3 2 1 2 1 8 0 9 8 4 9 9 4 8 9 7 1 2 1 3 1 2 3 1 3 1 6 0 8 6 2 7 5 1 5 9 5 1 1 3 1 2 2 2 5 5 3 3 3 4 1 9 0 7 1 3 3 8 9 1 8 1 3 1 1 1 1 1 3 3 1 5 0 6 1 5 6 6 5 5 1 1 2 3 2 1 8 0 9 3 4 1 7 1 8 9 4 9 2 1 1 2 3 2 2 1 3 5 4 4 3 4 1 9 0 10 6 7 2 2 5 4 6 2 1 4 3 1 1 1 3 1 1 3 2 1 7 0 8 1 8 1 5 4 4 9 4 2 3 3 2 2 2 1 1 8 0 11 1 4 2 4 7 1 1 8 9 3 1 1 1 2 3 1 3 1 1 3 3 5 1 3 7 1 7 0 7 2 6 3 7 4 1 8 2 3 1 2 3 1 1 1 7 0 8 1 2 6 8 7 4 4 1 1 1 3 2 1 3 2 1 7 0 11 4 1 3 1 3 5 6 4 3 1 4 1 1 1 1 2 1 2 3 2 2 2 4 2 1 1 4 3 4 4 3 7 1 7 0 7 7 2 5 1 3 7 9 3 3 1 2 3 2 1 1 9 0 11 3 9 4 8 4 2 1 6 8 4 5 1 3 1 3 1 3 2 2 1 1 5 0 11 7 1 9 9 1 1 6 5 9 3 1 2 3 1 2 3 3 4 2 2 2 3 3 3 5 1 7 0 9 7 4 1 8 9 5 6 3 1 1 2 3 1 3 2 2 1 6 0 7 1 3 7 6 7 3 6 2 1 3 1 1 1 1 7 0 10 9 8 1 8 9 1 5 5 2 2 3 1 3 3 2 1 1 1 2 3 2 1 3 4 1 5 0 6 1 6 6 7 4 8 2 3 1 1 3 1 5 0 9 4 6 7 1 1 1 9 5 5 1 1 2 3 2 1 5 0 8 7 1 1 2 3 3 4 3 3 1 1 1 2 1 5 2 3 3 6 1 7 0 10 6 7 9 5 1 7 5 7 7 6 3 1 2 3 1 1 1 1 7 0 6 1 5 1 1 3 8 1 1 2 2 1 1 3 1 6 0 8 4 1 9 3 2 9 2 4 2 3 1 2 1 2 3 1 1 4 1 1 3 2 1 1 5 3 3 5 1 8 0 10 3 1 7 9 4 1 6 5 1 4 1 2 1 2 1 2 2 1 1 7 0 9 9 1 1 4 2 6 4 6 3 1 1 3 1 1 3 2 1 9 0 6 9 9 8 1 1 6 3 1 2 2 1 2 3 2 2 4 5 1 3 2 3 4 1 8 0 8 2 2 9 3 5 1 6 9 2 1 1 2 2 1 3 3 1 8 0 10 1 4 3 6 5 2 3 2 1 5 3 2 2 3 1 3 1 1 1 6 0 11 6 9 5 1 5 7 3 4 6 4 7 2 1 3 2 1 2 1 3 2 1 3 5 1 5 0 11 6 7 1 5 2 8 9 1 9 8 9 3 3 1 2 2 1 5 0 9 8 8 8 1 3 9 9 8 3 1 1 1 1 1 1 9 0 6 1 1 3 7 7 7 1 2 3 1 1 2 3 3 1 1 2 3 5 3 3 5 1 5 0 10 9 5 8 1 4 6 9 9 9 1 2 3 1 3 2 1 9 0 10 5 1 1 7 8 8 7 8 2 6 1 1 1 1 2 3 3 2 3 1 6 0 6 1 6 1 5 7 6 1 1 3 3 3 2 5 3 3 1 3 3 4 1 7 0 11 2 8 5 8 1 9 4 5 2 1 1 2 1 2 3 1 2 2 1 5 0 10 8 1 1 5 4 1 7 2 9 2 1 1 3 1 3 1 7 0 10 6 4 1 7 6 2 9 1 4 9 3 1 2 1 1 1 2 5 3 3 1 1 3 2 4 3 3 7 1 9 0 9 1 7 2 7 3 6 4 6 9 3 3 1 1 1 3 1 1 2 1 9 0 6 1 2 5 3 8 8 1 1 1 2 2 1 3 2 1 1 5 0 9 6 8 1 3 2 4 6 1 9 1 2 1 3 3 5 4 2 4 4 2 3 3 5 1 8 0 6 1 3 2 6 9 5 1 3 2 1 2 1 1 3 1 6 0 8 9 2 1 5 2 1 5 1 3 2 1 2 3 1 1 8 0 6 1 1 3 5 3 2 2 3 2 1 2 3 1 1 2 4 1 3 2 3 5 1 5 0 8 3 3 4 1 5 1 5 3 3 2 1 2 1 1 6 0 9 2 4 6 1 1 5 3 7 5 1 2 2 1 1 1 1 7 0 6 4 1 1 6 8 6 3 3 1 2 2 1 1 1 5 2 1 1 3 4 1 6 0 7 3 2 3 9 1 3 6 2 1 1 3 1 1 1 5 0 8 6 6 5 6 7 2 8 1 2 1 2 3 1 1 7 0 11 2 8 6 5 6 7 1 5 6 5 1 2 3 2 3 3 1 1 4 5 2 2 5 3 1 4 4 3 4 1 8 0 7 3 1 6 3 5 2 1 2 2 1 2 3 1 1 2 1 7 0 7 1 1 5 5 1 1 5 1 1 3 1 3 1 1 1 8 0 9 4 4 3 1 9 8 9 1 1 1 3 2 1 2 2 3 3 5 4 3 5 3 7 1 9 0 11 1 8 3 4 1 5 1 6 4 3 3 1 1 3 2 2 3 2 1 3 1 5 0 9 9 7 1 6 5 4 4 6 1 1 1 3 1 2 1 7 0 11 2 9 8 8 9 7 8 2 8 1 3 1 1 1 1 3 1 2 2 2 4 5 5 2 3 3 7 1 9 0 7 5 6 1 3 8 1 8 1 2 1 2 2 1 2 2 3 1 6 0 8 8 9 7 2 8 4 3 1 3 1 2 3 3 2 1 5 0 9 6 7 2 3 3 6 1 4 7 1 1 3 2 1 1 2 2 4 2 3 3 3 5 1 9 0 10 6 7 1 2 3 9 4 1 5 6 1 2 1 1 3 3 2 1 2 1 5 0 7 2 1 9 5 7 9 6 1 3 2 2 3 1 7 0 6 1 1 1 3 7 3 1 2 3 2 2 1 1 4 1 2 5 1 2 1 5 6 5 3 7 2 4 4 3 4 1 7 0 7 6 7 6 5 9 1 4 1 1 3 1 2 1 1 1 5 0 10 9 1 8 3 7 5 7 1 2 3 1 1 1 1 2 1 5 0 7 8 5 1 8 8 3 1 2 3 1 3 3 2 5 3 1 3 7 1 8 0 9 3 4 5 2 8 1 2 1 6 3 3 3 2 1 3 2 3 1 9 0 10 8 4 2 1 8 2 1 2 5 2 2 3 2 2 1 1 1 1 2 1 6 0 6 4 4 1 3 1 4 3 2 2 1 1 1 4 3 1 2 1 2 2 3 5 1 7 0 6 1 7 5 2 9 5 1 2 2 3 3 1 1 1 8 0 9 6 3 9 2 1 7 3 6 2 2 3 1 3 2 3 1 1 1 5 0 7 1 7 2 1 3 8 8 1 1 3 3 2 2 4 2 1 5 3 4 1 9 0 6 2 3 1 9 9 1 1 2 1 2 1 3 2 2 2 1 7 0 7 1 4 3 9 1 8 8 2 1 2 1 1 1 2 1 6 0 10 7 8 3 5 7 8 4 6 1 3 3 1 1 2 1 1 4 3 3 5 6 1 3 3 5 5 3 6 1 5 0 8 8 1 1 8 4 9 2 1 1 1 3 1 2 1 7 0 11 7 7 3 3 1 5 3 2 4 5 1 2 3 2 3 2 1 2 1 8 0 8 5 6 1 5 2 1 1 1 1 1 1 1 1 3 3 3 2 2 2 1 4 1 3 4 1 6 0 10 8 8 8 4 7 6 4 1 1 9 3 1 1 1 1 3 1 7 0 7 5 2 6 4 1 3 1 1 1 3 2 2 2 3 1 9 0 9 4 3 1 8 6 8 4 2 7 3 1 2 2 1 3 2 1 1 2 2 4 1 3 4 1 5 0 7 3 6 1 1 2 3 9 2 2 2 1 1 1 9 0 7 2 3 9 9 8 8 1 1 1 2 1 1 3 2 1 3 1 7 0 10 2 6 7 5 1 9 7 8 4 3 2 2 2 1 1 3 1 2 1 1 1 3 7 1 8 0 9 2 9 2 5 1 8 1 2 2 1 1 1 1 1 1 2 3 1 6 0 9 4 1 2 5 5 7 2 4 1 3 3 3 1 1 1 1 6 0 10 3 7 5 7 3 7 1 2 2 1 1 1 3 1 1 2 2 3 5 2 2 3 2 3 4 1 6 0 10 5 9 4 9 4 4 1 7 5 6 1 2 2 2 2 1 1 6 0 11 5 6 3 3 6 2 4 4 7 1 5 2 2 2 1 1 1 1 7 0 7 6 6 1 8 4 9 2 3 1 1 1 3 2 3 2 2 3 2 7 5 5 6 2 4 4 3 4 1 9 0 9 2 1 2 7 2 2 2 9 1 3 2 3 1 2 3 3 3 2 1 9 0 9 4 7 7 1 1 8 9 9 9 2 1 1 3 2 3 2 1 1 1 8 0 11 7 6 3 9 2 7 5 5 6 1 1 3 1 1 2 1 3 2 1 5 3 2 5 3 6 1 5 0 8 3 4 2 1 1 5 1 2 1 1 1 1 1 1 7 0 7 6 9 6 2 1 4 2 2 1 3 1 3 2 1 1 5 0 6 8 7 1 4 3 5 1 1 1 2 2 3 4 2 1 4 5 3 6 1 6 0 7 4 3 7 6 8 1 4 1 3 3 3 2 3 1 5 0 7 1 1 2 4 2 6 3 1 3 1 3 1 1 7 0 7 4 7 5 1 1 9 2 1 3 3 2 2 1 2 2 2 1 1 5 2 3 7 1 5 0 9 6 4 8 1 1 1 7 1 9 2 2 1 1 2 1 6 0 6 7 1 5 7 5 1 2 3 1 1 1 1 1 7 0 6 2 6 8 4 1 8 1 1 2 1 3 3 1 4 2 1 4 3 2 3 6 1 1 2 5 4 3 6 1 5 0 7 2 7 4 4 1 8 9 3 3 2 1 2 1 8 0 6 4 2 1 9 9 9 2 3 2 1 2 3 1 2 1 7 0 7 1 2 8 6 6 3 4 3 1 1 2 1 2 2 4 4 1 2 1 3 3 6 1 8 0 11 9 1 1 9 1 6 1 7 8 3 3 3 1 3 2 1 1 3 2 1 9 0 9 1 6 7 3 7 7 1 6 1 2 2 1 2 2 1 3 1 1 1 7 0 8 6 5 1 2 9 3 9 6 1 3 1 1 1 1 1 2 2 1 5 1 2 3 4 1 8 0 11 3 2 9 8 2 8 2 6 7 1 4 1 3 3 3 3 1 3 1 1 7 0 8 1 7 1 4 2 1 5 5 1 1 2 3 1 2 1 1 7 0 9 2 1 9 5 8 2 3 9 4 1 1 3 3 3 2 3 5 1 1 1 3 6 1 6 0 8 3 7 9 4 4 1 1 9 2 1 3 3 1 3 1 6 0 9 1 1 1 3 9 2 5 5 6 3 1 2 3 1 3 1 7 0 10 9 4 3 9 1 4 7 2 5 4 2 1 1 3 1 3 1 4 2 3 4 4 4 3 4 1 5 0 11 5 7 1 6 4 9 3 9 5 8 5 1 1 1 3 3 1 5 0 11 1 6 8 1 9 7 2 8 1 9 5 2 2 1 1 1 1 8 0 7 1 9 1 9 2 1 8 1 2 1 3 1 3 3 2 1 3 1 3 2 6 3 2 5 5 3 5 1 9 0 9 1 9 2 9 8 3 1 1 5 1 3 1 1 3 3 1 1 3 1 6 0 10 4 5 7 8 2 5 1 1 1 9 1 1 2 1 3 1 1 8 0 10 9 7 7 8 4 7 5 4 6 1 1 1 2 3 3 1 3 3 5 3 1 3 3 3 7 1 8 0 11 6 5 1 7 7 3 4 8 6 4 8 3 1 2 1 2 3 1 3 1 5 0 6 1 8 4 8 3 1 1 3 1 1 1 1 6 0 8 6 6 7 2 2 5 5 1 1 1 1 3 3 1 1 3 3 5 4 3 5 3 7 1 5 0 7 2 6 9 3 1 7 3 2 2 3 3 1 1 6 0 10 2 1 9 7 2 9 7 2 9 3 1 2 2 1 1 3 1 9 0 9 5 1 4 6 4 3 4 2 5 3 3 3 1 1 2 3 2 1 2 3 1 2 4 1 3 3 4 1 5 0 9 9 4 8 4 4 1 9 6 3 1 3 1 1 2 1 9 0 6 4 3 5 1 4 4 2 1 1 2 1 1 3 1 1 1 5 0 10 4 1 2 8 9 1 7 2 9 8 3 3 3 1 3 4 1 2 4 3 6 1 9 0 9 6 4 6 4 1 8 7 2 4 3 3 2 3 1 1 1 1 2 1 6 0 10 6 2 1 4 5 2 1 4 8 1 1 2 3 1 1 2 1 9 0 10 3 1 9 3 7 9 5 3 4 2 2 2 1 3 1 1 2 2 1 1 4 3 1 4 1 1 5 7 2 4 5 5 3 7 1 5 0 9 4 1 1 5 3 6 9 6 7 1 3 2 1 1 1 5 0 6 1 6 8 1 4 1 3 3 1 3 1 1 5 0 7 2 4 1 6 1 3 4 1 1 3 2 1 5 1 5 5 3 4 1 3 5 1 8 0 7 8 2 6 1 6 7 6 1 1 2 3 3 2 1 2 1 7 0 6 8 1 2 1 5 8 1 2 2 3 1 3 3 1 7 0 11 8 9 4 5 6 6 1 8 6 5 2 1 1 2 1 1 2 2 2 5 4 1 1 3 5 1 8 0 8 1 8 1 3 5 5 8 2 3 2 2 2 3 1 1 1 1 7 0 7 6 8 6 2 1 3 2 3 1 1 1 1 2 1 1 5 0 6 1 7 6 9 1 8 3 1 3 1 2 1 3 4 1 1 3 6 1 8 0 11 1 9 3 1 4 7 3 4 1 3 8 1 2 1 2 2 2 1 3 1 5 0 10 7 6 1 7 4 1 3 4 8 1 3 2 3 1 1 1 6 0 9 7 4 7 2 5 1 3 8 2 2 2 2 3 1 2 1 4 2 1 1 5 3 4 1 7 0 7 8 5 7 1 9 2 1 1 1 2 1 1 1 2 1 6 0 6 3 1 1 4 6 6 1 2 3 1 3 3 1 8 0 10 4 1 1 6 1 5 1 3 1 2 1 1 1 2 2 2 2 1 4 4 3 1 4 2 6 6 4 5 5 3 5 1 5 0 10 2 1 4 4 9 8 3 8 3 7 3 3 1 2 3 1 5 0 8 4 6 4 9 2 6 1 3 2 1 1 3 3 1 5 0 10 3 7 4 5 9 3 1 7 1 9 3 2 1 3 1 3 2 1 3 5 3 4 1 6 0 8 6 2 2 7 4 4 3 1 1 2 1 3 2 1 1 7 0 10 1 6 2 2 9 6 8 8 8 6 1 2 3 3 2 3 3 1 5 0 11 4 3 7 1 3 5 4 7 9 9 1 1 2 2 3 1 3 3 1 2 3 7 1 9 0 11 9 2 4 1 5 6 3 1 6 3 5 2 2 3 2 3 1 1 2 1 1 7 0 8 6 1 1 6 8 8 8 6 3 1 1 2 2 2 1 1 7 0 6 3 5 1 5 5 7 3 1 1 1 1 1 1 3 1 1 1 5 2 5 3 7 1 5 0 9 9 4 9 1 5 1 7 3 3 2 2 1 2 2 1 6 0 8 4 8 4 3 1 5 7 5 1 1 1 2 1 3 1 8 0 10 3 7 1 2 7 8 7 7 1 9 3 2 1 2 2 1 1 3 1 3 4 1 3 1 4 3 4 1 7 0 7 4 2 8 1 7 8 1 2 1 1 1 2 1 3 1 7 0 7 5 2 1 4 3 4 5 3 3 3 1 2 2 3 1 8 0 8 8 6 1 6 9 3 7 5 1 3 1 1 1 3 3 1 2 2 1 4 4 4 5 6 2 6 6 6 2 4 3 3 6 1 9 0 9 1 6 7 5 5 6 9 6 1 3 2 3 1 2 2 3 3 3 1 7 0 11 6 9 1 6 2 3 9 4 8 9 2 1 2 2 1 1 3 1 1 6 0 7 2 3 1 7 6 1 3 3 1 3 1 3 3 2 1 3 4 3 3 3 4 1 7 0 11 8 2 3 3 8 7 7 6 9 3 1 3 1 1 3 3 3 3 1 6 0 10 1 5 1 2 8 5 9 7 7 5 2 1 1 2 3 3 1 5 0 11 4 3 7 3 7 5 2 1 4 6 4 1 1 2 2 2 1 5 5 5 3 6 1 6 0 7 9 8 2 9 5 9 1 1 3 3 1 3 3 1 6 0 9 2 4 5 5 3 8 2 5 1 1 2 2 1 1 3 1 6 0 8 9 6 1 9 2 1 2 1 1 1 2 3 1 1 2 2 5 5 1 1 3 5 1 5 0 9 4 4 7 6 6 1 1 1 1 3 3 1 3 2 1 8 0 11 8 3 2 4 4 5 1 1 2 4 5 1 1 1 2 2 1 1 2 1 6 0 11 3 4 1 3 5 2 3 1 6 8 8 1 1 3 1 2 3 3 5 1 2 4 2 6 3 5 3 3 5 1 7 0 11 1 6 3 1 1 6 2 5 4 6 6 1 1 2 3 3 1 3 1 7 0 8 3 2 5 1 4 4 6 8 3 2 3 3 2 1 1 1 7 0 7 4 1 9 2 1 1 7 1 1 1 3 2 3 2 2 5 2 4 1 3 5 1 7 0 6 6 1 2 1 9 8 1 2 2 3 2 2 1 1 9 0 7 1 4 3 6 3 2 1 1 3 1 3 1 1 2 3 2 1 5 0 7 5 2 1 3 8 9 9 3 1 1 3 3 3 1 3 5 2 3 7 1 5 0 8 2 9 1 7 6 3 3 3 3 1 2 2 3 1 7 0 6 1 6 5 4 6 2 1 1 3 2 1 3 1 1 6 0 11 5 9 1 3 2 1 1 3 4 8 8 1 1 1 2 3 1 1 2 1 4 1 4 2 3 4 1 8 0 8 9 9 9 3 8 1 4 1 1 3 1 3 3 3 3 1 1 7 0 11 1 2 2 4 3 9 1 6 9 8 3 1 1 1 2 1 1 1 1 7 0 9 8 2 2 1 7 4 8 7 8 1 2 1 2 1 1 1 1 3 3 1 3 4 1 9 0 10 2 3 6 4 9 4 6 1 1 1 3 3 3 1 3 1 1 2 1 1 8 0 10 9 7 1 1 1 4 2 3 1 5 2 3 1 2 1 1 2 1 1 7 0 10 2 6 1 3 5 5 1 6 1 5 1 1 3 2 1 2 3 1 5 1 2 7 2 4 5 3 3 4 1 8 0 11 1 4 5 1 2 3 5 5 6 2 3 1 1 3 1 1 1 2 1 1 9 0 10 5 2 9 1 4 6 8 9 4 4 3 1 2 1 1 2 3 1 3 1 8 0 6 6 3 7 2 4 1 1 1 1 1 2 2 1 1 3 1 5 1 3 7 1 9 0 9 1 5 3 5 6 4 1 3 9 1 1 3 1 1 3 1 3 1 1 8 0 6 5 9 8 2 1 9 2 1 3 3 2 1 1 2 1 8 0 8 2 1 3 5 2 9 6 1 2 3 1 1 3 1 1 3 4 5 2 1 2 2 2 3 4 1 8 0 6 9 9 5 1 3 1 1 1 3 2 1 1 1 1 1 7 0 8 5 4 9 8 9 7 9 1 3 1 2 2 1 2 3 1 6 0 9 6 1 9 7 5 7 4 5 7 1 3 1 3 2 3 3 3 1 3 3 6 1 8 0 7 1 4 7 1 9 8 6 1 1 3 2 2 3 2 1 1 7 0 8 8 6 9 3 1 7 8 9 3 1 2 3 2 2 2 1 8 0 9 1 8 6 9 8 2 4 9 8 1 2 2 1 1 3 3 3 1 3 2 1 2 1 3 5 1 7 0 7 1 6 2 1 3 7 4 3 2 1 1 1 3 2 1 9 0 9 1 1 1 1 2 5 9 4 5 3 2 1 2 1 3 1 1 3 1 7 0 7 1 3 9 4 5 8 6 1 2 2 3 1 2 3 1 4 2 4 1 4 1 5 5 5 3 7 1 6 0 8 1 1 3 7 4 6 5 8 1 2 3 1 1 1 1 7 0 6 7 7 3 2 8 1 3 3 1 2 1 1 3 1 8 0 10 2 4 1 8 2 8 8 1 1 6 3 1 1 1 1 2 1 3 1 2 3 5 5 3 1 3 6 1 6 0 10 9 3 6 9 2 3 9 1 2 4 1 1 2 3 3 3 1 9 0 8 8 4 7 8 2 1 2 8 3 2 2 3 3 1 3 1 2 1 7 0 9 9 1 6 7 6 5 1 1 4 2 1 2 2 3 1 1 2 3 3 2 3 3 3 5 1 9 0 11 1 1 3 6 6 7 9 3 1 5 8 1 1 1 2 3 1 1 3 2 1 9 0 7 1 9 6 6 4 2 1 1 1 3 1 3 3 1 3 3 1 5 0 11 5 3 1 2 6 3 6 6 9 9 6 1 3 2 1 1 1 3 1 2 5 3 5 1 5 0 8 8 6 7 1 8 6 6 4 1 2 3 1 2 1 5 0 9 9 9 3 7 9 6 4 1 4 1 1 3 1 1 1 7 0 9 3 5 7 9 1 7 9 2 5 1 2 1 2 3 1 3 1 1 4 1 5 3 4 1 7 0 7 4 8 4 1 6 4 9 1 1 1 1 1 2 3 1 8 0 10 4 3 6 5 3 8 3 1 3 1 1 3 2 2 1 2 2 3 1 5 0 10 6 8 4 1 1 1 7 9 1 1 2 1 1 2 1 1 3 3 5 5 4 2 4 2 4 4 3 5 1 9 0 9 4 1 5 3 8 5 5 4 1 3 3 2 2 3 3 3 1 2 1 8 0 10 3 5 1 1 3 6 7 8 8 2 2 2 3 3 2 1 1 2 1 9 0 6 3 1 5 3 6 1 3 3 1 1 1 3 2 3 2 3 2 2 5 1 3 7 1 5 0 9 5 1 8 2 5 1 4 9 9 1 1 2 1 2 1 5 0 7 6 6 1 8 3 4 1 3 2 2 1 1 1 8 0 10 8 1 2 7 8 1 7 6 6 8 1 1 2 1 2 1 1 3 2 2 2 1 5 4 1 3 5 1 7 0 10 9 5 5 7 8 1 5 5 6 5 3 1 1 1 3 1 1 1 5 0 10 2 9 1 9 6 1 1 8 4 8 2 1 1 3 1 1 6 0 8 4 4 1 4 4 8 1 6 2 2 1 3 3 3 2 3 3 4 3 3 4 1 6 0 7 5 9 5 9 1 9 7 1 1 2 2 1 1 1 7 0 6 4 3 1 3 3 5 1 2 1 1 2 1 1 1 6 0 7 2 4 1 7 1 8 2 1 2 2 1 1 2 3 2 3 1 1 5 5 3 4 4 3 7 1 6 0 11 1 1 3 5 6 6 5 1 9 1 6 3 1 3 2 1 1 1 7 0 7 1 6 9 5 1 5 5 2 2 2 1 1 1 2 1 7 0 9 9 4 9 1 4 2 2 6 8 2 2 1 1 3 2 1 5 1 5 3 3 1 4 3 6 1 6 0 7 9 9 7 9 1 6 3 1 2 1 1 3 3 1 8 0 6 1 1 5 8 4 6 1 1 3 3 2 1 3 3 1 9 0 6 1 1 5 1 1 3 2 2 1 1 2 1 3 2 1 4 3 1 1 3 2 3 7 1 6 0 6 4 1 6 1 1 5 1 2 3 2 1 1 1 9 0 6 7 3 1 8 8 8 2 1 2 2 1 1 2 2 1 1 6 0 9 6 7 2 6 1 1 6 7 9 1 3 2 2 2 2 4 3 4 1 3 1 5 3 4 1 9 0 7 8 1 4 8 1 9 6 3 3 1 3 2 2 1 3 1 1 8 0 11 3 3 8 1 3 8 4 1 2 6 1 1 3 1 2 3 1 1 2 1 5 0 11 3 4 7 9 5 9 4 5 1 8 7 1 2 1 2 2 1 3 4 2 1 6 6 4 4 7 7 2 4 5 3 4 1 8 0 11 6 2 5 3 5 8 2 2 1 1 6 3 1 2 1 2 2 1 3 1 7 0 9 1 7 6 7 4 1 4 9 9 1 2 1 2 1 1 1 1 5 0 10 9 7 8 4 1 2 2 4 1 1 3 1 3 3 1 3 3 2 3 3 4 1 8 0 7 2 3 8 1 9 7 1 1 3 1 1 3 3 1 3 1 9 0 7 1 9 9 8 1 1 9 3 3 2 2 3 1 2 1 1 1 7 0 11 1 1 5 7 8 3 2 4 8 8 3 1 2 1 1 1 2 2 1 1 4 3 3 4 1 7 0 7 9 4 2 1 9 1 3 2 1 3 2 3 1 2 1 7 0 6 6 2 1 1 8 8 1 3 3 2 1 2 1 1 9 0 10 1 7 8 3 1 3 1 6 4 9 2 2 1 3 1 3 1 1 3 2 4 1 3 3 6 1 5 0 9 5 4 2 7 7 1 1 1 2 2 1 1 1 1 1 8 0 7 1 4 4 3 2 7 3 3 2 2 1 3 3 1 1 1 9 0 9 4 8 6 1 6 2 8 9 7 3 3 1 2 1 1 1 3 3 3 5 2 5 1 1 2 6 4 6 6 4 3 3 5 1 7 0 8 1 8 5 7 4 1 9 5 2 3 3 3 3 2 1 1 8 0 10 6 5 9 5 9 1 1 6 1 4 1 1 3 2 3 1 2 3 1 8 0 7 1 4 7 4 5 8 8 1 1 1 1 2 2 3 3 3 3 3 1 1 3 5 1 6 0 7 4 1 9 6 7 7 6 1 2 1 2 2 1 1 5 0 11 5 3 1 1 1 5 2 8 3 5 5 1 2 3 1 2 1 5 0 9 5 3 3 2 6 7 5 1 1 1 1 2 1 3 1 4 2 2 1 3 6 1 9 0 10 9 2 2 8 1 7 4 4 7 8 1 2 2 1 3 1 2 2 3 1 9 0 9 6 7 3 1 4 6 6 7 4 3 2 1 1 1 3 2 3 1 1 5 0 10 6 7 4 4 8 6 1 7 3 3 2 2 2 1 3 1 5 5 1 1 2 3 7 1 7 0 8 3 6 1 4 8 6 3 9 1 1 2 1 1 2 1 1 7 0 9 2 5 2 7 4 2 7 5 1 1 2 1 3 3 1 2 1 9 0 7 4 2 3 3 1 8 4 3 3 1 1 3 1 1 2 3 1 1 1 2 3 2 5 3 2 2 4 4 3 7 1 6 0 8 9 3 1 1 6 3 3 7 1 2 3 3 1 2 1 7 0 11 7 6 6 2 1 2 6 3 5 4 1 1 1 1 1 2 1 1 1 9 0 6 4 1 5 1 5 8 3 1 2 3 1 2 1 1 2 4 5 2 3 4 2 4 3 7 1 5 0 10 4 2 6 5 1 1 5 1 4 4 1 1 2 1 1 1 5 0 8 6 8 9 6 9 6 1 5 2 1 2 2 3 1 5 0 9 6 7 9 8 6 5 1 3 5 1 2 1 3 1 2 1 4 4 3 3 2 3 7 1 7 0 8 8 5 1 9 1 9 1 4 1 1 3 2 2 1 1 1 6 0 10 1 7 3 2 1 5 7 2 7 5 1 2 2 3 1 1 1 5 0 11 8 2 4 2 1 7 4 1 3 2 6 1 2 2 3 3 2 1 3 4 2 1 3 3 6 1 7 0 10 4 9 6 2 1 6 8 5 6 1 1 2 3 2 1 1 1 1 7 0 7 8 7 7 4 1 5 2 1 1 2 1 1 1 1 1 6 0 6 3 2 2 5 1 4 3 2 2 3 1 3 3 2 5 4 4 5 3 2 6 1 5 4 3 5 1 9 0 8 7 1 5 8 6 5 1 4 2 1 3 1 2 1 2 1 2 1 8 0 8 6 2 1 1 4 3 7 2 2 3 1 1 2 1 2 1 1 5 0 9 3 7 7 2 1 6 7 8 1 1 1 2 2 3 4 1 4 2 2 3 5 1 5 0 9 1 8 3 4 5 1 1 1 4 3 2 1 2 3 1 9 0 11 6 1 4 2 6 4 6 5 7 2 2 3 1 1 3 3 3 3 2 1 1 5 0 8 4 9 1 4 4 4 5 9 1 1 3 3 1 2 4 2 1 5 3 7 1 5 0 10 6 2 1 9 7 1 6 4 4 2 2 1 1 2 3 1 9 0 7 6 4 1 6 5 6 9 1 1 1 2 3 1 2 2 1 1 9 0 6 1 2 1 4 7 4 2 2 1 2 1 2 3 2 2 3 4 1 5 1 5 5 3 6 1 6 0 7 3 7 4 9 3 4 1 1 2 2 3 3 1 1 5 0 10 5 4 7 6 2 2 1 9 8 4 1 1 3 1 2 1 6 0 10 8 4 6 1 1 7 9 6 5 6 3 2 1 3 3 2 1 1 2 5 3 2 3 4 1 6 0 10 5 9 1 4 8 7 2 2 4 2 2 3 3 2 1 1 1 8 0 10 1 6 2 7 4 6 1 3 1 4 3 2 1 3 3 1 3 3 1 8 0 9 3 1 8 7 8 2 1 7 8 1 2 2 1 1 1 2 1 4 2 3 4 1 3 2 2 5 3 3 7 1 6 0 8 9 7 1 3 6 2 1 6 1 1 1 1 1 1 1 6 0 6 1 1 5 3 4 4 1 1 3 3 1 3 1 8 0 7 1 2 9 5 4 6 1 1 1 3 3 1 1 1 2 5 2 5 5 5 5 2 3 5 1 9 0 9 7 6 9 4 1 7 6 6 5 3 2 1 3 2 1 1 1 1 1 7 0 9 1 3 7 4 9 5 4 6 5 3 2 3 3 3 1 2 1 6 0 11 3 6 6 1 9 7 8 7 5 6 1 3 1 1 2 1 1 5 1 1 2 4 3 6 1 9 0 7 5 3 4 1 8 3 9 2 1 3 3 1 3 3 3 3 1 6 0 9 9 1 4 1 9 1 1 4 3 1 2 1 2 2 3 1 5 0 6 4 9 4 9 3 1 1 1 1 1 1 1 4 3 1 3 3 3 6 1 9 0 11 7 4 9 2 7 1 6 6 4 7 1 2 1 2 1 2 1 2 2 3 1 9 0 9 7 9 1 6 1 6 9 7 5 1 3 1 2 2 3 3 1 2 1 6 0 8 3 2 1 5 8 6 5 1 1 2 1 3 1 1 2 3 5 2 2 3 3 4 1 8 0 6 1 9 1 8 2 7 2 3 2 1 1 2 3 2 1 5 0 11 6 6 5 3 7 5 6 3 6 5 1 1 1 1 2 2 1 5 0 11 2 8 3 4 6 1 4 2 1 1 8 1 1 1 2 2 2 1 5 1 4 4 5 4 3 3 6 1 6 0 9 9 7 8 4 9 1 9 9 3 3 3 2 3 2 1 1 7 0 9 8 9 1 7 5 7 9 1 7 3 3 3 1 3 1 1 1 9 0 7 5 5 6 2 1 5 8 1 2 3 1 1 3 2 1 1 5 5 2 3 2 5 3 5 1 7 0 10 4 3 1 8 1 9 3 4 9 3 1 1 2 2 3 1 3 1 8 0 7 7 1 2 7 1 7 8 1 3 1 2 1 3 1 1 1 9 0 11 1 5 6 3 2 1 1 5 1 2 3 2 1 1 1 3 1 3 2 3 3 1 3 1 2 3 6 1 9 0 9 1 1 9 1 3 9 9 7 5 3 3 3 2 1 1 1 3 2 1 5 0 9 6 4 9 1 5 9 7 4 6 1 3 2 1 1 1 7 0 6 8 2 3 1 8 8 1 2 1 1 2 3 2 1 3 1 4 3 5 3 5 1 6 0 7 4 9 8 1 1 6 9 3 1 3 2 1 1 1 9 0 9 9 2 1 4 7 2 7 4 3 2 2 1 1 3 3 1 1 1 1 8 0 10 9 9 8 1 5 6 1 9 5 1 3 3 3 2 3 3 1 2 4 1 5 3 5 4 1 5 5 5 3 6 1 7 0 7 2 1 2 5 4 3 3 2 3 2 3 1 2 1 1 5 0 10 7 9 4 9 2 4 1 9 4 2 2 2 1 1 1 1 5 0 7 1 5 1 1 2 6 3 3 3 2 1 2 5 1 3 3 1 2 3 6 1 6 0 10 2 5 1 6 1 4 8 5 1 5 2 1 2 1 2 2 1 6 0 11 1 5 2 5 8 3 2 3 4 1 3 1 2 2 2 1 1 1 6 0 10 4 9 9 5 8 1 7 8 6 8 1 1 3 2 1 1 1 2 5 3 1 5 3 5 1 8 0 8 9 8 1 4 9 7 7 5 3 1 2 2 1 3 3 3 1 9 0 7 7 5 7 1 4 9 1 3 3 3 2 2 1 1 3 3 1 6 0 10 2 1 1 4 1 4 7 4 3 7 3 2 1 3 1 3 3 1 3 2 3 3 5 1 5 0 8 6 1 1 1 2 8 9 8 1 2 1 2 2 1 7 0 9 6 1 5 9 6 8 6 5 4 2 1 3 3 1 3 1 1 5 0 7 5 4 3 3 1 3 5 2 3 1 3 1 2 1 1 1 3 3 6 1 7 0 6 1 9 9 6 3 1 1 1 1 3 2 2 2 1 5 0 8 3 9 2 1 3 1 1 2 1 1 1 1 1 1 6 0 9 8 6 3 2 4 1 3 6 9 3 1 2 1 2 3 5 2 5 5 1 1 4 2 1 2 2 9 5 6 3 5 4 3 7 1 9 0 10 6 5 6 2 3 6 8 8 9 1 1 1 3 3 2 3 1 1 2 1 7 0 11 2 3 4 4 2 6 1 1 2 9 2 2 2 1 2 3 1 2 1 8 0 11 3 1 1 1 2 6 9 1 5 4 5 3 1 3 1 1 3 1 1 3 4 1 3 1 4 3 3 6 1 6 0 10 4 4 2 1 4 4 7 7 1 1 1 1 1 1 3 2 1 9 0 8 5 4 2 1 3 6 4 1 1 2 3 1 1 2 3 2 3 1 9 0 11 6 4 3 3 5 7 1 5 9 3 7 3 1 1 2 3 1 1 2 3 5 1 1 2 4 2 3 6 1 7 0 8 1 5 1 6 3 7 2 6 3 2 2 2 2 1 2 1 7 0 11 8 1 8 8 4 4 3 5 4 6 1 2 1 1 3 1 1 2 1 5 0 7 8 6 3 1 4 3 1 2 2 1 1 1 2 1 4 4 4 3 3 4 1 9 0 10 2 8 1 1 1 1 2 7 6 2 2 1 1 2 2 3 2 1 3 1 8 0 10 1 6 8 7 6 5 8 9 8 1 1 1 3 2 3 1 2 1 1 9 0 8 1 3 4 1 1 7 4 8 2 1 1 3 3 1 1 1 2 4 1 1 2 3 4 1 7 0 10 8 8 4 7 1 5 9 5 8 7 1 1 1 1 1 1 2 1 9 0 8 4 1 1 6 2 8 6 3 2 1 3 1 3 1 2 1 1 1 5 0 11 1 9 9 4 7 9 7 6 3 9 9 3 3 1 1 3 4 2 2 5 7 2 4 4 4 3 3 7 1 7 0 10 2 2 3 8 1 3 9 1 9 8 3 1 1 1 1 1 2 1 8 0 7 1 1 1 5 3 4 4 3 1 2 1 1 2 2 1 1 8 0 11 4 1 8 5 1 1 7 1 4 4 6 1 2 1 1 2 3 1 2 1 2 2 5 2 2 4 3 4 1 5 0 10 2 5 4 2 2 5 3 1 4 3 2 1 3 3 3 1 8 0 7 7 1 8 7 7 7 6 1 1 3 2 2 3 1 3 1 6 0 11 6 7 2 3 2 2 1 8 9 3 7 1 2 3 1 3 2 2 2 5 3 3 5 1 5 0 7 9 2 1 9 2 6 9 2 2 1 1 1 1 5 0 6 1 7 1 7 5 4 3 1 1 2 3 1 5 0 9 6 1 5 9 3 8 2 1 4 1 3 3 1 1 1 5 2 3 3 3 6 1 7 0 11 5 3 8 9 1 6 6 5 4 4 6 1 2 1 1 3 2 2 1 6 0 8 1 8 6 6 1 1 2 9 2 1 1 1 1 3 1 7 0 6 8 2 1 6 1 2 1 3 1 2 2 1 3 5 3 3 1 1 3 5 2 2 5 4 3 4 1 9 0 6 1 1 8 7 1 5 3 2 3 1 3 2 1 3 1 1 7 0 8 8 1 6 3 5 8 6 2 1 2 1 2 1 2 2 1 9 0 6 2 1 4 7 5 9 3 2 1 2 1 3 3 3 2 1 2 4 3 3 7 1 6 0 8 1 9 3 2 5 7 3 7 2 1 1 3 2 2 1 9 0 11 5 5 4 1 2 8 5 5 2 7 6 1 3 3 1 3 3 3 1 2 1 7 0 7 4 3 9 9 1 6 5 2 1 3 3 3 2 1 5 3 2 3 1 2 3 3 4 1 7 0 7 9 7 9 1 1 9 5 1 1 2 3 2 1 1 1 7 0 6 1 3 7 6 6 3 3 3 1 1 1 2 2 1 9 0 11 4 8 2 7 5 3 1 7 1 8 1 1 3 2 1 2 2 1 3 1 4 2 3 3 3 4 1 9 0 11 7 9 6 1 8 1 5 2 7 5 7 1 3 1 2 1 2 2 1 1 1 7 0 6 2 8 6 5 1 6 3 2 2 1 3 2 2 1 5 0 10 1 7 4 2 8 6 9 7 4 2 3 2 2 1 3 2 3 3 2 3 6 1 7 0 8 4 8 1 1 5 3 7 8 1 1 1 1 3 2 1 1 8 0 9 3 7 6 2 6 5 1 1 7 3 2 3 2 1 2 3 3 1 7 0 8 7 4 6 8 2 8 3 1 1 2 2 3 2 3 1 5 4 1 3 2 4 5 4 2 6 4 5 3 7 1 5 0 8 7 3 9 1 5 5 6 3 2 1 1 3 2 1 5 0 6 1 1 4 3 6 3 1 3 1 1 2 1 6 0 7 3 9 1 5 9 9 3 3 1 2 3 1 1 4 3 2 5 2 5 4 3 7 1 9 0 10 2 1 6 7 4 8 4 7 6 1 2 2 1 3 3 1 2 2 3 1 7 0 9 1 7 6 1 8 6 3 1 3 1 1 1 1 3 1 1 1 8 0 9 7 7 8 5 8 1 1 1 5 3 1 1 1 3 2 3 3 3 3 2 1 5 2 3 3 6 1 5 0 7 3 3 1 4 5 5 5 1 2 3 3 1 1 5 0 9 1 3 5 1 9 1 1 7 2 2 1 2 2 2 1 7 0 9 4 6 1 5 6 3 5 2 4 2 1 1 2 3 2 1 3 2 2 4 3 2 3 4 1 6 0 7 5 2 1 5 1 9 5 3 1 3 1 1 1 1 9 0 8 1 1 1 7 1 2 6 5 3 3 1 1 1 1 3 2 2 1 8 0 8 1 5 5 9 1 6 2 5 1 3 2 1 3 3 2 1 4 4 3 1 1 2 4 6 6 5 3 3 4 1 9 0 11 7 6 8 2 9 8 9 8 4 1 3 1 2 1 1 1 3 3 2 2 1 9 0 11 3 2 9 1 1 3 5 3 7 9 8 2 1 2 2 1 3 3 1 3 1 8 0 7 1 8 4 5 9 8 4 1 3 2 1 1 1 3 1 2 5 1 2 3 7 1 8 0 8 3 1 3 4 1 3 3 8 3 2 1 2 2 1 1 2 1 5 0 9 1 2 8 6 4 4 6 6 6 3 1 3 3 1 1 7 0 8 9 1 1 9 7 2 9 7 3 3 2 2 1 1 3 3 3 2 1 4 3 3 3 5 1 5 0 10 6 3 1 6 7 7 2 6 5 7 2 3 1 3 1 1 6 0 7 7 4 6 3 7 1 3 3 2 2 1 1 3 1 9 0 11 7 2 6 1 1 6 8 8 2 6 6 1 2 2 1 1 3 1 3 1 4 1 5 4 1 3 7 1 8 0 11 2 2 1 7 1 7 2 4 6 1 5 3 2 3 1 2 3 2 3 1 5 0 11 8 5 6 9 2 5 3 3 3 6 1 1 3 1 3 3 1 5 0 8 7 1 9 9 4 4 9 1 2 3 3 3 1 4 3 4 2 1 5 1 3 7 1 9 0 9 8 1 7 9 9 5 5 3 5 3 1 3 3 3 1 1 1 3 1 9 0 9 5 3 3 6 1 2 1 8 2 2 3 2 1 3 3 2 3 1 1 7 0 10 6 1 5 7 4 6 4 6 6 3 1 3 1 1 2 3 2 5 2 1 1 2 2 1 3 3 2 5 5 3 4 1 5 0 9 8 9 5 5 1 2 8 4 3 1 3 3 1 1 1 6 0 7 6 1 5 6 2 5 7 3 1 3 1 1 1 1 6 0 11 5 1 1 7 7 4 5 6 3 4 2 3 1 3 1 1 2 5 3 2 1 3 6 1 7 0 10 9 7 1 1 4 3 5 1 5 2 1 2 2 2 2 3 1 1 7 0 8 9 1 3 6 6 1 4 9 1 1 2 2 3 1 1 1 7 0 9 9 4 1 6 5 2 7 1 5 2 1 3 1 2 2 1 1 3 1 1 1 3 3 5 1 5 0 7 1 9 2 3 2 9 2 2 1 1 2 2 1 5 0 9 4 1 6 1 4 2 3 8 3 3 3 2 1 1 1 5 0 10 9 1 6 4 8 5 7 1 7 4 2 3 1 2 1 2 3 2 1 4 3 4 1 9 0 9 8 1 8 8 7 2 7 7 1 2 2 3 3 1 1 1 1 3 1 7 0 11 5 8 3 1 5 1 3 1 2 3 1 3 1 1 1 1 2 1 1 9 0 6 1 8 3 8 1 7 3 1 3 1 1 2 1 2 3 1 5 2 3 3 5 1 5 0 11 3 8 2 5 4 5 1 2 2 3 1 1 1 3 3 2 1 8 0 9 2 7 1 1 3 1 7 2 5 2 1 2 1 3 2 1 3 1 9 0 11 9 1 8 4 2 8 1 6 1 5 5 3 1 2 2 1 1 2 1 3 4 3 1 5 1 7 4 2 1 2 1 3 1 7 2 4 4 3 5 1 5 0 6 7 1 1 4 6 4 3 3 1 1 1 1 6 0 11 1 3 5 8 4 8 7 1 2 3 2 3 1 1 1 2 3 1 7 0 10 3 1 3 1 7 1 4 1 2 5 1 1 3 3 3 2 1 5 5 1 5 1 3 7 1 8 0 11 9 1 7 1 5 2 5 3 1 8 4 1 3 3 2 3 2 3 1 1 7 0 8 7 3 4 5 8 4 1 4 2 1 2 1 1 1 2 1 7 0 9 3 1 3 9 5 5 1 9 7 3 3 1 2 1 1 2 2 3 1 1 1 4 4 3 7 1 5 0 7 7 9 1 6 2 1 1 3 3 3 3 1 1 7 0 7 5 8 1 8 8 1 9 1 1 1 3 1 1 2 1 9 0 6 9 9 7 4 1 1 2 1 1 2 1 3 2 1 3 5 2 2 1 2 5 2 3 6 1 7 0 11 1 7 3 1 4 3 6 4 2 7 7 3 1 3 1 3 1 1 1 6 0 10 2 1 9 7 4 8 6 6 2 6 1 3 1 1 2 3 1 5 0 6 4 2 3 1 7 8 1 2 2 3 1 2 3 3 5 1 1 4 2 2 3 5 4 3 4 1 7 0 9 9 2 6 2 2 8 4 8 1 2 1 3 3 2 3 3 1 8 0 7 1 2 8 6 9 4 6 2 1 1 3 2 1 3 1 1 5 0 9 2 3 9 7 1 8 1 9 3 2 2 2 3 1 2 4 1 3 3 5 1 8 0 7 5 1 1 9 7 8 6 1 1 2 3 2 1 3 1 1 9 0 6 8 9 1 7 3 8 2 2 3 3 1 3 1 2 3 1 8 0 8 5 8 4 1 3 1 4 4 1 3 3 1 2 3 1 3 2 3 4 2 2 3 4 1 9 0 10 4 1 1 2 1 7 7 2 5 7 1 3 1 1 2 3 3 2 3 1 7 0 10 2 1 4 1 5 2 2 7 9 5 1 1 3 2 2 2 1 1 9 0 7 8 1 1 8 6 5 1 1 3 1 3 1 2 2 2 1 2 3 2 4 3 4 1 8 0 9 3 6 1 9 1 6 7 7 7 1 2 1 2 3 1 3 1 1 8 0 11 5 3 1 2 7 6 6 8 9 1 6 3 3 3 1 1 2 2 3 1 7 0 11 3 6 1 2 1 4 5 7 9 3 1 2 3 3 3 1 1 2 2 3 4 2 3 6 1 9 0 9 1 1 5 4 8 7 5 6 8 1 1 3 3 3 1 1 2 1 1 6 0 8 3 9 1 9 8 7 1 2 2 3 1 2 1 2 1 5 0 6 8 1 1 4 6 8 1 1 1 1 1 5 4 2 1 2 2 4 5 1 1 5 5 3 6 1 9 0 9 1 6 8 3 6 4 1 9 1 3 3 3 3 1 1 1 3 1 1 5 0 9 5 2 5 6 2 6 3 5 1 3 1 1 3 1 1 5 0 8 2 8 1 8 8 2 4 1 3 1 2 2 2 5 2 5 3 3 2 3 5 1 5 0 7 3 9 5 4 1 4 9 1 1 3 1 3 1 5 0 7 5 5 1 5 1 4 3 2 1 2 1 1 1 6 0 6 6 3 1 9 3 1 3 1 3 2 2 3 2 3 2 4 3 3 7 1 5 0 9 1 9 5 2 3 6 7 1 1 3 1 3 2 1 1 9 0 6 1 5 6 2 7 6 3 1 2 3 3 1 2 1 2 1 6 0 6 4 5 4 9 6 1 3 3 1 1 3 2 1 5 2 5 4 4 1 3 6 1 7 0 7 8 1 6 6 1 4 4 3 2 1 1 1 2 1 1 5 0 10 6 4 4 7 8 7 1 3 9 7 1 1 3 2 3 1 8 0 7 1 3 9 6 3 2 4 1 2 3 2 3 3 1 2 1 3 2 2 1 3 3 7 1 6 0 6 1 3 7 1 2 3 2 2 1 3 1 1 1 8 0 11 8 7 4 7 7 1 3 8 3 5 1 2 1 2 3 1 1 1 2 1 9 0 6 9 3 1 2 5 2 3 2 3 3 3 3 2 1 2 2 3 1 5 5 3 1 2 6 1 4 3 5 5 3 6 1 8 0 11 9 4 3 2 7 2 6 8 7 1 5 3 1 1 1 1 1 2 2 1 6 0 11 5 4 3 2 1 6 8 7 3 1 3 2 1 1 3 2 3 1 6 0 10 3 1 8 4 4 1 4 9 8 1 2 2 2 1 2 3 2 2 3 3 4 2 3 4 1 7 0 6 5 8 6 9 1 7 1 3 3 1 2 2 1 1 7 0 7 2 5 7 1 2 7 1 1 2 2 1 2 2 2 1 7 0 10 9 4 7 1 9 2 3 2 2 6 2 1 3 1 1 2 1 4 4 1 5 3 4 1 9 0 9 1 3 5 4 1 1 1 6 2 3 1 1 3 1 3 1 2 1 1 9 0 10 1 5 1 2 3 8 7 1 6 4 1 2 2 1 3 1 1 3 2 1 6 0 8 1 9 3 5 3 7 2 5 2 1 1 1 1 3 2 5 2 4 3 4 1 6 0 11 6 5 5 7 1 4 6 4 3 8 1 1 1 2 1 2 1 1 8 0 9 4 1 6 9 3 9 7 6 2 1 1 1 2 1 1 1 1 1 5 0 6 4 5 1 7 2 9 3 2 2 1 1 2 2 3 4 3 5 1 6 0 8 7 2 1 9 2 1 7 9 1 1 3 3 3 2 1 9 0 11 4 7 9 1 6 4 1 1 9 5 8 1 1 2 2 3 3 3 1 1 1 9 0 7 6 3 5 9 1 2 3 2 2 3 3 2 2 1 3 2 3 2 5 3 1 5 2 4 4 2 4 3 3 4 1 6 0 6 4 1 9 8 9 2 1 3 1 2 2 2 1 7 0 6 3 2 7 1 9 7 3 1 1 2 2 1 3 1 5 0 9 4 5 2 8 1 8 4 4 3 1 2 1 2 1 4 2 4 2 3 6 1 9 0 10 1 7 3 9 7 4 9 3 2 5 1 2 1 2 1 1 3 1 1 1 8 0 6 8 7 1 6 7 8 1 1 2 2 2 1 1 1 1 5 0 7 6 8 1 8 8 5 6 3 3 1 2 1 5 3 4 2 2 2 3 5 1 7 0 8 1 6 3 3 8 5 6 1 1 2 1 3 1 1 1 1 7 0 9 6 9 4 7 7 2 1 3 1 1 1 3 2 1 3 3 1 9 0 10 7 5 9 5 1 1 2 3 4 9 3 3 3 3 1 1 3 2 1 5 4 1 2 3 3 7 1 5 0 7 8 5 4 7 1 9 1 3 1 1 3 2 1 6 0 11 4 5 5 2 3 3 2 1 6 4 4 3 1 3 1 1 1 1 7 0 6 4 1 3 3 1 5 2 2 3 1 1 1 1 1 3 2 1 4 1 3 3 5 3 5 3 3 4 1 6 0 7 9 4 1 9 5 2 4 1 3 1 3 3 2 1 7 0 11 9 9 9 4 4 8 9 4 1 1 6 1 1 2 1 2 1 1 1 8 0 9 4 3 1 5 7 1 5 2 4 1 1 2 2 1 3 1 1 3 4 1 3 3 5 1 8 0 6 1 2 8 9 4 5 1 3 2 3 1 1 3 1 1 5 0 9 9 3 5 1 2 2 4 7 8 3 1 1 1 1 1 6 0 9 6 8 1 1 2 3 6 1 4 1 1 3 1 2 2 5 4 2 4 2 3 4 1 8 0 8 8 6 2 5 3 1 4 1 3 1 3 3 3 3 1 3 1 5 0 6 1 7 8 9 2 9 1 1 1 3 2 1 8 0 7 1 1 9 5 9 2 1 3 1 2 1 1 2 1 3 1 2 3 4 3 5 1 8 0 9 9 5 7 3 2 8 6 4 1 1 1 1 2 1 3 1 1 1 5 0 7 2 6 1 1 5 8 7 1 3 3 3 3 1 6 0 7 8 9 6 9 6 1 6 1 2 2 1 2 3 2 2 5 4 5 3 7 1 6 0 11 2 2 2 4 2 9 6 9 1 9 9 1 1 3 2 2 1 1 6 0 6 9 1 3 4 8 1 1 2 1 2 3 1 1 5 0 10 8 2 6 5 5 4 1 1 6 2 1 1 1 1 2 2 3 5 1 4 3 5 7 5 5 5 4 3 7 1 7 0 9 2 9 7 5 5 4 1 2 2 3 3 1 2 1 3 1 1 5 0 6 9 7 4 7 1 1 2 2 1 3 2 1 5 0 8 1 1 4 8 8 1 6 3 1 3 2 3 3 4 4 4 4 3 5 2 3 4 1 7 0 7 9 6 8 3 1 7 1 2 1 3 1 1 2 1 1 6 0 11 5 9 5 7 4 7 7 1 5 4 4 1 3 2 3 2 1 1 8 0 9 2 4 2 1 1 1 4 2 8 3 1 1 1 1 3 1 2 3 2 1 3 3 6 1 7 0 8 4 7 2 1 4 6 2 7 2 1 1 3 1 1 2 1 8 0 6 1 2 9 9 1 2 3 1 2 3 2 1 3 1 1 6 0 10 4 7 5 6 1 4 4 4 9 1 3 3 1 3 1 1 2 3 1 5 2 5 3 4 1 6 0 10 3 2 3 5 5 1 1 7 4 7 1 1 1 2 1 2 1 7 0 7 1 3 1 7 9 6 1 3 2 2 2 3 3 1 1 7 0 6 1 8 9 1 3 9 1 2 2 2 2 1 2 3 3 4 5 3 5 1 8 0 8 9 1 2 1 1 4 8 7 2 3 3 2 2 2 3 1 1 9 0 10 7 5 3 8 4 7 2 1 6 1 3 3 1 2 3 3 1 3 2 1 9 0 6 9 1 1 9 9 7 1 3 1 3 2 3 1 2 1 4 1 5 2 2 5 7 2 2 3 5 6 3 4 3 3 5 1 9 0 7 9 2 9 7 1 7 7 1 3 3 1 1 1 3 3 2 1 6 0 11 1 1 9 4 7 6 1 5 3 1 1 3 1 3 3 3 2 1 7 0 8 1 1 9 3 8 5 6 8 2 1 2 1 1 3 3 1 3 3 3 3 3 4 1 9 0 11 2 9 1 5 1 9 4 4 2 2 1 1 2 2 2 3 2 1 3 3 1 9 0 11 1 4 6 3 8 5 6 8 1 5 1 1 2 1 1 2 1 2 1 3 1 7 0 10 1 3 8 1 1 3 4 6 4 9 3 2 3 2 1 1 1 5 3 4 3 3 6 1 6 0 11 4 9 2 6 9 5 2 5 9 7 1 1 1 1 1 1 2 1 5 0 9 1 7 4 1 5 9 9 5 3 1 2 1 3 1 1 9 0 7 5 8 5 9 8 1 9 1 3 3 1 1 2 1 2 2 3 2 5 1 1 5 3 6 1 9 0 9 1 9 5 8 4 1 5 2 8 3 2 1 1 2 2 1 1 2 1 5 0 8 3 6 1 1 1 2 8 3 3 2 2 1 2 1 5 0 8 1 6 5 3 9 1 7 1 1 1 3 1 1 4 5 1 2 2 1 1 4 1 4 4 3 7 1 9 0 7 6 3 1 7 8 7 3 2 1 2 3 1 3 2 1 2 1 6 0 6 2 9 6 9 1 6 3 1 1 1 1 2 1 9 0 10 2 2 1 6 8 5 5 1 5 4 2 1 3 1 2 2 3 3 1 3 4 1 3 5 3 4 3 5 1 8 0 6 8 1 2 1 4 8 3 3 1 3 1 3 3 1 1 7 0 10 1 7 8 5 8 1 6 5 3 8 1 3 1 1 1 3 3 1 8 0 7 4 5 6 5 1 2 7 1 2 3 3 3 1 1 1 5 5 1 4 3 3 7 1 9 0 10 7 8 1 5 1 1 3 5 1 6 3 3 3 3 3 1 2 2 1 1 8 0 7 1 3 7 6 4 1 9 2 1 1 3 2 2 2 1 1 9 0 10 2 9 1 1 5 8 2 4 2 6 2 2 1 1 2 3 1 1 3 2 4 3 4 3 3 3 3 4 1 5 0 7 8 1 6 6 8 2 8 2 1 2 3 1 1 7 0 6 7 1 9 1 8 8 3 3 3 3 3 1 2 1 5 0 6 3 4 8 1 6 1 1 3 1 1 1 4 2 5 5 4 1 4 3 5 3 3 5 1 7 0 8 2 8 9 6 2 5 5 1 2 1 3 2 2 1 2 1 7 0 9 4 1 4 7 9 2 8 7 1 1 3 3 3 1 1 3 1 5 0 11 2 1 2 5 2 1 8 5 9 8 9 3 3 1 2 1 2 1 1 5 2 3 4 1 6 0 6 7 1 1 6 5 2 2 1 2 2 1 1 1 8 0 10 1 5 8 2 3 2 1 3 1 1 2 2 2 3 3 3 1 1 1 6 0 9 1 3 9 3 8 4 3 4 1 1 3 2 2 1 3 3 4 1 3 3 6 1 6 0 11 9 1 3 2 3 3 6 3 4 4 7 1 3 3 1 1 1 1 5 0 7 9 9 7 1 2 7 5 1 3 2 1 2 1 8 0 10 4 4 1 3 1 5 9 3 3 5 2 1 2 1 1 3 3 2 3 5 3 3 3 2 3 6 1 9 0 6 1 2 6 8 5 5 2 2 3 1 1 2 2 1 3 1 9 0 11 3 6 1 9 7 2 1 1 1 7 8 3 2 3 2 2 1 3 2 3 1 9 0 9 1 6 9 9 7 1 3 7 1 2 3 3 2 1 1 3 1 3 3 4 3 4 5 2 3 4 1 5 0 9 7 9 9 3 6 2 1 8 2 2 3 1 3 2 1 5 0 7 7 6 3 1 2 2 4 2 2 2 2 1 1 9 0 8 3 3 7 8 7 1 6 3 3 1 1 2 1 1 2 3 2 2 1 3 5 6 2 1 5 4 3 7 1 9 0 10 4 1 3 6 6 7 3 3 4 6 2 3 2 2 2 2 2 3 1 1 9 0 8 9 3 6 3 6 8 2 1 1 2 1 2 3 1 3 3 2 1 7 0 9 3 4 6 9 9 1 3 7 8 2 2 3 1 3 3 2 1 5 4 2 2 4 5 3 7 1 5 0 6 8 1 7 7 1 7 2 2 2 1 1 1 8 0 6 3 2 1 8 4 5 1 2 2 1 1 1 3 1 1 5 0 8 1 4 4 1 2 9 4 8 2 1 3 3 1 2 2 4 3 5 1 2 3 5 1 5 0 7 4 1 4 2 2 1 2 3 1 1 3 2 1 5 0 8 8 2 9 7 1 7 3 1 1 1 2 3 2 1 7 0 7 1 1 3 2 4 5 5 3 1 3 3 1 1 2 4 4 3 5 2 3 6 1 6 0 8 7 8 6 5 1 2 2 6 2 1 3 1 1 1 1 8 0 8 1 8 8 2 5 3 2 5 1 3 3 3 2 1 2 3 1 7 0 9 6 6 5 2 2 6 2 7 1 1 3 2 3 2 1 3 2 4 1 5 4 4 3 5 1 5 0 8 5 1 3 9 8 1 7 2 2 1 1 1 3 1 7 0 8 2 9 2 2 6 8 1 6 1 1 2 2 3 2 3 1 5 0 11 3 1 3 1 1 2 5 5 2 3 2 3 2 3 2 1 4 1 1 4 3 7 2 7 1 4 5 3 5 1 7 0 9 8 6 2 8 9 1 7 5 1 1 1 1 1 1 1 1 1 9 0 7 4 9 3 8 1 5 9 1 2 3 2 1 2 2 1 1 1 5 0 8 9 8 4 1 1 1 9 5 1 1 3 1 1 3 2 2 1 1 3 4 1 8 0 11 1 2 8 1 9 2 3 3 3 6 7 2 1 1 2 3 3 1 1 1 8 0 11 3 8 7 1 8 3 4 4 7 6 1 2 2 1 2 2 1 2 1 1 8 0 11 8 8 1 1 7 6 5 6 4 5 7 3 3 1 3 1 3 1 1 3 3 2 1 3 5 1 8 0 9 1 3 7 8 3 8 1 1 4 3 2 3 3 1 1 1 1 1 5 0 9 4 5 2 1 4 2 4 1 1 2 1 1 2 2 1 8 0 7 1 2 5 1 2 1 1 2 3 1 2 2 3 1 3 3 1 2 4 1 3 7 1 5 0 7 3 1 9 4 6 1 9 3 2 1 3 1 1 9 0 9 1 2 4 7 1 9 3 1 8 3 3 3 1 3 2 3 1 3 1 7 0 6 9 3 1 6 4 7 3 2 2 1 1 3 2 2 2 2 3 3 5 4 6 5 5 4 4 5 4 3 4 1 9 0 11 2 4 7 1 6 7 9 7 2 4 9 2 1 3 3 1 2 3 3 2 1 7 0 7 8 5 4 6 8 7 1 1 3 1 2 3 2 3 1 8 0 10 8 2 1 8 8 6 7 8 8 5 1 1 2 1 1 3 3 1 1 4 5 3 3 5 1 9 0 11 7 5 7 8 4 3 5 1 7 8 4 3 2 2 1 1 1 1 2 3 1 6 0 11 8 5 2 9 9 8 4 2 3 1 5 1 2 1 3 3 2 1 7 0 6 1 5 7 9 1 2 3 2 3 1 3 2 3 4 3 5 2 2 3 4 1 5 0 6 6 7 8 2 1 1 2 1 3 1 3 1 9 0 6 1 8 6 2 1 5 3 3 3 1 2 3 3 1 1 1 6 0 7 6 6 3 1 1 4 8 2 2 1 1 1 3 2 1 1 3 3 5 1 7 0 9 7 1 2 7 7 1 4 4 5 1 1 2 1 1 3 1 1 9 0 6 5 1 3 8 2 7 1 2 1 2 2 3 1 3 2 1 8 0 8 1 7 2 2 5 5 1 1 2 1 3 3 3 1 1 1 5 3 3 2 5 3 6 1 9 0 11 5 3 5 4 7 1 1 3 7 9 4 1 1 2 2 2 2 2 1 1 1 9 0 10 6 2 8 7 6 1 6 1 9 3 1 2 2 3 1 2 3 1 3 1 5 0 10 1 7 2 9 6 2 3 1 7 1 1 3 2 2 3 5 2 4 2 4 1 1 1 4 3 3 2 7 1 4 8 11 11 8 6 3 4 1 4 + diff --git a/adventOfCode/2018/81.py b/adventOfCode/2018/81.py new file mode 100644 index 0000000..b7e1e60 --- /dev/null +++ b/adventOfCode/2018/81.py @@ -0,0 +1,195 @@ +# Arrangement: +# * We provide our own naming +# * Each node: 1st num of children +# * 2nd metadata size + +# Part 1 --> sum of all the metadata + +### Rock Solid Logic: Contruct a Nary Tree and work out from there + +class node: + def __init__(self, children_size, metadata_size): + self.no_of_children = children_size + self.metadata_size = metadata_size + self.children = [] + self.parent = None + self.metadata = "" + # Part 2 + self.value = 0 + +fullStack = [] + +def construct_a_tree(data): + n = len(data) + i = 0 + root = None + while i < n: + + # Safe? + #if fullStack and fullStack[-1].children == 0 and root == fullStack[-1]: + # fullStack[-1].metadata += "".join(data[i:i+fullStack[-1].metadata_size]) + # i += fullStack[-1].metadata_size + # break + + #debug + #print i + #if fullStack: + # print fullStack[-1].metadata_size, fullStack[-1].no_of_children, i + + current = node(int(data[i]), int(data[i+1])) + if not root: + root = current + if current.no_of_children > 0: + fullStack.append(current) + #current.no_of_children -= 1 + i += 2 + else: + current.metadata = data[i+2:i+current.metadata_size+2] + i += 2+current.metadata_size + fullStack[-1].children.append(current) + fullStack[-1].no_of_children -= 1 + current.parent = fullStack[-1] + while fullStack and fullStack[-1].no_of_children == 0: + fullStack[-1].metadata = data[i:i+fullStack[-1].metadata_size] + i += fullStack[-1].metadata_size + next = fullStack.pop() + if fullStack: + fullStack[-1].children.append(next) + fullStack[-1].no_of_children -= 1 + if i > n: + break + + #print root.metadata, root.children + return root + +# Part 1 question ==> Metadata sum of all nodes +# Recursively traverse the tree for metadata sum +def calc_metadata(node, metadata_sum): + #print node.metadata, metadata_sum + + metadata_sum = sum([int(data) for data in node.metadata]) + + for child in node.children: + metadata_sum += calc_metadata(child, metadata_sum) + + return metadata_sum + +# Part 2 question ==> Value of the root node +def root_value(node): + + # Logic to calculate the value + if len(node.children) == 0: + node.value = sum([int(data) for data in node.metadata]) + else: + for md in list(set(node.metadata)): + if int(md)-1 < len(node.children): + node.value += root_value(node.children[int(md)-1]) * (node.metadata.count(md)) + else: + # metadata greater than children list index + node.value += 0 + + return node.value + +def main(): + # Fetch input from url + import requests, sys + # Sent the cookie set through the environment variable to get this + #input = requests.get("https://adventofcode.com/2018/day/8/input") + + # Hard Coded inputs + input = open("81.input","r").read() + input = input.split("\n")[0].split(" ") + root = construct_a_tree(input) + print "Day 8: Part 1 answer is --> " + str(calc_metadata(root, 0)) + print "Day 8: Part 2 answer is --> " + str(root_value(root)) + +main() + +# Logic 1: Construct a dictionary +""" +def traverse(data): + stack = {} + n = len(data) + i = 0 + while i < n: + element = stack[] + if element.children == 0: + element.metadata += data[i+1:i+1+n] + stack.append(element) + +# Logic 2: Stack Method +# * The metadata of A is after all the children metadata are filled. When there is heavy nesting a tree mthod would require a depth first traversal either way to add the children and fill in the metadata values. +# Backward traversal is a little tough for tree. Going with stack logic +class node: + def __init__(children, metadata_size): + self.children = children + self.metadata = metadata_size + self.metadata = "" + +def traverse(data): + stack = [] + n = len(data) + i = 0 + while i < n: + element = node(data[i], data[i+1]) + if element.children == 0: + element.metadata += data[i+1:i+1+n] + stack.append(element) + +# Logic 3: Construct a tree +class node: + def __init__(self, children, metadata_size, index, parent): + # Integer num of children + self.children = children + # Integer size of metadata + self.metadata = metadata_size + # Metadata string + self.md = "" + # Store index in the array + self.index = index + # Children node in a list + self.childs = [] + # Parent details + self.parent = parent + +# Possible recursion function to iterate through the tree +def create_tree(data, parent, next): + #i = current_index + + #if parent.children == 0: + # parent.md += "".join(data[i+1:i+parent.metadata+1]) + # return parent, i+parent.metadata + + while parent.children: + #curr_child = node(int(data[next+1]), int(data[next+2]), next+1) + #tree_for_child, next = create_tree(data, curr_child, next+1) + curr_child = node(int(data[0]), int(data[1]), 1) + tree_for_child, next = create_tree(data[2:], curr_child, 1) + parent.childs.append(tree_for_child) + parent.children -= 1 + + if parent.children == 0: + #if next+parent.metadata+1 > len(data): + # parent.md += "".join(data[next+3:]) + #else: + # parent.md += "".join(data[next+3:next+parent.metadata+1]) + parent.md += "".join(data[:parent.metadata]) + print parent.metadata, parent.md + return parent, next+parent.metadata + + #return parent + +def traverse(data): + root = node(int(data[0]), int(data[1]), 0, None) + create_tree(data[2:], root, 1) + return root.md, root.childs[0].md + +def traverse(data): + n = len(data) + prev_node = None + full_stack = [] + while i < n: + current_node = node(int(data[i]), int(data[i+1]), i, prev_node) + prev_node = current_node + full_stack.append() +""" diff --git a/adventOfCode/2018/dummy.html b/adventOfCode/2018/dummy.html new file mode 100644 index 0000000..b14df64 --- /dev/null +++ b/adventOfCode/2018/dummy.html @@ -0,0 +1 @@ +Hi diff --git a/adventOfCode/2018/notes_to_solve.pdf b/adventOfCode/2018/notes_to_solve.pdf new file mode 100644 index 0000000..9df18b3 Binary files /dev/null and b/adventOfCode/2018/notes_to_solve.pdf differ diff --git a/adventOfCode/2019/day1.go b/adventOfCode/2019/day1.go new file mode 100644 index 0000000..5fbf74d --- /dev/null +++ b/adventOfCode/2019/day1.go @@ -0,0 +1,124 @@ +/* +--- Day 1: The Tyranny of the Rocket Equation --- +Santa has become stranded at the edge of the Solar System while delivering presents to other planets! To accurately calculate his position in space, safely align his warp drive, and return to Earth in time to save Christmas, he needs you to bring him measurements from fifty stars. + +Collect stars by solving puzzles. Two puzzles will be made available on each day in the Advent calendar; the second puzzle is unlocked when you complete the first. Each puzzle grants one star. Good luck! + +The Elves quickly load you into a spacecraft and prepare to launch. + +At the first Go / No Go poll, every Elf is Go until the Fuel Counter-Upper. They haven't determined the amount of fuel required yet. + +Fuel required to launch a given module is based on its mass. Specifically, to find the fuel required for a module, take its mass, divide by three, round down, and subtract 2. + +For example: + +For a mass of 12, divide by 3 and round down to get 4, then subtract 2 to get 2. +For a mass of 14, dividing by 3 and rounding down still yields 4, so the fuel required is also 2. +For a mass of 1969, the fuel required is 654. +For a mass of 100756, the fuel required is 33583. +The Fuel Counter-Upper needs to know the total fuel requirement. To find it, individually calculate the fuel needed for the mass of each module (your puzzle input), then add together all the fuel values. + +What is the sum of the fuel requirements for all of the modules on your spacecraft? +*/ + +package main + +import ( + "fmt" + "net/http" + "io/ioutil" + "math" + "os" + "bufio" + "strconv" +) + +func get_input() ([]byte, error) { + resp, err := http.Get("https://adventofcode.com/2019/day/1/input"); + if err != nil { + fmt.Println("Cannot get the input for the problem!"); + return []byte{}, err; + } + body, err := ioutil.ReadAll(resp.Body); + if err != nil { + fmt.Println("Cannot get the input for the problem!"); + return []byte{}, err; + } + defer resp.Body.Close(); + //fmt.Println(body); + return body, nil; +} + +func part1_assigned_user_input() (int) { + //input, err := ioutil.ReadFile("day1.input") + + // Open the file. + f, _ := os.Open("day1.input") + + // Create a Scanner for the file + scanner := bufio.NewScanner(f) + + // Read and print each line in the file + var result int; + for scanner.Scan() { + num, _ := strconv.Atoi(scanner.Text()) + result += solve_problem(num); + } + + return result +} + +func part2_assigned_user_input() (int) { + // Open the file. + f, _ := os.Open("day1.input") + + // Create a Scanner for the file + scanner := bufio.NewScanner(f) + + // Read and print each line in the file + var result int; + for scanner.Scan() { + num, _ := strconv.Atoi(scanner.Text()); + next := solve_problem(num); + current := next; + for ( next >= 0 ) { + //fmt.Println(next, current); + next = solve_problem(next); + if ( next > 0 ) { + current += next; + } + } + //fmt.Println(num, current); + result += current; + } + return result; +} + +func solve_problem(num int) int { + return int(math.Round(float64(num/3.0))-2) +} + +func main() { + fmt.Println("Day 1 of Advent-Of-Code!..."); + + // Program non-user input + input, err := get_input(); + if err != nil { + fmt.Println("Cannot get the non-user first input for the problem!"); + } + + var result int; + for _, value := range input { + result += solve_problem(int(value)); + } + + // Program assigned user input + result2 := part1_assigned_user_input(); + + fmt.Println("Solution to Day 1 is: "); + fmt.Println("* Part 1: program non-user input solution is: ", result); + fmt.Println("* Part 1: program assigned-user input solution is: ", result2); + //fmt.Println(input); + fmt.Println("* Part 2: program assigned-user input solution is: ", part2_assigned_user_input()); + +} diff --git a/adventOfCode/2019/day1.input b/adventOfCode/2019/day1.input new file mode 100644 index 0000000..131206a --- /dev/null +++ b/adventOfCode/2019/day1.input @@ -0,0 +1,100 @@ +115810 +58892 +76569 +87782 +103850 +103320 +62798 +98400 +71197 +124777 +97523 +52210 +122364 +112858 +58303 +72246 +130616 +118911 +120467 +62299 +71680 +83273 +87791 +89728 +112402 +94325 +118423 +54979 +99132 +70851 +89887 +54131 +103911 +139205 +97804 +68670 +113097 +104705 +109659 +85259 +138145 +56602 +140942 +144354 +104776 +63627 +100050 +90929 +130607 +104809 +69613 +93375 +136009 +81838 +84705 +61669 +84975 +95055 +107505 +126406 +116391 +57303 +128320 +93274 +78225 +116717 +84915 +109201 +102855 +61361 +146332 +127109 +78523 +61900 +59891 +135089 +55323 +51659 +87020 +86431 +132494 +51020 +126660 +81594 +73209 +71717 +135977 +78521 +82396 +118952 +144343 +149121 +119233 +79917 +125447 +127014 +138309 +107308 +146818 +63364 diff --git a/adventOfCode/2019/day12.go b/adventOfCode/2019/day12.go new file mode 100644 index 0000000..06a4e6f --- /dev/null +++ b/adventOfCode/2019/day12.go @@ -0,0 +1,290 @@ +/* +--- Day 12: The N-Body Problem --- +The space near Jupiter is not a very safe place; you need to be careful of a big distracting red spot, extreme radiation, and a whole lot of moons swirling around. You decide to start by tracking the four largest moons: Io, Europa, Ganymede, and Callisto. + +After a brief scan, you calculate the position of each moon (your puzzle input). You just need to simulate their motion so you can avoid them. + +Each moon has a 3-dimensional position (x, y, and z) and a 3-dimensional velocity. The position of each moon is given in your scan; the x, y, and z velocity of each moon starts at 0. + +Simulate the motion of the moons in time steps. Within each time step, first update the velocity of every moon by applying gravity. Then, once all moons' velocities have been updated, update the position of every moon by applying velocity. Time progresses by one step once all of the positions are updated. + +To apply gravity, consider every pair of moons. On each axis (x, y, and z), the velocity of each moon changes by exactly +1 or -1 to pull the moons together. For example, if Ganymede has an x position of 3, and Callisto has a x position of 5, then Ganymede's x velocity changes by +1 (because 5 > 3) and Callisto's x velocity changes by -1 (because 3 < 5). However, if the positions on a given axis are the same, the velocity on that axis does not change for that pair of moons. + +Once all gravity has been applied, apply velocity: simply add the velocity of each moon to its own position. For example, if Europa has a position of x=1, y=2, z=3 and a velocity of x=-2, y=0,z=3, then its new position would be x=-1, y=2, z=6. This process does not modify the velocity of any moon. + +For example, suppose your scan reveals the following positions: + + + + + +Simulating the motion of these moons would produce the following: + +After 0 steps: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= + +After 1 step: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= + +After 2 steps: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= + +After 3 steps: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= + +After 4 steps: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= + +After 5 steps: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= + +After 6 steps: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= + +After 7 steps: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= + +After 8 steps: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= + +After 9 steps: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= + +After 10 steps: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= +Then, it might help to calculate the total energy in the system. The total energy for a single moon is its potential energy multiplied by its kinetic energy. A moon's potential energy is the sum of the absolute values of its x, y, and z position coordinates. A moon's kinetic energy is the sum of the absolute values of its velocity coordinates. Below, each line shows the calculations for a moon's potential energy (pot), kinetic energy (kin), and total energy: + +Energy after 10 steps: +pot: 2 + 1 + 3 = 6; kin: 3 + 2 + 1 = 6; total: 6 * 6 = 36 +pot: 1 + 8 + 0 = 9; kin: 1 + 1 + 3 = 5; total: 9 * 5 = 45 +pot: 3 + 6 + 1 = 10; kin: 3 + 2 + 3 = 8; total: 10 * 8 = 80 +pot: 2 + 0 + 4 = 6; kin: 1 + 1 + 1 = 3; total: 6 * 3 = 18 +Sum of total energy: 36 + 45 + 80 + 18 = 179 +In the above example, adding together the total energy for all moons after 10 steps produces the total energy in the system, 179. + +Here's a second example: + + + + + +Every ten steps of simulation for 100 steps produces: + +After 0 steps: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= + +After 10 steps: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= + +After 20 steps: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= + +After 30 steps: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= + +After 40 steps: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= + +After 50 steps: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= + +After 60 steps: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= + +After 70 steps: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= + +After 80 steps: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= + +After 90 steps: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= + +After 100 steps: +pos=, vel= +pos=, vel= +pos=, vel= +pos=, vel= + +Energy after 100 steps: +pot: 8 + 12 + 9 = 29; kin: 7 + 3 + 0 = 10; total: 29 * 10 = 290 +pot: 13 + 16 + 3 = 32; kin: 3 + 11 + 5 = 19; total: 32 * 19 = 608 +pot: 29 + 11 + 1 = 41; kin: 3 + 7 + 4 = 14; total: 41 * 14 = 574 +pot: 16 + 13 + 23 = 52; kin: 7 + 1 + 1 = 9; total: 52 * 9 = 468 +Sum of total energy: 290 + 608 + 574 + 468 = 1940 +What is the total energy in the system after simulating the moons given in your scan for 1000 steps? +*/ + +package main + +import ( + "fmt" + //"math" + "os" + "bufio" + "strconv" + "strings" +) + +func part1_assigned_user_input(n string) (int) { + + f, _ := os.Open("day"+n+".input") + + scanner := bufio.NewScanner(f) + + var encoded_data string; + + var positions [][]int; + i := 0; + + for scanner.Scan() { + encoded_data = strings.Trim(scanner.Text(), "<>"); + xyz := strings.Split(encoded_data, ","); + positions = append(positions, []int{0,0,0}); + for index, axis := range(xyz) { + value := strings.Split(axis, "="); + number, _ := strconv.Atoi(value[1]); + positions[i][index] = number; + } + i += 1; + } + return solve_problem(positions); +} + +func solve_problem(positions [][]int) int { + + var total int; + + // Velocities for 4 Moons + var velocity [][]int; + for i:=0;i<4;i++ { + velocity = append(velocity, []int{0,0,0}); + } + + // 1000 steps or time + for i:=0;i<1000;i++ { + //fmt.Println(positions, velocity); + + // Update velocity with the positions + for p, pos := range positions { + for axis, value := range pos { + for other:=0;other<4;other++ { + if other != p { + if value < positions[other][axis] { + velocity[p][axis] += 1; + } else if value > positions[other][axis] { + velocity[p][axis] -= 1; + } + } + } + } + } + + // Update Position + for p, pos := range positions { + for axis, _ := range pos { + positions[p][axis] += velocity[p][axis]; + } + } + } + + // Update Position + for p, pos := range positions { + var potential int = 0; + var kinetic int = 0; + for axis, _ := range pos { + if positions[p][axis] < 0 { + potential += (-1*positions[p][axis]); + } else { + potential += positions[p][axis]; + } + if velocity[p][axis] < 0 { + kinetic += (-1*velocity[p][axis]); + } else { + kinetic += velocity[p][axis]; + } + } + fmt.Println(potential, kinetic); + total += potential*kinetic; + } + + //fmt.Println(positions, velocity); + + return total; +} + +func main() { + day := "12"; + fmt.Println("Day "+ day +" of Advent-Of-Code!..."); + + // Program assigned user input + result2 := part1_assigned_user_input(day); + + fmt.Println("Solution to Day "+ day +" is: "); + fmt.Println("* Part 1: program assigned-user input solution is: ", result2); + //fmt.Println("* Part 2: program assigned-user input solution is: ", part2_assigned_user_input(day)); + +} \ No newline at end of file diff --git a/adventOfCode/2019/day12.input b/adventOfCode/2019/day12.input new file mode 100644 index 0000000..39a4680 --- /dev/null +++ b/adventOfCode/2019/day12.input @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/adventOfCode/2019/day2.go b/adventOfCode/2019/day2.go new file mode 100644 index 0000000..16c54e7 --- /dev/null +++ b/adventOfCode/2019/day2.go @@ -0,0 +1,227 @@ +/* +Day 2 Question - Reference to https://adventofcode.com/2019/day/2 + +--- Day 2: 1202 Program Alarm --- +On the way to your gravity assist around the Moon, your ship computer beeps angrily about a "1202 program alarm". On the radio, an Elf is already explaining how to handle the situation: "Don't worry, that's perfectly norma--" The ship computer bursts into flames. + +You notify the Elves that the computer's magic smoke seems to have escaped. "That computer ran Intcode programs like the gravity assist program it was working on; surely there are enough spare parts up there to build a new Intcode computer!" + +An Intcode program is a list of integers separated by commas (like 1,0,0,3,99). To run one, start by looking at the first integer (called position 0). Here, you will find an opcode - either 1, 2, or 99. The opcode indicates what to do; for example, 99 means that the program is finished and should immediately halt. Encountering an unknown opcode means something went wrong. + +Opcode 1 adds together numbers read from two positions and stores the result in a third position. The three integers immediately after the opcode tell you these three positions - the first two indicate the positions from which you should read the input values, and the third indicates the position at which the output should be stored. + +For example, if your Intcode computer encounters 1,10,20,30, it should read the values at positions 10 and 20, add those values, and then overwrite the value at position 30 with their sum. + +Opcode 2 works exactly like opcode 1, except it multiplies the two inputs instead of adding them. Again, the three integers after the opcode indicate where the inputs and outputs are, not their values. + +Once you're done processing an opcode, move to the next one by stepping forward 4 positions. + +For example, suppose you have the following program: + +1,9,10,3,2,3,11,0,99,30,40,50 +For the purposes of illustration, here is the same program split into multiple lines: + +1,9,10,3, +2,3,11,0, +99, +30,40,50 +The first four integers, 1,9,10,3, are at positions 0, 1, 2, and 3. Together, they represent the first opcode (1, addition), the positions of the two inputs (9 and 10), and the position of the output (3). To handle this opcode, you first need to get the values at the input positions: position 9 contains 30, and position 10 contains 40. Add these numbers together to get 70. Then, store this value at the output position; here, the output position (3) is at position 3, so it overwrites itself. Afterward, the program looks like this: + +1,9,10,70, +2,3,11,0, +99, +30,40,50 +Step forward 4 positions to reach the next opcode, 2. This opcode works just like the previous, but it multiplies instead of adding. The inputs are at positions 3 and 11; these positions contain 70 and 50 respectively. Multiplying these produces 3500; this is stored at position 0: + +3500,9,10,70, +2,3,11,0, +99, +30,40,50 +Stepping forward 4 more positions arrives at opcode 99, halting the program. + +Here are the initial and final states of a few more small programs: + +1,0,0,0,99 becomes 2,0,0,0,99 (1 + 1 = 2). +2,3,0,3,99 becomes 2,3,0,6,99 (3 * 2 = 6). +2,4,4,5,99,0 becomes 2,4,4,5,99,9801 (99 * 99 = 9801). +1,1,1,4,99,5,6,0,99 becomes 30,1,1,4,2,5,6,0,99. +Once you have a working computer, the first step is to restore the gravity assist program (your puzzle input) to the "1202 program alarm" state it had just before the last computer caught fire. To do this, before running the program, replace position 1 with the value 12 and replace position 2 with the value 2. What value is left at position 0 after the program halts? +*/ + +package main + +import ( + "fmt" + "net/http" + "io/ioutil" + //"math" + "os" + "bufio" + "strconv" + "strings" +) + +// Get the input for the program as anonymous user + +func get_input(n string) ([]byte, error) { + resp, err := http.Get("https://adventofcode.com/2019/day/" + n+ "/input"); + if err != nil { + fmt.Println("Cannot get the input for the problem!"); + return []byte{}, err; + } + body, err := ioutil.ReadAll(resp.Body); + if err != nil { + fmt.Println("Cannot get the input for the problem!"); + return []byte{}, err; + } + defer resp.Body.Close(); + return body, nil; +} + +func part1_assigned_user_input(n string) ([]int) { + //input, err := ioutil.ReadFile("day"+n+".input") + + // Open the file. + f, _ := os.Open("day"+n+".input") + + // Create a Scanner for the file + scanner := bufio.NewScanner(f) + var lines []int; + + for scanner.Scan() { + line := strings.Split(scanner.Text(), ","); + for _, value := range line { + num, _ := strconv.Atoi(value); + lines = append(lines, num); + } + } + + // Read and print each line in the file + return solve_problem(lines, "1"); +} + +func part2_assigned_user_input(n string) ([]int) { + //input, err := ioutil.ReadFile("day"+n+".input") + + // Open the file. + f, _ := os.Open("day"+n+".input") + + // Create a Scanner for the file + scanner := bufio.NewScanner(f) + var lines []int; + + for scanner.Scan() { + line := strings.Split(scanner.Text(), ","); + for _, value := range line { + num, _ := strconv.Atoi(value); + lines = append(lines, num); + } + } + + // Read and print each line in the file + return solve_problem(lines, "2"); +} + +func solve_problem(input []int, part string) []int { + // core formula to solve + + // 1. Get opcode (decide operation) and jump the indexes (3) - 2 operands and 1 result + i := 0; + end_program := 99; + var opcode int; + var op1 int; + var op2 int; + var target int; + var result int; + + if ( part == "1" ) { + // 2. Initialize program to 1202 state + input[1] = 12; + input[2] = 2; + + //fmt.Println(input); + + // 3. Iterate == run program + for ( input[i] != end_program ) { + opcode = input[i]; + op1 = input[i+1]; + op2 = input[i+2]; + target = input[i+3]; + if ( opcode == 1 ) { + result = input[op1] + input[op2]; + } else { + result = input[op1]*input[op2]; + } + //fmt.Println(input, opcode, op1, op2, target, result); + input[target] = result; + i += 4; + } + + // 4. Return the zeroth index + return []int{input[0]}; + } else { + // 2. Initialize program to 1202 state + for k := 1; k < 100; k++ { + for j := 1; j < 100; j++ { + // 2. Initialize program to 1202 state + //new_input := input; + new_input := make([]int, len(input)); + copy(new_input, input); + //fmt.Println(k,j,new_input, input); + i := 0; + new_input[1] = k; + new_input[2] = j; + // 3. Iterate == run program + for ( new_input[i] != end_program ) { + opcode = new_input[i]; + op1 = new_input[i+1]; + op2 = new_input[i+2]; + target = new_input[i+3]; + if ( opcode == 1 ) { + result = new_input[op1] + new_input[op2]; + } else { + result = new_input[op1] * new_input[op2]; + } + //fmt.Println(input, opcode, op1, op2, target, result); + new_input[target] = result; + i += 4; + } + if new_input[0] == 19690720 { + return []int{100*k+j} + } + } + } + + // 4. Return the zeroth index + return []int{input[0]}; + } +} + +func main() { + day := "2"; + fmt.Println("Day "+ day +" of Advent-Of-Code!..."); + + // Program non-user input + input, err := get_input(day); + if err != nil { + fmt.Println("Cannot get the non-user first input for the problem!"); + } + + var input_arr []int; + for _, value := range input { + input_arr = append(input_arr, int(value)); + } + + // anonymous input solve + //result := solve_problem(input_arr); + + // Program assigned user input - part 1 + result2 := part1_assigned_user_input(day); + result3 := part2_assigned_user_input(day); + + fmt.Println("Solution to Day "+ day +" is: "); + //fmt.Println("* Part 1: program non-user input solution is: ", result); + fmt.Println("* Part 1: program assigned-user input solution is: ", result2); + //fmt.Println(input); + fmt.Println("* Part 2: program assigned-user input solution is: ", result3); +} diff --git a/adventOfCode/2019/day2.input b/adventOfCode/2019/day2.input new file mode 100644 index 0000000..96bdd57 --- /dev/null +++ b/adventOfCode/2019/day2.input @@ -0,0 +1 @@ +1,0,0,3,1,1,2,3,1,3,4,3,1,5,0,3,2,1,10,19,1,19,6,23,2,23,13,27,1,27,5,31,2,31,10,35,1,9,35,39,1,39,9,43,2,9,43,47,1,5,47,51,2,13,51,55,1,55,9,59,2,6,59,63,1,63,5,67,1,10,67,71,1,71,10,75,2,75,13,79,2,79,13,83,1,5,83,87,1,87,6,91,2,91,13,95,1,5,95,99,1,99,2,103,1,103,6,0,99,2,14,0,0 \ No newline at end of file diff --git a/adventOfCode/2019/day4.go b/adventOfCode/2019/day4.go new file mode 100644 index 0000000..6c8fa06 --- /dev/null +++ b/adventOfCode/2019/day4.go @@ -0,0 +1,144 @@ +/* + +Day 4 Question - Reference to https://adventofcode.com/2019/day/4 + +--- Day 4: Secure Container --- +You arrive at the Venus fuel depot only to discover it's protected by a password. The Elves had written the password on a sticky note, but someone threw it out. + +However, they do remember a few key facts about the password: + +It is a six-digit number. +The value is within the range given in your puzzle input. +Two adjacent digits are the same (like 22 in 122345). +Going from left to right, the digits never decrease; they only ever increase or stay the same (like 111123 or 135679). +Other than the range rule, the following are true: + +111111 meets these criteria (double 11, never decreases). +223450 does not meet these criteria (decreasing pair of digits 50). +123789 does not meet these criteria (no double). +How many different passwords within the range given in your puzzle input meet these criteria? + +Your puzzle answer was 979. + +The first half of this puzzle is complete! It provides one gold star: * + +--- Part Two --- +An Elf just remembered one more important detail: the two adjacent matching digits are not part of a larger group of matching digits. + +Given this additional criterion, but still ignoring the range rule, the following are now true: + +112233 meets these criteria because the digits never decrease and all repeated digits are exactly two digits long. +123444 no longer meets the criteria (the repeated 44 is part of a larger group of 444). +111122 meets the criteria (even though 1 is repeated more than twice, it still contains a double 22). +How many different passwords within the range given in your puzzle input meet all of the criteria? + +Your puzzle input is still 256310-732736. +*/ + +package main + +import ( + "fmt" + "strconv" +) + +// Part 1 Solution +func part1_assigned_user_input(n string) (int) { + + // Count of possible passwords + count := 0; + + // Loop through the answer range ( might differ depend on the user ) + for i := 256310; i <= 732736; i++ { + + // convert the num to string to operate and compare + num := string(strconv.Itoa(i)); + + // Adjacent same critera detection + alternate := false; + + // Current index location + current := 0; + + // Last value visited + parent := int(num[0]); + + // Iterate through the number string + for index, value := range num { + // Alter the current index + current = index; + // Rule 1 fails --> digits should keep increasing + if index > 0 && parent > int(value) { + index = 0; + alternate = false; + break; + } + // Rule 2 success --> Same alternate + if index > 0 && int(value) == int(parent) { + alternate = true; + } else { + parent = int(value); + } + } + if ( alternate == true && current == len(num)-1 ) { + //fmt.Println(num, alternate, current); + count += 1; + } + } + return count; +} + +func part2_assigned_user_input(n string) (int) { + count := 0; + //for i := 123455; i <= 123455; i++ { + for i := 256310; i <= 732736; i++ { + num := string(strconv.Itoa(i)); + alternate := false; + current := 0; + parent := int(num[0]); + times := 0; + //freq := map[string]int{}; + for index, value := range num { + current = index; + if index > 0 && parent > int(value) { // Rule 1 Fail --> if decreases + index = 0; + alternate = false; + break; + } else if index > 0 && int(value) == parent { // Rule 2 success --> Same alternate + times += 1; + //freq[parent] = times; + if times == 2 && current == len(num)-1 { + alternate = true; + } + } else { // Rule 3 success --> Same alternate not in a bigger group + if times >= 2 && alternate == false { + //fmt.Println("change", times, num, index, int(value), times); + if times == 2 { + alternate = true; + } + } + // Reset match counter + times = 1; + } + // track a parent or previous value for matching + parent = int(value); + } + // Update counter when all the rules match + if ( alternate == true && current == len(num)-1 ) { + //fmt.Println("----->", num, alternate, current); + count += 1; + } + } + return count; +} + + +func main() { + day := "4"; + fmt.Println("Day "+ day +" of Advent-Of-Code!..."); + result := part1_assigned_user_input(day); + result2 := part2_assigned_user_input(day); + fmt.Println("Solution to Day "+ day +" is: "); + fmt.Println("* Part 1: program assigned-user input solution is: ", result); + fmt.Println("* Part 2: program assigned-user input solution is: ", result2); +} \ No newline at end of file diff --git a/adventOfCode/2019/day6.example b/adventOfCode/2019/day6.example new file mode 100644 index 0000000..d6db9b9 --- /dev/null +++ b/adventOfCode/2019/day6.example @@ -0,0 +1,11 @@ +COM)B +B)C +C)D +D)E +E)F +B)G +G)H +D)I +E)J +J)K +K)L \ No newline at end of file diff --git a/adventOfCode/2019/day6.example2 b/adventOfCode/2019/day6.example2 new file mode 100644 index 0000000..77456ed --- /dev/null +++ b/adventOfCode/2019/day6.example2 @@ -0,0 +1,13 @@ +COM)B +B)C +C)D +D)E +E)F +B)G +G)H +D)I +E)J +J)K +K)L +K)YOU +I)SAN \ No newline at end of file diff --git a/adventOfCode/2019/day6.input b/adventOfCode/2019/day6.input new file mode 100644 index 0000000..a1067be --- /dev/null +++ b/adventOfCode/2019/day6.input @@ -0,0 +1,1713 @@ +YMK)12Q +N3N)11S +P73)8Q3 +PC8)14H +CDH)SR2 +Z3F)KJF +3QM)NMC +GYV)H9S +7WN)TSD +GJ5)PXT +YSX)QT6 +S74)HHH +2SG)Q63 +N81)FGV +6V4)4VC +V12)HTX +SBY)WP6 +22S)4JY +18W)CDB +8J6)3YS +BNS)X8W +L9V)N4T +JYL)R3X +941)5N8 +8JL)JNJ +GVW)5LF +Z9K)H3K +G1T)MXH +11S)48W +4FX)8BD +NMN)YWJ +SY5)98H +MKT)44B +KNB)73D +GX4)BBP +V4P)8ZS +29S)3ZQ +X1H)MXF +FVC)16Q +TD1)79C +C2W)6HG +KHH)F82 +D6R)PHM +C3H)K4T +6TR)NXG +RWV)17F +4ZW)FVY +5JQ)VDX +8XX)34J +VMX)HT3 +JCY)X1H +4TN)8XX +QW6)8S9 +Y78)87P +7BM)3Z9 +8M3)396 +RZ2)TLX +68P)41J +C72)3QM +J8D)61B +T3B)HTL +TC7)WQ1 +676)CDW +7CW)J2Z +XYJ)68X +6VJ)RJH +CXC)R34 +WQ2)WBW +1F2)X2X +QP1)JSJ +7KG)LL2 +L63)TKM +RQ5)MV8 +MGP)2V4 +1LX)TYN +HJ6)LVP +3Z3)JB8 +FQT)X7G +7XN)3VH +YWJ)TH8 +787)8JV +TWJ)18L +MQT)3RG +XKP)YRQ +KJF)LRW +148)G7L +PR6)9JP +W5Q)GX4 +JSJ)9HH +DKP)KXX +Z3Y)TRH +26K)8TS +VKP)XH6 +Q9Q)3QH +1ZB)NWD +3KN)G92 +64S)BJF +ZRT)KH5 +N5M)VW9 +142)RG1 +V76)B1J +PBC)SY3 +H8C)4SH +H78)7SR +2HP)R56 +RGX)XB2 +SKD)MFJ +7MV)4C5 +X9H)LHQ +BBW)RFB +47F)X1V +3SP)DRJ +8KQ)5X5 +ZHP)3NM +Z45)BKW +J87)RB4 +748)7QG +X2R)QK8 +6YN)SV1 +6WP)83M +V68)NDS +49Q)SF1 +L8D)XH1 +HTQ)LWC +M9H)HFB +59W)K9T +FCT)ZTH +SF9)YTP +R63)L3J +SLX)WJD +4FY)YSN +TBR)QHK +615)V2V +B1J)4TN +XZV)GKX +8XX)CXC +FCT)S5M +YND)HTQ +HRC)Z39 +Z4N)1TW +3ST)BYW +XHF)YGL +4JY)GVW +QNM)SBG +JVZ)TGZ +VB3)RB7 +Z7M)MJL +KGG)Q8D +GYG)8FB +RRS)QF5 +P7Y)LF3 +MTG)GFJ +LHK)XP3 +Z8V)VG3 +Y9C)KK1 +28L)26K +BX9)RMS +XB1)YQQ +PXF)9V6 +4FR)J68 +TMN)F2Y +MRX)N16 +Y2Q)3QL +Z4Z)S8Y +3DT)VFM +751)L74 +FKB)19W +X7B)J8D +C7K)7KG +R46)J37 +QM2)FBW +FGS)NG8 +PG1)91M +DRJ)175 +S9Y)4LG +GX2)VF4 +JT5)TQ2 +87P)NVS +FLB)CT5 +KK2)C3T +Y5J)BXF +S8X)XZ2 +J7D)N5M +CLJ)TYC +794)YVG +YCP)DNZ +W9N)4NG +QK8)79Y +MQP)B3G +8F8)9J6 +Z8D)PWT +WBW)98G +VX8)625 +KSP)CHX +M5Q)J49 +RMJ)QGQ +X6K)9T2 +YC6)8VT +QT6)NB9 +PC8)N38 +FCD)2VQ +PCB)BB5 +HXN)8C2 +NF7)SKF +VV7)1H6 +X1V)J4P +GSZ)DWX +QGQ)NKJ +CYV)9P7 +94Y)YHV +RZY)JZ6 +WXY)Q3L +RJC)T99 +RWQ)KX7 +RFQ)S6Q +QP1)BWD +KH5)NTV +DDJ)C8J +Z9L)RXZ +7M1)DH9 +4JY)XQH +9TY)T59 +P34)174 +FM8)F25 +76Q)81F +9WT)T33 +8ZD)GQ7 +MZW)1QC +HLW)YWR +H3K)1LX +L7F)1S6 +SQB)5LJ +7VV)FXV +Q3L)QHT +34J)1Z3 +P2P)FG9 +15B)G52 +KVS)YRX +5T7)NCC +TGZ)FRG +P7X)YOU +J37)MS5 +DL4)DHS +PBH)HFV +KTD)ZHZ +GGH)FQJ +BJF)LWZ +R16)7VV +DQM)KG4 +74Z)XYJ +11P)QT3 +W1J)R42 +Z1B)B8M +PD6)FQT +X1H)QD1 +QGR)TX5 +TDF)9TM +X11)9L1 +P72)SZQ +CYT)1VW +PL9)FXW +HKD)8CP +F5L)G1T +KMV)YX9 +1PS)GVG +DL7)W9N +M26)5QL +PLC)FCS +SY3)PZF +JPS)FVG +8BD)DZV +9MB)VCD +WS8)ZJG +9H6)2QY +HYQ)4N9 +73D)HX4 +6RB)QGV +MT2)GWN +12Q)NX7 +KGB)9T4 +XRD)M3T +P15)W5Q +JJ8)ZXJ +FXV)94Y +R1J)HTZ +1XP)7CW +ZZ1)X4S +KWG)WSN +RQK)Z9S +1M9)Z74 +538)6CK +TN4)5T7 +NXV)15S +8Q3)QZH +75N)YFS +VNN)LSC +NZS)L6V +LXN)FPQ +GYS)MZD +XM6)L66 +LRG)KSP +CHX)Y7T +SLS)FFX +PP5)QZV +K8W)751 +S1C)H2H +H93)WSY +175)ZTN +1F6)HLS +MVN)C79 +N5T)LRM +W1P)VHN +G1C)N1W +GBJ)WWJ +KCN)8PX +QRH)6H2 +1VW)GGX +J9N)RQL +J6B)YVT +BWD)VQR +JZ6)M4B +Q48)H4K +897)XJN +LSB)PPJ +5HK)KDQ +DL2)1TD +NSS)YVV +QVF)ZVV +BJF)WQ2 +JTQ)62Q +765)N4P +H65)YMK +3JV)3NL +QQL)NZS +ZW2)V3C +FVC)97Z +ZSP)L71 +J66)NTN +DY4)M2G +W5B)SKN +4G7)676 +F21)C67 +TCT)6FW +4TT)YR3 +468)WXH +HDP)PG1 +X79)NQK +S2J)BD6 +2CG)SDJ +PZF)QFW +HX4)5JQ +SCP)CB8 +XWJ)D47 +CSX)V12 +T99)B11 +272)3F5 +96V)M26 +4SH)W3P +DF2)8N9 +8CP)CWX +2T8)PF3 +XH6)36Q +8N9)5XN +WXH)L6N +YZ8)L5W +6FW)GCH +S2V)CQP +Y11)WMK +Q48)F4X +N4P)ZHL +7HX)VLK +Q7Y)JRB +HL3)1ZD +ZQD)DKP +9H6)SAN +BB5)7BK +SKD)DYX +QDZ)ZK8 +ZH6)1JC +GVT)P91 +VLT)WXY +DH9)WDW +SP6)SSY +MTZ)GQ8 +RJH)468 +YC1)15B +FGV)MRX +8FB)LCW +F25)6Q4 +424)SCL +WZG)JXW +396)XRX +JWC)F74 +NZS)L75 +C6B)9N9 +34J)HKD +MZJ)LSF +S2T)4G7 +X15)R16 +ZH5)XPL +6VV)3ZK +55F)DDJ +PC6)4HG +N7B)897 +V61)82Q +MS5)86B +16J)ZKZ +HVX)941 +M2G)ZPB +PWC)NPH +FC1)Q48 +9FZ)PVJ +R77)KRV +V6Q)SLS +5HB)6TR +3YS)2ZF +3TV)K9H +M18)QNM +3P6)GCC +SXM)6HS +4VD)T5N +6G1)H8H +7GG)R2D +5LJ)ZSP +6DB)NKT +B6T)73R +FH5)GVT +8SP)Z45 +YSY)QQ7 +9TM)MQP +2YZ)GT7 +5X3)DF4 +8TK)JLD +4N9)VKP +9T2)CNG +FDC)B6S +91X)TKQ +86H)HXZ +2TG)JPT +YVG)9JM +YTN)S95 +RTD)C3H +625)73C +JRB)1XP +SX7)JWC +TSD)RP6 +5X5)RSN +LLL)Y2Q +NQK)TSZ +H73)19D +C6B)ZQD +PPJ)VKR +FK4)XF9 +XM2)2LK +67Z)95V +D3M)997 +QFW)R1J +G1T)F37 +KY9)R46 +1RF)6RB +TDQ)34D +3QJ)MTR +VKR)49P +G57)DM1 +Q73)TTR +LKY)6V4 +B11)DPL +8QD)248 +GFJ)MVN +MNQ)XRD +LXS)QXK +MFG)WD2 +JTJ)3WX +2V4)8G5 +H2T)3JC +MRD)QHM +HT5)JNP +HSZ)2Z2 +YGL)QK7 +SJF)VMX +X4Y)8K7 +LGG)MJS +K8Q)VBQ +QT8)NSS +377)ZHP +SM6)MRD +XYL)YM4 +3H8)LPT +6QH)B9M +QX5)9SB +F1S)9QR +42W)PKW +Z9S)QD2 +R34)CLJ +KK1)Z23 +XZ2)6VV +3VH)P2P +3F3)FGS +CWX)WWQ +JJ8)BFH +D5F)91Y +S15)2T8 +GKD)1W1 +GPD)6MM +2XH)Y77 +4JH)R95 +H8H)3KD +YF5)TG1 +WCG)F63 +67Z)9RD +73R)C7Z +B88)7BX +HHH)7B9 +NKJ)ZPM +WLQ)JG2 +P5Q)GHN +C3B)F46 +8CL)26T +N4T)46R +YKT)89V +6RF)D3M +R2F)18W +X4H)DL4 +XRX)FCD +YFC)WGZ +LRM)6RF +3CH)XQT +PVJ)SNV +H9M)H2V +15T)8QD +J68)RWV +XFH)VB3 +GVW)9SQ +T8F)KFW +QT5)BXJ +K6C)3DZ +SBG)Y1X +N69)7HX +V86)314 +GTJ)D6R +V3C)CJS +9S1)6GD +86B)X5L +P69)QRW +R8C)BWZ +FXD)1PM +TSG)Y78 +G9G)4Y9 +9LV)1F2 +K66)YDF +RG1)F1X +VGL)3KN +RFB)Z4Z +66P)L6D +6G9)YFL +NWR)PD3 +L6D)CB3 +V5J)C6B +C67)3PJ +B6X)S9Y +9TY)JVZ +8ZS)H2T +J2Z)4JH +QHT)V87 +8JV)PZP +VYM)K1M +WSY)YSH +C83)242 +TDM)LR9 +RRS)LJ2 +VDX)GQ2 +PLT)76Q +PBC)142 +1QC)F1V +DSJ)SXF +YSK)S2T +KJF)QDZ +LSC)XT3 +XKK)HRK +YRQ)SR9 +Q39)449 +216)K8Z +B16)RFZ +34N)G29 +2ZF)H8N +S6Q)G4H +B75)X79 +LRW)8J5 +NCK)5B3 +3DZ)RMW +MHM)22S +Y5N)88G +H4R)8NZ +6GB)R2P +97Y)Y37 +X3G)F79 +JJ1)6RW +HXZ)N5T +YFL)3P6 +QMV)PBC +9RD)6DG +SDJ)16J +DNZ)7WN +MZD)J92 +YSH)GX2 +VNG)4DR +LPM)3YD +JB8)WZG +4T7)8RK +FQJ)FTT +ZPM)PRX +F46)LDN +PF3)LRZ +6RW)MNQ +9GN)CGW +LVP)N7D +VJS)P72 +Y7R)N3N +DY4)1P1 +CMQ)HX3 +CB3)V5N +JJ6)58Y +ZXJ)W5B +4LH)7MV +DVN)34N +GD3)2BR +CVP)51P +CQP)KJW +LCB)Z9L +JZH)S67 +K9T)MPT +L9J)Z6N +WRV)SRR +V9Y)5QH +J59)CGN +17F)DH2 +B3G)VBC +TSH)JKN +H7L)9D8 +6MV)7HT +BYK)MKT +V8V)WCG +COM)WLQ +939)Z42 +BSS)459 +TQ2)L9J +KSC)K6X +F37)K6Q +H9D)V5J +SBC)FWX +FNX)T3B +1WV)8Z5 +MB5)CVY +TY5)794 +PWT)QWS +XHC)RZ2 +BFH)S15 +S21)41Q +TP2)GDF +P91)M93 +TBF)6QK +8HW)YSK +459)8D4 +FWV)5JP +9CB)7HZ +WJL)FP7 +RY6)T39 +8D4)972 +N38)PCB +SV1)R2F +JJQ)H3M +6YN)R6D +YGQ)H8K +5NV)LMY +7LV)CDH +12P)2TG +JBS)3JV +Q5P)V86 +GFD)2X7 +6FQ)2YZ +8NZ)BQP +8HG)3YK +RP6)MFP +7W2)SP6 +T8Z)PC8 +126)LQJ +2KK)Y11 +BY5)VXS +FPQ)QP1 +396)F9Y +4D9)4T7 +29R)V9S +GBJ)VNF +ZBK)ZH5 +QZV)4YL +GRV)3W4 +3BT)PRQ +WSN)8X5 +QZH)Y9G +VQR)YX3 +KJ1)QX5 +XXV)2XH +91Y)TCT +YQ3)X6K +M93)5HK +BQL)4VJ +R3X)HNW +9X1)TC7 +298)V9Y +MFD)KNB +MFP)YTN +K8H)4D9 +FWX)QGM +LF4)2WW +X6J)S54 +J4P)FVC +PHQ)6WP +18R)QRH +3YD)NYX +73C)BW2 +CB8)QHY +R6R)FWV +DS4)S1X +F9Y)ZRT +Z5M)H85 +SR9)9LV +NK4)GQM +F87)9X1 +8G5)YTH +9LV)7PN +5Y3)WSS +9JP)5T2 +GHN)6NJ +G11)BGM +D8Y)PHQ +MGV)VRF +N7D)787 +27Z)X6J +FFX)F3S +68X)67Z +MT2)XFH +YCZ)HX2 +ZCX)25Q +CBK)ZBK +RBP)6GW +R6N)TY5 +MTG)DL7 +CFN)DL2 +X7G)9C8 +XQT)YFC +CWY)G7H +VF4)XKP +169)WSX +Z95)54H +ZHB)JX1 +9JP)CVP +1P8)LPM +F7G)7QW +VBQ)291 +XB2)8TL +5N8)HRL +3NL)7GR +R56)YFD +7BK)RGB +89V)LGG +TNF)86Z +H2H)HSZ +CT5)T5L +5KF)83R +SKN)XTV +HTX)SQV +9T4)5B9 +4Z9)PD6 +1ZD)HPG +PHP)DFB +31H)XDY +9KZ)47S +KW1)FCT +VW9)4QL +1KW)MHM +PRQ)V1B +D52)72Q +8Y1)21R +HT3)ZVN +LWC)748 +3ZQ)84V +53F)Q83 +YX3)BYK +4Y9)5SY +PLT)TKF +YFS)LSB +RMW)97Y +1W1)HJ6 +SJN)28L +XYJ)8KQ +G86)X8Y +1GD)K2Y +ZPB)5DY +QQD)FKD +B8M)7YC +F4X)CVL +15S)MGP +B19)HK8 +WG7)7XJ +JWF)7BM +86Z)126 +QQ7)6YN +9GN)KZH +J52)HXN +GGM)68P +SVQ)LXS +F1V)B5L +7B9)YW5 +3PP)YW3 +RSP)Z3F +8K7)216 +8F8)KGG +WRQ)GZM +91M)ZW2 +VLK)LLL +Z6N)TDJ +FTT)T3H +CH5)KHH +GQM)T3Z +8C2)6F7 +JG3)BDB +L75)J2C +1S8)ZN9 +XDL)C2W +JX1)BBW +FG9)D5F +P2G)3NQ +2WW)SMS +9C8)CWY +3QX)7GJ +SG8)H9D +KFW)VD6 +LWZ)BSS +SWY)K8H +F1X)Q5P +9SQ)J6B +WF6)F57 +5SK)FXD +34D)41H +6DB)2LC +M9Z)4LH +FXR)KVS +9MJ)15P +B9F)9TY +M4L)QQL +Q63)PLC +6ZC)6VJ +N16)W1B +6SX)3QX +7WZ)N8H +974)K66 +3BZ)FLB +T3Z)VLT +2DS)BQL +61B)SY5 +TKQ)BFP +3NM)H6G +M25)N81 +XKB)H32 +ZXH)LJC +8Z5)KSC +5XN)6Z7 +36Q)FXR +2LC)SJF +T1J)CYV +SWM)Z7M +RZ2)P34 +Y9C)15T +MKW)SF8 +J94)TN4 +DV8)SWH +JJ1)DMS +BL1)4TS +ZCR)55F +G79)4PS +T5L)XWJ +BYW)B88 +3D5)25D +CPZ)1GS +524)59W +J2C)Y9C +R13)R6N +9D8)1S7 +ZVX)1ZB +VNS)ZZS +DM1)BNG +CVY)GTJ +GQ2)BL1 +8HL)NSQ +PNS)96R +G4H)QFX +DFB)TDQ +S5M)PFD +TH8)SLX +BX6)XYL +V5F)LLF +41Q)1YG +1GP)SL7 +W52)6G1 +4C5)H8Z +KG4)86H +7GR)387 +KNY)CQ1 +HCJ)3JW +2K2)J87 +916)LKY +RNL)YQM +WSS)3BZ +LH1)PR6 +SWH)7TS +Z42)R4S +C2R)JJ1 +GCH)TVW +B9F)8J6 +9TW)9MJ +KDQ)QW6 +ZFC)GXX +4ZM)T1R +VG3)PNS +DHS)LMX +5JZ)D9Z +YTP)8SX +S41)6FQ +1S7)KL9 +YHV)W52 +96R)RR6 +YW5)54D +5CJ)3TV +RFZ)NMN +QF5)WF6 +3TW)MTZ +DHD)KYT +2X7)SG8 +YW5)RJC +NMC)8HG +74N)RNG +ZKZ)878 +8HG)QVF +JYD)FK4 +972)PQJ +248)TWN +SQV)P6Q +TLX)8J9 +VCD)YCP +BDB)C72 +7MV)C3B +QBG)GD3 +F74)41K +2SV)5TL +TCR)GWQ +G7M)PXZ +ZVV)W1J +GX1)5CJ +N8H)WRV +25D)B75 +MK9)YND +VFZ)M9Z +RH1)X4Y +FJW)BD2 +M1V)GKD +41J)DY4 +3ZK)MFG +TQQ)HPT +T84)5X3 +KHR)MJ7 +Q5L)NH7 +YQM)5HB +4DR)9JS +JGL)8W3 +Y7T)P7X +G6R)RL3 +PXT)P4V +M18)M1V +YRX)FM8 +84V)2CG +WD2)DYW +8J9)L72 +R2V)PQG +64D)27Z +5KD)76Z +HPG)5JM +XP3)BX9 +HPT)BX6 +C7Z)5QP +ZJG)5SG +H2V)75N +H47)4WS +VCM)43R +5TJ)49Q +VRF)N43 +T1R)PC6 +HWT)B9F +16Q)Q39 +HQF)3QJ +CLH)V61 +25D)1M3 +QQ1)LPQ +HPP)SN4 +CQ1)DHD +XQH)SXM +W1B)RGX +4HG)YQ3 +77Y)NF7 +15P)K3H +FQ9)SF9 +Y75)S2V +NVS)YKT +7HZ)X5X +8TT)F1S +PYC)PS7 +WJQ)272 +5B9)169 +HZR)ZMY +7M1)5FK +665)CLH +S1X)HPP +S95)N3Y +LGF)KWG +NYX)Z5X +98G)R6R +WJD)K3T +YFD)XQF +Z23)4ZW +RSN)9H6 +YWJ)PMD +M83)8M3 +1TW)DSJ +RSP)LD3 +XF3)XRN +JG2)HRC +DYX)SM6 +FTB)9S1 +83M)9JR +3NL)XPT +9V6)47F +D5K)SLV +BPP)M83 +SY7)SX7 +1LM)7GG +P8H)2CQ +3M3)4ZB +41K)3PP +KZH)9Q9 +MZW)LCB +TG1)CBK +242)YSX +LRZ)PY6 +TRH)RMJ +2NC)XWY +5QH)TH7 +QNY)9WT +TSZ)JJQ +G7H)VFZ +Y51)ZCK +QGM)63Z +Q92)VNG +NX7)HL3 +K2Y)NNM +CGW)N3F +CBK)YGQ +HL2)SJX +921)PLT +B1J)7XN +47S)Y51 +PZP)FNX +DMS)H7L +KN8)MZW +DDF)X4H +4VQ)N3H +174)F7H +L72)6MV +XDR)CCR +WQ1)QGR +NSQ)7CN +PQJ)8B5 +CDQ)GYT +YQQ)91X +5NZ)DF2 +14H)8YB +7N9)MJW +3XT)JQM +5LD)TW3 +4WS)ZVX +PWT)2KN +8S9)96V +ZHZ)1FJ +BC4)X6G +MGT)75P +HX3)Z8D +7CN)Y4J +C83)TQQ +PFD)R2V +H3M)PWC +8ZD)8F8 +TYN)1GD +HFV)TDM +Y37)F21 +XFD)5JF +Q9X)Z5V +YM4)VNN +MRG)HZR +GZV)Q7Y +GZM)3Z3 +997)9MB +KL9)3M3 +XTV)JT5 +HTR)GFD +SLK)NB7 +MPT)1M9 +449)KN8 +MJW)MTV +ZVN)7W2 +21R)BD3 +HK8)NCK +FBW)D41 +L71)39K +YR3)Z8V +LSF)KK2 +MTV)1F6 +387)T84 +6Q4)VJS +R2D)VPQ +DWX)3BT +KSV)6L7 +CXK)GNT +81F)974 +LDN)WRW +FRG)K8Q +54H)8L3 +KXV)JGL +BXJ)765 +CGN)179 +72Q)J9N +W1S)XDR +41Q)ZCR +ZLH)MB5 +RXZ)P2G +TYC)X7K +TYS)939 +5T6)Y5N +QGR)TWJ +765)1RF +179)GBJ +HTZ)SVQ +2KV)XJD +MVZ)M4L +WP6)1QH +8X5)R63 +QT3)R77 +QQL)V8V +RR6)77Y +GXX)Y5J +6ZR)Z95 +TWN)G57 +ZZS)R8C +PMD)WS8 +8TL)LB7 +QHK)TYS +PMR)8JL +142)TCR +R95)ZFC +6HS)615 +5TL)L7F +FP7)LKN +F79)X9H +XWY)4C2 +SN4)DWH +1H6)KY9 +7QW)XM6 +C3T)9TS +XHT)GPX +Q83)GZV +7XJ)MVG +NKT)NKZ +2NX)3CH +T3H)KW1 +YHY)K71 +GDF)V7L +NLP)DF1 +2LK)HDP +L66)V4P +NP9)W8B +49P)SQB +S67)Z1B +YDP)6ZC +7HT)PYY +GQ7)YST +Z39)FKB +QGV)JWF +86B)KXJ +TX5)VX8 +V5N)GCW +7BX)JJ8 +GT7)3F3 +CNG)7M1 +58Y)MTG +685)1FR +5SG)H8C +JXW)BZ4 +XF9)QQD +CH5)F7G +1YG)KXV +BD2)F5L +NH7)3DT +LQJ)4VD +4ZB)12R +V7P)9FZ +TDJ)M5V +9SB)QBG +BPP)X11 +ZKM)3XT +XFJ)54R +NG2)42W +G92)G7V +SJN)XHT +3KD)BLB +8W3)Z4Q +1M3)148 +VYM)TSG +4TS)QT5 +RFW)T8Z +WWQ)Z5M +TK8)C83 +QWS)SY7 +SYR)6G9 +HNW)P15 +PHM)74Z +D1L)FQ9 +F82)8Y1 +1P1)5LD +6F7)V9W +GPX)H47 +MKF)JCY +V76)HL2 +G2T)N9W +VPQ)B6X +ZMY)3L1 +GCW)HLW +TW3)6DB +H7B)MFL +RQL)CV9 +GKX)YF5 +89B)3H8 +9QR)YHY +K4T)SS1 +SZM)GRV +SKF)D5K +6CK)1WV +8RK)8TT +6RB)T1J +X84)7N9 +ZN9)9F4 +N3F)P73 +4V8)4M8 +HRK)MKR +CJ4)7N5 +HMK)XHF +928)ZT7 +Y11)PBH +WMK)843 +P73)2ZM +PQG)D8H +RFW)GX1 +6GD)8ZD +298)4V8 +3X8)CJ4 +RR6)7SS +LPT)SJN +7BX)V76 +LW2)2TK +DWH)D1L +KLR)XKB +2YZ)WG7 +LPQ)FG1 +D9Z)TJV +Y9G)XFJ +Z5X)8R6 +5FK)M25 +LCW)TXX +JKN)685 +YTH)QS7 +D47)MRG +QW4)9B6 +7GJ)XFD +39K)RLD +Z74)5KD +1MD)JPS +8SX)VV7 +N9V)V68 +TDJ)G86 +M9F)XMF +DYW)GGH +B9Z)KTD +HTZ)RY6 +K9H)Q9Q +YVT)SYR +FKD)B42 +R9N)48L +XPW)BPP +V7L)RFQ +X5X)VV5 +XPL)H4R +2TK)WD6 +XJD)N45 +LV4)S2J +878)TJ4 +T59)JYL +S8Y)3X8 +ZJG)QM2 +FBZ)J7D +3L1)S8X +TNF)35T +83X)BY5 +3X8)921 +BDD)KCN +TVW)TBR +9HH)CFN +P4V)KV6 +BBP)Z5Q +WJ8)G79 +KX7)SWY +6ZK)GF8 +W3P)H7B +B42)LGF +R3K)J66 +WD6)VGF +T5N)CDQ +1XP)1KW +H8N)G2T +BRF)ZCX +FXW)P8H +BGM)H73 +QHM)MGV +V87)298 +314)5PX +MJL)PR3 +GXD)XM2 +F7H)K44 +JSP)62V +H8C)Z3Y +3RG)6ZK +L3J)DTX +JT5)T8F +XKG)N4S +HX2)XDL +DZV)ZJR +RLD)Q9B +Y1X)XHC +WQ4)JK8 +BNG)SLK +LB7)LV4 +35T)2NC +GCH)JTJ +K4V)D7G +LF3)7LV +HFB)GYS +4YL)2DS +VBC)SSR +SLV)ZHB +56P)LJ9 +62Q)NBX +GYT)GXD +2Z2)CPZ +V61)CMQ +ZC5)RWQ +R9N)NXV +425)LRG +1Z3)Y75 +TJV)BQ7 +LLF)HCJ +CJS)425 +K6Q)4K1 +HTX)RNL +9KZ)7D7 +FG1)DDF +1RF)FBZ +KXJ)CY9 +4HT)J52 +R95)B9Z +3NQ)JBS +PPJ)15N +SJX)P69 +4PS)64D +H8K)2SV +6DG)5NZ +3Z9)12P +SL7)G1C +5QP)JYD +T39)SWM +95V)29S +NWD)LXN +G29)JTQ +8YB)424 +LJ9)ZMG +VXS)WTB +YX9)4FR +WSX)85M +QBG)FJW +DLF)56P +QNM)YSY +9TS)SPR +J49)KGB +3QL)R13 +K3T)J2T +PYY)4VQ +K5Y)MT2 +RMS)3CM +ZJ8)NWR +V2V)VNS +TC7)89B +26T)5TN +JK8)YC7 +P4V)L8S +44B)RQ5 +8J5)WJQ +1S6)HVX +H87)7TF +3WX)RBP +RB7)LHK +MJ7)ZC5 +2QY)CH5 +25Q)1D2 +K2Y)2KK +GGM)66P +97Z)YCZ +NTV)4FY +G49)G7M +SXF)8N6 +MXF)DLF +T5L)6ZR +878)N7B +5B9)QJT +SZQ)3SP +C8J)XJC +N43)YZ8 +9F4)DS4 +75P)X3G +4LG)K9W +Z16)YC6 +F3S)GYV +5KJ)TD1 +9B6)CG3 +LVP)DV8 +XQF)HYQ +L6V)KJ1 +Z5V)RRS +T33)Y7S +BFP)8BZ +7PN)VCM +4VQ)R9N +MVG)TBF +QFX)GYG +48W)9KZ +CG3)5TJ +X8Y)1MD +JPT)BC4 +Y23)K7T +HTL)12M +B5L)MVZ +5LF)WQ4 +5JF)MGB +VHN)C5Q +6H2)6GB +ZHL)MK9 +FVG)NLP +QJT)RTD +3KS)Q1B +Z32)S74 +SR2)MKW +K1M)ZZ1 +H8Z)RFW +2VQ)ZXH +PCB)SKD +CDW)SBY +ZJR)53F +88G)TMN +DF1)PQ2 +YC7)R3K +QKX)D52 +BLB)MQT +LR9)1S8 +8L3)M9F +C79)BRF +HLS)8SP +3QH)BDD +K6X)XB1 +4QD)QNY +NPH)1GP +CMQ)QKX +GCC)K5Y +N3Y)H93 +3YK)Z4N +928)VYM +6GW)Y7R +NKZ)HTR +D7G)T8N +RB4)KLR +H6G)FH5 +2CQ)V14 +X8W)ZH6 +GVG)5SK +TX5)XXV +XH1)KHR +MFJ)H52 +XMF)TCD +X5L)5KF +NG8)VGL +KV6)DVN +VNF)29R +WSG)8CL +85M)ZJ8 +7D7)2SG +7SR)PXF +K8Q)GSZ +G7L)Z32 +QRW)KQK +98H)H87 +9JS)P7Y +KYY)BZ6 +L6N)PYC +MFL)34L +BZ4)L9V +9RD)5T6 +76Z)SHM +D8H)QW4 +51P)BNS +DTX)F87 +DJB)Q73 +CY9)FC1 +843)4XK +K7W)N69 +18L)9CB +F57)Q92 +FCS)WSG +SF8)TP2 +8BZ)31H +Z4Q)QT8 +PXZ)JS9 +JLD)3TW +L8S)WJ8 +3JW)XF3 +2NR)83X +DVN)4TT +6L7)5Y3 +X4S)C2R +K6Q)PL9 +7TF)W87 +7ZG)S41 +LMX)57N +FPQ)CSX +4K1)WRQ +3PJ)M18 +JQM)Q9X +3JN)X84 +HRL)538 +XDL)6SX +6QK)L63 +1FJ)Q5L +TH7)SBC +K8Z)J59 +GHN)524 +F2Y)G9G +9JR)HQF +VGF)CYT +DPL)K4V +C5Q)TNF +X7K)W15 +79Y)DJB +56P)XPW +BW2)X7B +9L1)5KJ +ZCK)3J5 +H85)SZM +LKN)MZJ +SMS)GYD +ZTH)MKF +QHT)K8W +CVL)JJ6 +X2X)7ZG +ZTN)S1C +N16)G11 +3Z9)RZY +19D)H9M +48L)YC1 +5QL)928 +216)CXK +N45)8HL +VT6)4HT +XDY)GGM +W8B)Y23 +JVZ)B16 +MHM)QMV +XDR)1PS +19W)64S +TXX)2HP +BKW)P5Q +9J6)11P +43R)V5F +RGB)8TK +6NJ)V6Q +ZK8)665 +9N9)H78 +Y77)WJL +VJS)YDP +Z5Q)3ST +MXF)QQ1 +JNP)ZKM +R6D)LH1 +M4B)JSP +Y7S)V48 +M5V)YKJ +3F5)NG2 +5PX)Q2F +T8N)JG3 +83R)C7K +VFM)C5V +3J5)KYY +W87)NK4 +4C2)3KS +ML4)PHP +54D)H65 +BQP)K7W +N4S)9GN +RRP)RH1 +C3B)D8Y +L74)DQM +XWN)916 +NDS)ZLH +1PM)4FX +PD3)GJ5 +F3J)L8D +3CM)HT5 +GNT)2K2 +TKF)3D5 +2T8)RRP +XJN)G6R +VV5)74N +1TD)XFK +V9S)KMV +2ZM)QPV +C7Z)1P8 +41H)B6T +GWN)HMK +DF4)Q8Z +314)XWN +V1B)TFW +1D2)2PW +N4P)W1P +WWJ)1LM +GF8)HWT +K8Z)FTB +MJS)TK8 +F63)TSH +CWY)SCP +4XK)Z16 +TBF)2KV +1GS)DG9 +NBX)XKK +LJ2)LF4 +WDW)M5Q +NTN)XT1 +WTB)3JN +8N6)W1S +N9W)377 +QD1)V7P +6HG)RSP +7N5)18R +TSG)6JN +SPR)7WZ +QHY)TDF +H9S)4Z9 +4M8)X2R +DRJ)PP5 +MTR)5JZ +8B5)4ZM +TJ4)6QH +CCR)2NX +SF1)MFD +SS1)T4M +VD6)5NV +BQ7)XZV +ZT7)KSV +97Z)4QD +BBP)B19 +6JN)J94 +R42)RQK +MGP)JZH +V9S)KNY +5DY)PMR +FK4)8HW +4VJ)F3J +J92)2NR +XRN)Z9K +M83)NP9 +787)G49 +N1W)ML4 +XJD)VT6 +7SS)9TW +YST)S21 +K71)X15 +3W4)FDC +1FR)GPD +WRW)MGT +TRH)K6C +LL2)M9H +NNM)XKG +KXX)N9V +5CJ)LW2 \ No newline at end of file diff --git a/adventOfCode/2019/day6.py b/adventOfCode/2019/day6.py new file mode 100644 index 0000000..41b110c --- /dev/null +++ b/adventOfCode/2019/day6.py @@ -0,0 +1,197 @@ +""" +--- Day 6: Universal Orbit Map --- +You've landed at the Universal Orbit Map facility on Mercury. Because navigation in space often involves transferring between orbits, the orbit maps here are useful for finding efficient routes between, for example, you and Santa. You download a map of the local orbits (your puzzle input). + +Except for the universal Center of Mass (COM), every object in space is in orbit around exactly one other object. An orbit looks roughly like this: + + \ + \ + | + | +AAA--> o o <--BBB + | + | + / + / +In this diagram, the object BBB is in orbit around AAA. The path that BBB takes around AAA (drawn with lines) is only partly shown. In the map data, this orbital relationship is written AAA)BBB, which means "BBB is in orbit around AAA". + +Before you use your map data to plot a course, you need to make sure it wasn't corrupted during the download. To verify maps, the Universal Orbit Map facility uses orbit count checksums - the total number of direct orbits (like the one shown above) and indirect orbits. + +Whenever A orbits B and B orbits C, then A indirectly orbits C. This chain can be any number of objects long: if A orbits B, B orbits C, and C orbits D, then A indirectly orbits D. + +For example, suppose you have the following map: + +COM)B +B)C +C)D +D)E +E)F +B)G +G)H +D)I +E)J +J)K +K)L +Visually, the above map of orbits looks like this: + + G - H J - K - L + / / +COM - B - C - D - E - F + \ + I +In this visual representation, when two objects are connected by a line, the one on the right directly orbits the one on the left. + +Here, we can count the total number of orbits as follows: + +D directly orbits C and indirectly orbits B and COM, a total of 3 orbits. +L directly orbits K and indirectly orbits J, E, D, C, B, and COM, a total of 7 orbits. +COM orbits nothing. +The total number of direct and indirect orbits in this example is 42. + +What is the total number of direct and indirect orbits in your map data? + +Your puzzle answer was 358244. + +The first half of this puzzle is complete! It provides one gold star: * + +--- Part Two --- +Now, you just need to figure out how many orbital transfers you (YOU) need to take to get to Santa (SAN). + +You start at the object YOU are orbiting; your destination is the object SAN is orbiting. An orbital transfer lets you move from any object to an object orbiting or orbited by that object. + +For example, suppose you have the following map: + +COM)B +B)C +C)D +D)E +E)F +B)G +G)H +D)I +E)J +J)K +K)L +K)YOU +I)SAN +Visually, the above map of orbits looks like this: + + YOU + / + G - H J - K - L + / / +COM - B - C - D - E - F + \ + I - SAN +In this example, YOU are in orbit around K, and SAN is in orbit around I. To move from K to I, a minimum of 4 orbital transfers are required: + +K to J +J to E +E to D +D to I +Afterward, the map of orbits looks like this: + + G - H J - K - L + / / +COM - B - C - D - E - F + \ + I - SAN + \ + YOU +What is the minimum number of orbital transfers required to move from the object YOU are orbiting to the object SAN is orbiting? (Between the objects they are orbiting - not between YOU and SAN.) + +Although it hasn't changed, you can still get your puzzle input. +""" + +# Python Implmentation of day 6 + +def solve_problem(): + return "" + +def main(): + day = "6" + print("Day "+ day + " problem solver: ") + + files = [".input", ".example", ".example2"] + + for f in files: + # Get input for problem + content = open("day"+day+f).readlines() + + # Create a graph for the inputs + graph = {} + + # Iterate through the inputs to create the graph with relations + for c in content: + core, direct_orbit = c.split(")") + core = core.strip() + direct_orbit = direct_orbit.strip() + if direct_orbit not in graph: + graph[direct_orbit] = [] + graph[direct_orbit].append(core) + + #print(graph) + + # Total number of edges + edges = 0 + + for node in graph: + stack = graph[node][:] + curr_edge = 0 + while stack: + current = stack.pop(0) + curr_edge += 1 + if current in graph: + stack.extend(graph[current]) + edges += curr_edge + #print(node, curr_edge) + + print("Day 6 Part 1 " + f + " answer is " + str(edges)) + + if "YOU" in graph: + + # Logic 1: Traceback until intersection --> this assumes both the sides are of same length which is wrong + """ + left = graph["YOU"][0] + right = graph["SAN"][0] + orbital_transfers = 0 + + while left != right and left in graph and right in graph: + orbital_transfers += 1 + print(left, right) + left = graph[left][0] + right = graph[right][0] + """ + + # Logic: Find the path of SAN and YOU until the end and find intersection --> this would be a worst case solution + orbital_transfers = 0 + left = "YOU" + left_path = [] + while left in graph: + left = graph[left][0] + left_path.append(left) + + right = "SAN" + right_path = [] + while right in graph: + right = graph[right][0] + right_path.append(right) + + i = 0 + while i < len(left_path): + if left_path[i] in right_path: + break + else: + i += 1 + + orbital_transfers = i + right_path.index(left_path[i]) + + print("Day 6 Part 2 " + f + " answer is " + str(orbital_transfers)) + + + +main() + + + + diff --git a/adventOfCode/2019/day8.go b/adventOfCode/2019/day8.go new file mode 100644 index 0000000..7ba84f4 --- /dev/null +++ b/adventOfCode/2019/day8.go @@ -0,0 +1,159 @@ +/* +--- Day 8: Space Image Format --- +The Elves' spirits are lifted when they realize you have an opportunity to reboot one of their Mars rovers, and so they are curious if you would spend a brief sojourn on Mars. You land your ship near the rover. + +When you reach the rover, you discover that it's already in the process of rebooting! It's just waiting for someone to enter a BIOS password. The Elf responsible for the rover takes a picture of the password (your puzzle input) and sends it to you via the Digital Sending Network. + +Unfortunately, images sent via the Digital Sending Network aren't encoded with any normal encoding; instead, they're encoded in a special Space Image Format. None of the Elves seem to remember why this is the case. They send you the instructions to decode it. + +Images are sent as a series of digits that each represent the color of a single pixel. The digits fill each row of the image left-to-right, then move downward to the next row, filling rows top-to-bottom until every pixel of the image is filled. + +Each image actually consists of a series of identically-sized layers that are filled in this way. So, the first digit corresponds to the top-left pixel of the first layer, the second digit corresponds to the pixel to the right of that on the same layer, and so on until the last digit, which corresponds to the bottom-right pixel of the last layer. + +For example, given an image 3 pixels wide and 2 pixels tall, the image data 123456789012 corresponds to the following image layers: + +Layer 1: 123 + 456 + +Layer 2: 789 + 012 +The image you received is 25 pixels wide and 6 pixels tall. + +To make sure the image wasn't corrupted during transmission, the Elves would like you to find the layer that contains the fewest 0 digits. On that layer, what is the number of 1 digits multiplied by the number of 2 digits? +*/ + +package main + +import ( + "fmt" + "os" + "bufio" + "strings" + "strconv" +) + +func part_n_assigned_user_input(n string, width int, height int) ([][]string) { + + // Open the file. + f, _ := os.Open("day"+n+".input") + + // Create a Scanner for the file + scanner := bufio.NewScanner(f) + + var encoded_data []string; + + // Create a GRAPH with hashmap or dict for the inputs + for scanner.Scan() { + encoded_data = strings.Split(scanner.Text(), ""); + //fmt.Println(encoded_data); + } + + // Decode image data + return decode_image(encoded_data, width, height); + } + +func decode_image(encoded_data []string, w int, h int) ([][]string) { + // As per input we need to create the layer 25 wide x 6 tall + + // Part 1 Params + count0 := int(^uint(0) >> 1); + count1 := 0; + count2 := 0; + var min_zero_layer []string; + var top_layer []string; + var result [][]string; + + var decode_data [][]string; + i := 0; + for i < len(encoded_data) { + var current_layer []string; + var current_zero int; + tall := 0; + index := 0 + for tall < h { + width := 0; + for width < w { + if encoded_data[i] == "0" { + current_zero += 1; + } + current_layer = append(current_layer, encoded_data[i]); + if len(top_layer) > 0 && top_layer[index] == "2" && encoded_data[i] != "2" { + fmt.Println(index, encoded_data[i]); + top_layer[index] = encoded_data[i]; + } + i += 1; + index += 1; + width += 1; + } + //i += 1; + tall += 1; + } + fmt.Println(current_layer); + if len(top_layer) == 0 { + //fmt.Println(current_layer); + top_layer = current_layer; + } + if current_zero < count0 { + count0 = current_zero; + min_zero_layer = current_layer; + } + decode_data = append(decode_data, current_layer); + } + //fmt.Println(decode_data); + //fmt.Println(min_zero_layer); + for i:=0; i= len(day1Inputs) { + continue + } + curr_window = day1Inputs[i] + day1Inputs[i+1] + day1Inputs[i+2] + if last_window == 0 { + last_window = curr_window + } else if curr_window > last_window { + sol2 += 1 + } + last_window = curr_window + } + return sol1, sol2 +} \ No newline at end of file diff --git a/adventOfCode/2021/1/1-sample.input b/adventOfCode/2021/1/1-sample.input new file mode 100644 index 0000000..60ac9b8 --- /dev/null +++ b/adventOfCode/2021/1/1-sample.input @@ -0,0 +1,11 @@ +199 +200 +208 +210 +200 +207 +240 +269 +260 +263 + diff --git a/adventOfCode/2021/1/1.input b/adventOfCode/2021/1/1.input new file mode 100644 index 0000000..be8b29b --- /dev/null +++ b/adventOfCode/2021/1/1.input @@ -0,0 +1,2001 @@ +199 +227 +229 +230 +233 +228 +231 +226 +237 +259 +262 +265 +266 +265 +269 +276 +278 +279 +281 +287 +305 +316 +314 +320 +313 +314 +315 +329 +346 +357 +370 +369 +360 +384 +383 +401 +402 +403 +404 +403 +406 +408 +406 +401 +393 +395 +416 +418 +408 +411 +412 +416 +417 +404 +421 +436 +437 +436 +420 +388 +405 +403 +371 +376 +378 +374 +378 +377 +403 +411 +444 +424 +417 +416 +419 +436 +415 +413 +429 +446 +462 +463 +464 +467 +466 +475 +483 +478 +487 +488 +469 +470 +472 +473 +460 +463 +465 +477 +487 +508 +506 +509 +512 +513 +519 +525 +531 +498 +506 +504 +506 +507 +509 +510 +512 +537 +553 +536 +533 +524 +525 +526 +527 +530 +531 +533 +537 +538 +537 +539 +544 +552 +550 +576 +560 +556 +561 +552 +560 +572 +573 +572 +571 +573 +578 +581 +582 +578 +541 +546 +537 +545 +556 +565 +566 +571 +561 +573 +579 +578 +581 +600 +603 +604 +597 +598 +599 +598 +599 +580 +585 +586 +596 +597 +602 +593 +598 +599 +604 +608 +609 +616 +615 +613 +622 +625 +620 +632 +636 +628 +633 +640 +621 +620 +638 +646 +647 +648 +647 +654 +655 +663 +652 +664 +668 +669 +668 +663 +667 +659 +658 +666 +670 +685 +703 +706 +705 +706 +727 +730 +729 +735 +743 +749 +750 +751 +756 +774 +776 +767 +778 +777 +790 +791 +794 +798 +801 +804 +812 +818 +819 +818 +821 +825 +818 +829 +832 +835 +849 +848 +863 +859 +863 +871 +870 +869 +873 +875 +878 +874 +896 +903 +890 +891 +905 +912 +913 +911 +917 +941 +943 +944 +940 +943 +945 +947 +948 +953 +930 +932 +933 +948 +936 +937 +941 +947 +952 +957 +951 +953 +954 +958 +979 +982 +971 +974 +979 +984 +988 +989 +986 +987 +992 +998 +1013 +1024 +1022 +1023 +1014 +1019 +1042 +1048 +1047 +1060 +1056 +1067 +1054 +1053 +1061 +1063 +1068 +1074 +1104 +1105 +1107 +1119 +1126 +1127 +1129 +1143 +1145 +1146 +1151 +1159 +1183 +1185 +1192 +1183 +1185 +1182 +1180 +1198 +1215 +1221 +1224 +1227 +1230 +1262 +1289 +1291 +1294 +1297 +1300 +1303 +1321 +1323 +1329 +1331 +1341 +1362 +1369 +1370 +1388 +1389 +1393 +1407 +1386 +1380 +1381 +1378 +1398 +1402 +1399 +1422 +1433 +1449 +1451 +1449 +1462 +1454 +1455 +1452 +1471 +1472 +1487 +1477 +1459 +1463 +1461 +1463 +1473 +1489 +1482 +1516 +1527 +1521 +1522 +1527 +1529 +1531 +1538 +1550 +1553 +1548 +1549 +1545 +1548 +1543 +1546 +1549 +1572 +1576 +1581 +1575 +1584 +1602 +1604 +1605 +1606 +1611 +1610 +1623 +1618 +1614 +1622 +1613 +1608 +1611 +1638 +1632 +1643 +1649 +1652 +1655 +1652 +1653 +1654 +1658 +1659 +1661 +1667 +1695 +1710 +1719 +1726 +1727 +1725 +1726 +1736 +1741 +1763 +1752 +1769 +1770 +1767 +1768 +1769 +1771 +1799 +1798 +1810 +1813 +1816 +1826 +1837 +1842 +1841 +1848 +1853 +1823 +1836 +1835 +1837 +1836 +1839 +1838 +1840 +1841 +1839 +1843 +1844 +1862 +1873 +1877 +1880 +1882 +1881 +1895 +1891 +1896 +1899 +1893 +1894 +1892 +1894 +1895 +1921 +1920 +1922 +1928 +1925 +1933 +1943 +1942 +1936 +1941 +1919 +1912 +1914 +1922 +1918 +1934 +1932 +1946 +1949 +1955 +1964 +1974 +1977 +1978 +1983 +1984 +1986 +1990 +2005 +2022 +2026 +2032 +2031 +2029 +2031 +2035 +2041 +2042 +2043 +2053 +2054 +2058 +2062 +2063 +2055 +2049 +2021 +2022 +2054 +2052 +2084 +2076 +2079 +2090 +2088 +2093 +2095 +2093 +2091 +2089 +2095 +2096 +2102 +2127 +2129 +2132 +2117 +2125 +2131 +2132 +2126 +2134 +2140 +2137 +2138 +2136 +2137 +2141 +2153 +2152 +2170 +2177 +2147 +2159 +2161 +2160 +2173 +2176 +2194 +2205 +2206 +2213 +2231 +2232 +2242 +2243 +2217 +2224 +2225 +2230 +2226 +2214 +2212 +2227 +2230 +2237 +2238 +2241 +2264 +2283 +2288 +2308 +2309 +2311 +2312 +2314 +2316 +2317 +2318 +2321 +2326 +2324 +2325 +2321 +2324 +2322 +2325 +2327 +2335 +2369 +2370 +2374 +2375 +2344 +2347 +2348 +2341 +2346 +2355 +2356 +2371 +2368 +2370 +2375 +2378 +2379 +2370 +2363 +2365 +2366 +2363 +2364 +2372 +2374 +2392 +2399 +2397 +2384 +2400 +2401 +2402 +2401 +2400 +2402 +2412 +2422 +2423 +2426 +2424 +2425 +2421 +2422 +2440 +2441 +2451 +2442 +2443 +2444 +2446 +2451 +2452 +2450 +2458 +2457 +2490 +2496 +2506 +2507 +2508 +2511 +2531 +2536 +2537 +2539 +2529 +2530 +2561 +2562 +2592 +2595 +2584 +2601 +2603 +2589 +2586 +2588 +2586 +2596 +2613 +2616 +2618 +2621 +2629 +2637 +2638 +2619 +2621 +2619 +2631 +2621 +2619 +2624 +2628 +2634 +2636 +2637 +2626 +2632 +2623 +2630 +2629 +2630 +2633 +2620 +2629 +2635 +2614 +2617 +2612 +2613 +2609 +2601 +2604 +2611 +2602 +2607 +2611 +2639 +2646 +2647 +2618 +2613 +2614 +2635 +2642 +2649 +2653 +2652 +2628 +2629 +2631 +2636 +2639 +2649 +2665 +2667 +2666 +2665 +2668 +2672 +2673 +2675 +2693 +2694 +2696 +2701 +2702 +2703 +2700 +2716 +2718 +2719 +2718 +2719 +2722 +2723 +2715 +2726 +2737 +2757 +2758 +2759 +2762 +2760 +2765 +2759 +2763 +2764 +2774 +2785 +2786 +2802 +2803 +2802 +2824 +2833 +2834 +2830 +2832 +2842 +2828 +2829 +2836 +2838 +2813 +2811 +2798 +2799 +2796 +2805 +2808 +2807 +2811 +2812 +2811 +2812 +2793 +2787 +2802 +2805 +2804 +2822 +2825 +2837 +2835 +2842 +2838 +2849 +2840 +2841 +2853 +2854 +2863 +2877 +2886 +2864 +2866 +2846 +2860 +2840 +2842 +2844 +2866 +2867 +2870 +2856 +2860 +2861 +2860 +2872 +2877 +2881 +2883 +2881 +2883 +2880 +2881 +2882 +2880 +2902 +2903 +2904 +2937 +2939 +2938 +2945 +2954 +2950 +2966 +2967 +2976 +2980 +2982 +2976 +2986 +2997 +2996 +2994 +3004 +3007 +3008 +3016 +3014 +3054 +3078 +3095 +3114 +3115 +3120 +3107 +3109 +3124 +3140 +3144 +3150 +3163 +3165 +3164 +3158 +3172 +3175 +3174 +3184 +3188 +3198 +3193 +3224 +3226 +3227 +3252 +3273 +3280 +3289 +3291 +3290 +3291 +3279 +3281 +3282 +3281 +3298 +3302 +3289 +3304 +3295 +3312 +3314 +3327 +3328 +3337 +3348 +3349 +3340 +3348 +3351 +3350 +3351 +3350 +3345 +3339 +3343 +3344 +3329 +3354 +3356 +3358 +3363 +3365 +3373 +3376 +3383 +3384 +3388 +3389 +3390 +3397 +3398 +3401 +3409 +3411 +3412 +3411 +3418 +3428 +3430 +3432 +3418 +3410 +3418 +3424 +3425 +3426 +3430 +3439 +3441 +3422 +3423 +3425 +3426 +3428 +3429 +3436 +3448 +3447 +3443 +3445 +3468 +3482 +3483 +3499 +3506 +3513 +3518 +3523 +3524 +3525 +3529 +3532 +3529 +3565 +3577 +3576 +3577 +3576 +3539 +3557 +3554 +3563 +3562 +3564 +3565 +3586 +3583 +3590 +3589 +3580 +3581 +3574 +3599 +3597 +3609 +3610 +3611 +3614 +3613 +3611 +3612 +3611 +3598 +3596 +3597 +3585 +3568 +3569 +3550 +3561 +3563 +3551 +3552 +3555 +3553 +3554 +3553 +3552 +3555 +3557 +3560 +3585 +3591 +3604 +3609 +3640 +3641 +3645 +3644 +3643 +3646 +3644 +3664 +3653 +3660 +3667 +3664 +3665 +3668 +3670 +3649 +3640 +3639 +3647 +3654 +3650 +3648 +3654 +3651 +3652 +3653 +3654 +3655 +3671 +3660 +3671 +3675 +3679 +3680 +3681 +3686 +3690 +3691 +3693 +3695 +3698 +3697 +3699 +3708 +3712 +3714 +3712 +3711 +3716 +3731 +3732 +3736 +3753 +3755 +3756 +3767 +3747 +3746 +3733 +3711 +3722 +3718 +3721 +3722 +3723 +3724 +3727 +3731 +3732 +3741 +3743 +3750 +3751 +3738 +3741 +3739 +3740 +3756 +3755 +3751 +3750 +3755 +3757 +3773 +3778 +3781 +3782 +3768 +3772 +3766 +3770 +3778 +3792 +3798 +3801 +3803 +3801 +3812 +3833 +3873 +3868 +3865 +3866 +3906 +3910 +3897 +3907 +3910 +3898 +3914 +3917 +3908 +3912 +3920 +3934 +3930 +3934 +3935 +3937 +3942 +3943 +3948 +3964 +3978 +3985 +3986 +3993 +3995 +4014 +4021 +4024 +4025 +4024 +4027 +4028 +4043 +4047 +4049 +4036 +4039 +4038 +4037 +4045 +4040 +4041 +4043 +4035 +4046 +4063 +4054 +4055 +4064 +4067 +4060 +4061 +4062 +4069 +4070 +4063 +4064 +4077 +4065 +4074 +4076 +4078 +4091 +4100 +4104 +4105 +4106 +4107 +4115 +4110 +4112 +4113 +4114 +4115 +4092 +4093 +4107 +4109 +4108 +4112 +4143 +4144 +4145 +4146 +4145 +4144 +4126 +4130 +4134 +4149 +4151 +4161 +4162 +4160 +4146 +4170 +4188 +4196 +4194 +4193 +4196 +4197 +4198 +4200 +4205 +4218 +4228 +4216 +4224 +4226 +4241 +4245 +4247 +4251 +4245 +4244 +4266 +4259 +4262 +4269 +4270 +4275 +4281 +4298 +4305 +4309 +4311 +4325 +4328 +4346 +4347 +4357 +4360 +4359 +4357 +4391 +4396 +4391 +4397 +4395 +4405 +4410 +4412 +4433 +4420 +4421 +4422 +4423 +4431 +4437 +4447 +4451 +4458 +4457 +4458 +4456 +4455 +4458 +4460 +4431 +4432 +4431 +4441 +4444 +4436 +4408 +4406 +4414 +4415 +4413 +4422 +4449 +4430 +4428 +4397 +4395 +4396 +4398 +4396 +4399 +4406 +4413 +4422 +4421 +4429 +4431 +4430 +4462 +4460 +4480 +4482 +4486 +4484 +4483 +4497 +4493 +4496 +4506 +4504 +4497 +4498 +4503 +4513 +4525 +4533 +4547 +4560 +4561 +4563 +4562 +4572 +4571 +4575 +4557 +4561 +4562 +4550 +4552 +4543 +4537 +4534 +4542 +4561 +4563 +4562 +4583 +4582 +4591 +4592 +4597 +4601 +4599 +4600 +4610 +4601 +4612 +4630 +4616 +4619 +4623 +4624 +4636 +4638 +4645 +4651 +4655 +4660 +4659 +4658 +4657 +4658 +4661 +4670 +4665 +4656 +4664 +4666 +4667 +4669 +4696 +4701 +4712 +4711 +4719 +4679 +4680 +4686 +4684 +4685 +4689 +4682 +4686 +4688 +4687 +4688 +4687 +4693 +4672 +4670 +4667 +4673 +4643 +4644 +4653 +4668 +4669 +4672 +4685 +4663 +4665 +4672 +4696 +4698 +4701 +4699 +4687 +4690 +4687 +4684 +4685 +4687 +4689 +4685 +4692 +4690 +4696 +4702 +4703 +4704 +4717 +4718 +4719 +4711 +4717 +4719 +4726 +4722 +4736 +4735 +4739 +4748 +4741 +4738 +4736 +4737 +4736 +4740 +4748 +4749 +4757 +4760 +4768 +4754 +4756 +4772 +4773 +4775 +4770 +4766 +4769 +4762 +4771 +4773 +4775 +4776 +4778 +4782 +4770 +4763 +4765 +4764 +4765 +4764 +4777 +4780 +4786 +4797 +4803 +4812 +4811 +4818 +4823 +4820 +4821 +4831 +4834 +4862 +4865 +4856 +4857 +4863 +4860 +4861 +4858 +4846 +4848 +4852 +4853 +4854 +4856 +4832 +4833 +4832 +4830 +4826 +4833 +4851 +4852 +4855 +4856 +4857 +4852 +4854 +4860 +4863 +4887 +4878 +4879 +4880 +4893 +4888 +4891 +4892 +4896 +4897 +4900 +4905 +4903 +4909 +4927 +4942 +4946 +4952 +4970 +4971 +4987 +4990 +4991 +4990 +4989 +4988 +4989 +4995 +4996 +5004 +5003 +5005 +5009 +4997 +4981 +4977 +4979 +4982 +4984 +4994 +5005 +5009 +5008 +5036 +5034 +5033 +5030 +5032 +5034 +5030 +5031 +5034 +5070 +5072 +5071 +5073 +5077 +5078 +5070 +5084 +5085 +5091 +5071 +5080 +5075 +5070 +5067 +5072 +5075 +5082 +5085 +5091 +5104 +5120 +5123 +5122 +5105 +5120 +5128 +5116 +5118 +5122 +5120 +5140 +5142 +5145 +5148 +5152 +5153 +5154 +5157 +5172 +5179 +5177 +5185 +5191 +5200 +5201 +5207 +5205 +5206 +5198 +5205 +5186 +5188 +5197 +5194 +5203 +5204 +5205 +5208 +5214 +5220 +5219 +5224 +5227 +5241 +5233 +5253 +5283 +5287 +5291 +5289 +5296 +5297 +5294 +5288 +5289 +5290 +5278 +5290 +5288 +5294 +5295 +5294 +5292 +5289 +5299 +5283 +5285 +5290 +5289 +5291 +5302 +5304 +5305 +5315 +5316 +5323 +5337 +5341 +5345 +5346 +5358 +5361 +5367 +5348 +5354 +5344 +5339 +5342 +5341 +5354 +5356 +5355 +5354 +5355 +5356 +5342 +5348 +5350 +5351 +5355 +5378 +5380 +5404 +5405 +5407 +5417 +5419 +5411 +5412 +5413 +5416 +5420 +5391 +5377 +5386 +5387 +5390 +5383 +5385 +5384 +5390 +5389 +5390 +5409 +5414 +5424 +5427 +5428 +5430 +5443 +5435 +5430 +5427 +5428 +5422 +5452 +5460 +5464 +5465 +5472 +5473 +5481 +5480 +5481 +5482 +5483 +5493 +5495 +5492 +5501 +5517 +5519 +5527 +5532 +5529 +5532 +5542 +5532 +5550 +5551 +5560 +5543 +5549 +5555 +5554 +5555 +5552 +5562 +5563 +5564 +5566 +5568 +5571 +5549 +5556 +5557 +5563 +5564 +5567 +5563 +5570 +5559 +5580 +5585 +5568 +5569 +5562 +5578 +5579 +5565 +5567 +5583 +5584 +5592 +5590 +5593 +5595 +5594 +5597 +5582 +5588 +5594 +5596 +5598 +5597 +5595 +5605 +5593 +5590 +5599 +5603 +5597 +5632 +5621 +5624 +5628 +5634 +5662 +5663 +5666 +5674 +5678 +5677 +5678 +5679 +5680 +5681 +5687 +5690 +5685 +5684 +5683 +5689 +5690 +5691 +5689 +5694 +5698 +5701 +5698 +5733 +5757 +5767 +5794 +5812 +5804 +5802 +5810 +5826 +5856 +5855 +5860 +5861 +5846 +5865 +5885 +5874 +5883 +5888 +5892 +5894 +5877 +5840 +5841 +5814 +5815 +5818 +5821 +5822 +5819 +5818 +5842 +5849 +5850 +5851 +5854 +5856 +5854 +5851 +5864 +5866 +5867 +5871 +5874 +5879 +5888 +5886 +5890 +5894 +5889 +5875 +5863 +5847 +5857 +5853 +5858 +5859 +5862 +5867 +5862 +5866 +5874 +5875 +5894 +5897 +5877 +5886 +5887 +5891 +5881 +5886 +5885 +5886 +5887 +5888 +5892 +5891 +5903 +5902 +5901 +5902 +5903 +5908 +5905 +5912 +5914 +5920 +5927 +5916 +5917 +5918 +5921 +5931 +5939 +5942 +5943 +5949 +5962 +5990 +5985 +5982 +5980 +5979 +5990 +5995 +6012 +6029 +6038 +6050 +6051 +6057 +6052 +6061 +6060 +6050 +6058 +6059 +6060 +6064 +6065 +6092 +6091 +6090 +6089 +6085 +6101 +6107 +6110 +6109 +6120 +6117 +6110 + diff --git a/adventOfCode/2021/2.go b/adventOfCode/2021/2.go new file mode 100644 index 0000000..8e02ae0 --- /dev/null +++ b/adventOfCode/2021/2.go @@ -0,0 +1,61 @@ +// Day 2 +package main + +import ( + //"fmt" + "strings" + "strconv" +) + +func solve2(input []interface{}) (int, int) { + + var day2Inputs []map[string]int + + // Customize input + for _, val := range input { + dirAndDist := strings.Split(val.(string), " ") + distance, err := strconv.Atoi(dirAndDist[1]) + if err != nil { panic(err) } + day2Inputs = append(day2Inputs, map[string]int{ dirAndDist[0]: distance}) + } + + directions := map[string]int{ + "forward": 1, + "down": 1, + "up": -1, + } + + // Solution 1 + sol1 := 0 + hori := 0 + dept := 0 + for _, i := range day2Inputs { + for dir, dist := range i { + if dir == "forward" { + hori += dist * directions[dir] + } else { + dept += dist * directions[dir] + } + } + } + sol1 = hori * dept + + // Solution 2 + sol2 := 0 + hori = 0 + dept = 0 + aim := 0 + for _, i := range day2Inputs { + for dir, dist := range i { + if dir == "forward" { + hori += dist * directions[dir] + dept += dist * aim + } else { + aim += dist * directions[dir] + } + } + } + sol2 = hori * dept + + return sol1, sol2 +} \ No newline at end of file diff --git a/adventOfCode/2021/2/2-sample.input b/adventOfCode/2021/2/2-sample.input new file mode 100644 index 0000000..b7172ac --- /dev/null +++ b/adventOfCode/2021/2/2-sample.input @@ -0,0 +1,6 @@ +forward 5 +down 5 +forward 8 +up 3 +down 8 +forward 2 diff --git a/adventOfCode/2021/2/2.input b/adventOfCode/2021/2/2.input new file mode 100644 index 0000000..f402851 --- /dev/null +++ b/adventOfCode/2021/2/2.input @@ -0,0 +1,1000 @@ +forward 1 +down 3 +down 2 +up 1 +down 7 +down 8 +forward 6 +forward 1 +forward 1 +down 6 +up 3 +down 7 +down 1 +down 6 +forward 6 +down 6 +forward 3 +up 7 +forward 5 +down 4 +forward 6 +forward 1 +forward 6 +forward 9 +forward 3 +up 1 +forward 7 +down 9 +forward 2 +up 9 +down 5 +down 3 +up 1 +down 6 +down 7 +down 8 +down 7 +forward 7 +forward 3 +down 5 +down 2 +forward 4 +forward 7 +down 8 +down 4 +down 5 +down 1 +forward 4 +up 6 +forward 6 +forward 4 +forward 5 +up 3 +up 6 +down 4 +down 8 +forward 4 +forward 5 +down 3 +forward 1 +down 5 +down 5 +forward 8 +forward 9 +forward 1 +forward 8 +forward 5 +forward 6 +up 8 +down 3 +forward 8 +up 2 +down 3 +down 9 +up 9 +forward 5 +down 2 +forward 7 +forward 5 +forward 5 +down 2 +down 3 +forward 7 +forward 9 +down 9 +forward 3 +forward 3 +down 3 +forward 3 +up 6 +down 4 +forward 3 +forward 3 +forward 7 +down 4 +forward 8 +up 8 +down 3 +down 2 +forward 2 +down 6 +down 6 +up 7 +up 9 +down 4 +up 7 +up 8 +down 6 +down 1 +forward 6 +forward 9 +forward 1 +forward 8 +down 4 +up 3 +forward 6 +down 5 +forward 7 +forward 5 +down 2 +forward 7 +down 6 +forward 7 +up 2 +up 5 +forward 3 +down 6 +down 9 +down 9 +forward 9 +up 7 +down 6 +down 4 +down 8 +forward 6 +up 6 +down 2 +forward 5 +up 7 +forward 5 +down 1 +up 8 +forward 2 +forward 4 +down 5 +down 8 +up 7 +up 5 +down 2 +forward 8 +forward 4 +up 6 +forward 8 +down 3 +down 2 +down 2 +forward 4 +forward 2 +forward 9 +up 3 +up 7 +up 3 +up 5 +forward 5 +up 8 +forward 3 +forward 1 +down 3 +down 8 +forward 6 +forward 5 +up 5 +down 9 +down 1 +down 9 +forward 9 +up 3 +forward 7 +forward 6 +forward 1 +up 3 +forward 9 +forward 7 +down 9 +up 6 +forward 2 +up 9 +forward 6 +forward 4 +up 3 +forward 5 +down 4 +up 8 +up 4 +up 9 +down 1 +down 7 +forward 7 +forward 2 +down 9 +forward 7 +forward 2 +down 6 +down 9 +up 6 +down 7 +down 2 +down 7 +down 6 +down 4 +down 4 +forward 6 +forward 9 +forward 4 +down 7 +down 5 +up 6 +down 7 +forward 2 +down 3 +down 1 +forward 1 +forward 5 +down 4 +down 4 +down 1 +down 9 +forward 6 +down 3 +forward 5 +up 7 +forward 9 +down 8 +down 3 +up 2 +up 2 +forward 4 +down 7 +forward 2 +forward 5 +forward 4 +forward 3 +down 8 +down 6 +forward 9 +down 1 +forward 1 +down 1 +up 8 +down 2 +forward 2 +up 5 +down 7 +forward 8 +down 7 +down 4 +forward 2 +forward 6 +up 2 +forward 8 +forward 2 +forward 1 +up 5 +down 4 +down 8 +forward 4 +down 8 +up 8 +forward 3 +down 5 +forward 2 +forward 1 +up 3 +forward 9 +up 5 +forward 5 +forward 5 +up 8 +down 6 +forward 3 +down 4 +up 5 +forward 3 +up 6 +forward 6 +forward 9 +down 7 +down 7 +down 8 +down 4 +forward 4 +forward 3 +forward 3 +forward 5 +down 3 +forward 8 +up 5 +forward 1 +up 7 +down 5 +forward 7 +forward 3 +down 3 +forward 2 +forward 1 +forward 4 +up 2 +down 8 +forward 9 +forward 9 +down 6 +down 1 +down 5 +forward 4 +down 2 +forward 1 +up 7 +down 9 +forward 3 +down 5 +down 5 +up 6 +down 6 +forward 8 +down 1 +up 3 +down 2 +up 1 +forward 5 +down 4 +down 6 +forward 8 +down 4 +down 5 +down 2 +forward 5 +forward 8 +down 8 +up 4 +forward 2 +up 2 +down 9 +forward 6 +forward 1 +forward 5 +up 2 +down 1 +up 7 +up 3 +forward 3 +down 7 +forward 2 +forward 4 +up 7 +forward 4 +forward 6 +up 2 +forward 4 +forward 2 +down 6 +down 5 +down 5 +down 6 +forward 9 +up 4 +down 4 +down 7 +up 6 +up 9 +up 4 +down 4 +up 7 +down 9 +down 9 +forward 3 +down 7 +down 7 +down 7 +down 2 +up 2 +up 1 +up 6 +down 8 +up 7 +down 4 +forward 8 +down 7 +up 1 +down 5 +down 3 +forward 6 +up 1 +down 5 +forward 3 +forward 6 +forward 7 +forward 2 +down 3 +forward 1 +up 9 +down 5 +up 2 +up 9 +up 2 +up 2 +forward 1 +down 2 +forward 1 +down 7 +forward 1 +forward 8 +down 9 +down 1 +forward 9 +forward 7 +forward 7 +down 5 +down 5 +down 3 +forward 6 +down 7 +down 4 +forward 2 +up 6 +down 3 +up 4 +up 7 +forward 2 +forward 8 +forward 4 +down 7 +down 9 +up 1 +down 2 +up 8 +down 2 +up 6 +forward 6 +up 5 +down 2 +forward 5 +down 4 +forward 7 +down 3 +down 5 +forward 1 +down 7 +forward 1 +up 1 +forward 4 +up 4 +forward 4 +forward 5 +forward 7 +down 7 +down 2 +up 4 +down 2 +down 3 +forward 3 +forward 2 +forward 5 +forward 2 +up 8 +forward 3 +down 7 +down 9 +forward 3 +forward 6 +down 7 +down 5 +down 3 +up 3 +forward 5 +forward 2 +down 1 +up 1 +up 8 +down 6 +down 4 +down 1 +forward 1 +down 7 +up 8 +forward 2 +forward 8 +forward 8 +forward 7 +down 1 +forward 8 +down 8 +forward 4 +down 3 +up 9 +down 8 +forward 9 +down 7 +up 2 +forward 9 +down 4 +up 3 +up 4 +up 4 +forward 5 +up 2 +forward 3 +down 5 +forward 5 +down 5 +up 8 +down 4 +forward 6 +down 6 +forward 7 +forward 2 +down 2 +up 7 +down 5 +down 9 +down 8 +down 4 +up 3 +forward 4 +down 8 +down 8 +down 9 +down 7 +forward 2 +forward 8 +up 5 +forward 8 +down 9 +forward 6 +up 1 +down 6 +forward 1 +up 4 +down 3 +forward 3 +forward 2 +down 6 +forward 7 +up 6 +up 9 +down 1 +forward 3 +forward 4 +forward 2 +up 8 +forward 9 +up 7 +down 2 +forward 2 +up 7 +down 2 +up 6 +down 2 +forward 9 +forward 3 +down 6 +down 5 +down 3 +forward 9 +down 8 +down 8 +down 2 +down 7 +up 3 +forward 1 +down 7 +up 8 +up 8 +forward 5 +forward 5 +forward 1 +down 8 +down 6 +forward 2 +up 3 +forward 1 +forward 7 +forward 4 +forward 5 +forward 9 +forward 7 +forward 6 +forward 3 +forward 4 +down 8 +down 1 +forward 6 +forward 9 +forward 6 +forward 9 +forward 6 +up 3 +down 8 +forward 4 +forward 1 +down 4 +forward 9 +down 8 +down 3 +up 2 +forward 5 +forward 2 +forward 5 +down 6 +down 3 +up 1 +down 9 +up 5 +forward 6 +down 7 +forward 1 +forward 9 +down 2 +down 5 +forward 3 +forward 6 +down 4 +down 5 +up 4 +forward 7 +forward 5 +down 8 +forward 6 +down 5 +forward 2 +down 7 +forward 4 +forward 8 +down 8 +forward 2 +forward 8 +down 5 +forward 7 +down 8 +down 1 +forward 8 +down 4 +up 4 +down 7 +down 6 +up 5 +forward 4 +forward 1 +forward 4 +down 5 +forward 5 +forward 9 +down 1 +forward 3 +up 7 +down 1 +down 7 +forward 2 +down 5 +down 6 +forward 5 +up 2 +down 9 +forward 1 +up 5 +forward 6 +forward 9 +forward 4 +up 4 +down 6 +up 9 +up 5 +down 2 +up 9 +down 2 +down 4 +down 8 +down 2 +forward 2 +forward 2 +down 9 +up 5 +forward 2 +forward 8 +down 2 +down 2 +down 9 +down 3 +down 9 +up 9 +up 3 +down 1 +down 9 +down 2 +forward 7 +down 2 +up 3 +down 9 +up 2 +up 4 +forward 5 +forward 7 +down 7 +up 7 +up 5 +down 8 +up 2 +forward 2 +down 3 +down 5 +forward 2 +forward 3 +forward 3 +down 1 +down 1 +forward 9 +down 5 +down 7 +forward 7 +forward 5 +up 9 +forward 3 +up 4 +forward 1 +forward 3 +down 4 +forward 9 +down 5 +down 3 +down 5 +forward 6 +down 6 +forward 2 +up 4 +down 4 +forward 2 +down 8 +up 9 +forward 9 +forward 4 +down 8 +forward 2 +forward 5 +forward 1 +forward 5 +up 1 +forward 7 +forward 9 +down 5 +forward 6 +down 1 +forward 6 +down 2 +forward 9 +down 1 +forward 1 +down 4 +down 6 +down 2 +up 7 +up 5 +forward 8 +forward 1 +down 8 +forward 1 +forward 2 +down 8 +forward 7 +down 5 +forward 1 +down 2 +up 7 +forward 7 +down 4 +down 8 +up 6 +up 4 +forward 7 +down 3 +up 5 +down 5 +forward 7 +up 7 +down 6 +forward 8 +down 7 +down 2 +up 3 +down 9 +down 7 +down 8 +forward 4 +forward 3 +forward 9 +forward 6 +up 7 +forward 5 +down 4 +down 5 +forward 6 +up 9 +down 6 +down 7 +down 8 +down 9 +down 4 +up 5 +down 4 +forward 5 +forward 3 +down 3 +down 7 +up 8 +forward 5 +down 8 +down 1 +down 6 +down 9 +up 4 +up 1 +down 8 +down 3 +down 8 +up 4 +down 7 +down 6 +forward 7 +up 9 +down 4 +down 1 +down 6 +down 2 +forward 7 +down 2 +down 7 +forward 3 +forward 6 +up 2 +down 4 +up 1 +forward 4 +up 2 +down 4 +up 3 +down 8 +up 9 +forward 8 +down 5 +down 4 +forward 8 +down 1 +down 8 +forward 3 +down 4 +forward 5 +down 5 +up 9 +forward 1 +down 9 +down 1 +forward 4 +forward 9 +up 1 +forward 4 +forward 2 +down 9 +down 1 +forward 1 +down 2 +forward 2 +down 5 +up 4 +up 7 +down 8 +forward 3 +up 1 +down 4 +forward 5 +up 2 +forward 4 +forward 2 +down 1 +forward 4 +forward 1 +up 5 +forward 8 +forward 4 +forward 1 +down 6 +down 7 +up 4 +forward 9 +up 6 +forward 9 +forward 3 +forward 2 +down 2 +forward 7 +up 7 +forward 7 +down 4 +down 6 +forward 8 +up 8 +forward 1 +forward 3 +forward 3 +up 8 +down 1 +up 9 +forward 1 +up 1 +down 7 +forward 7 +up 5 +forward 5 +up 9 +up 3 +forward 2 +forward 6 +up 1 +forward 5 +up 1 +down 3 +down 5 +forward 8 +up 5 +forward 1 +down 8 +forward 4 +down 3 +down 1 +down 7 +forward 7 +forward 3 +down 4 +forward 9 +up 5 +down 2 +forward 4 +up 7 +up 5 +forward 3 +down 7 +forward 8 +up 4 +up 2 +forward 2 +down 9 +forward 4 +down 5 +forward 2 +down 9 +down 5 +up 7 +forward 3 +down 8 +forward 7 +forward 9 +down 5 +forward 2 +forward 9 +forward 5 +down 5 +up 4 +down 6 +down 6 +forward 8 +forward 5 +forward 4 +down 5 +forward 2 +down 8 +forward 9 +down 1 +down 8 +down 7 +up 9 +down 7 +down 1 +forward 7 +forward 9 +forward 8 +up 2 +forward 6 +down 3 +down 6 +up 4 +forward 4 +forward 5 +down 9 +down 5 +forward 1 +down 2 +forward 1 +down 1 +up 1 +up 7 +up 5 +forward 6 +forward 3 diff --git a/adventOfCode/2021/3.go b/adventOfCode/2021/3.go new file mode 100644 index 0000000..4cb1948 --- /dev/null +++ b/adventOfCode/2021/3.go @@ -0,0 +1,180 @@ +// Day 3 +package main + +import ( + "fmt" + "strconv" + mapset "github.com/deckarep/golang-set" +) + +func solve3(input []interface{}) (int, int) { + + var day3Inputs []string + + // Customize input + for _, val := range input { + if val == "" { continue } + day3Inputs = append(day3Inputs, val.(string)) + } + + // Solution 1 + sol1 := 0 + n := len(day3Inputs) + numOnes := []int{} + gamma := "" + epilson := "" + for _, val := range day3Inputs { + for i := 0; i < len(val); i++ { + if val[i] == 49 { + if i >= len(numOnes) { + numOnes = append(numOnes, 1) + } else { + numOnes[i] += 1 + } + } + } + } + + for _, i := range numOnes { + if i >= n/2 { + gamma += "1" + epilson += "0" + } else { + gamma += "0" + epilson += "1" + } + } + + gammaInt, err := strconv.ParseInt(gamma, 2, 64) + if err != nil { + panic(err) + } + epilsonInt, err := strconv.ParseInt(epilson, 2, 64) + if err != nil { + panic(err) + } + sol1 = int(gammaInt * epilsonInt) + + // Solution 2 + sol2 := 0 + + + oxygen := mapset.NewSet() + positionZeros, positionOnes := getCounts(day3Inputs) + var ov, zv mapset.Set + index := 0 + + for oxygen.Cardinality() != 1 { + + ov = positionOnes[index] + zv = positionZeros[index] + + //fmt.Println(index, ov, zv) + + if ov.Cardinality() >= zv.Cardinality() { + if oxygen.Cardinality() == 0 { + oxygen = ov + } else { + oxygen = oxygen.Intersect(ov) + } + } else { + if oxygen.Cardinality() == 0 { + oxygen = zv + } else { oxygen = oxygen.Intersect(zv) } + } + + // Fail safe + if oxygen.Cardinality() == 0 { + fmt.Print("something wrong") + break + } + index += 1 + //fmt.Println("---->", index, oxygen) + + oslice := oxygen.ToSlice() + var oxy []string + for _, i := range oslice { + oxy = append(oxy, i.(string)) + } + positionZeros, positionOnes = getCounts(oxy) + } + + co2 := mapset.NewSet() + positionZeros, positionOnes = getCounts(day3Inputs) + index = 0 + + for co2.Cardinality() != 1 { + + ov = positionOnes[index] + zv = positionZeros[index] + + //fmt.Println(index, ov, zv) + + if ov.Cardinality() >= zv.Cardinality() { + if co2.Cardinality() == 0 { + co2 = zv + } else { + co2 = co2.Intersect(zv) + } + } else { + if co2.Cardinality() == 0 { + co2 = ov + } else { co2 = co2.Intersect(ov) } + } + + // Fail safe + if co2.Cardinality() == 0 { + fmt.Print("something wrong") + break + } + index += 1 + //fmt.Println("---->", index, co2) + + oslice := co2.ToSlice() + var oxy []string + for _, i := range oslice { + oxy = append(oxy, i.(string)) + } + positionZeros, positionOnes = getCounts(oxy) + } + + o2, err := strconv.ParseInt(oxygen.Pop().(string), 2, 64) + if err != nil { + panic(err) + } + + c2, err := strconv.ParseInt(co2.Pop().(string), 2, 64) + if err != nil { + panic(err) + } + + sol2 = int(o2*c2) + + return sol1, sol2 +} + + +func getCounts(inputs []string) (map[int]mapset.Set, map[int]mapset.Set) { + positionOnes := make(map[int]mapset.Set) + positionZeros := make(map[int]mapset.Set) + for _, val := range inputs { + for i := 0; i < len(val); i++ { + + // Add positions + if i >= len(positionOnes) { + positionOnes[i] = mapset.NewSet() + } + if i >= len(positionZeros) { + positionZeros[i] = mapset.NewSet() + } + + // Add to ones or zeros + if string(val[i]) == "1" { + positionOnes[i].Add(val) + } else { + positionZeros[i].Add(val) + } + } + } + return positionZeros, positionOnes +} \ No newline at end of file diff --git a/adventOfCode/2021/3/3-sample.input b/adventOfCode/2021/3/3-sample.input new file mode 100644 index 0000000..a6366a8 --- /dev/null +++ b/adventOfCode/2021/3/3-sample.input @@ -0,0 +1,12 @@ +00100 +11110 +10110 +10111 +10101 +01111 +00111 +11100 +10000 +11001 +00010 +01010 diff --git a/adventOfCode/2021/3/3.input b/adventOfCode/2021/3/3.input new file mode 100644 index 0000000..0cb01b7 --- /dev/null +++ b/adventOfCode/2021/3/3.input @@ -0,0 +1,1000 @@ +001110000001 +010100101000 +101101010010 +010111101010 +100011100110 +110100001011 +100010001100 +011110100110 +110011110000 +111010011001 +111100100011 +110101101010 +101001111100 +001110101110 +011100001110 +011000101101 +101100001000 +001010000111 +001100101001 +100001000011 +010010111011 +010101101010 +100111100001 +001011101000 +001110100100 +110001001011 +001101110111 +101100100010 +100110001111 +010111011111 +011111111101 +011111110011 +111011000001 +001000011110 +111001100001 +101111101100 +111000001011 +101110010111 +001111110001 +011110000010 +100101011101 +111000100010 +000110111100 +111010111100 +001110100011 +100111001100 +011111100101 +000010000110 +111111010011 +011000010011 +010101011011 +111110010000 +001100110110 +001111010100 +000100000100 +001100001011 +010010110010 +010010101101 +001111010101 +001111011000 +100101100000 +100101111100 +010010100011 +010001011101 +000101100010 +001101001100 +000001110111 +101101010000 +010100101101 +101011110100 +101010100111 +101001100100 +101001000010 +110110101110 +010010000111 +100001110110 +101011000010 +101000101000 +001101001011 +000011100010 +101111011101 +101100101110 +011001011101 +001101100110 +110101000011 +101001101100 +110000111111 +011000110010 +001101000011 +010001100111 +000101010110 +111100011100 +001011100011 +011110110100 +101000011101 +000010111010 +011011011101 +010100101110 +100110101011 +100110111001 +110000001010 +111000001110 +001110100110 +111010011011 +100000011000 +101010101110 +011000000001 +011011001011 +100110011011 +010101010000 +101111001101 +111100111010 +011110101111 +011100110000 +011010000011 +011010101011 +010110101011 +000000101010 +011101100101 +001001111111 +001000011000 +101001010101 +001010000000 +110110010101 +011100101101 +111010110011 +011000001101 +000000100000 +001110101111 +111010100011 +110101111101 +101001100101 +000111011011 +111011101011 +100110001101 +111100110000 +100000100110 +111100000111 +010011100101 +110011000000 +101001000100 +101001000110 +010111101000 +111100110100 +100111011100 +010000001011 +010100100001 +010100000100 +111000101100 +100100000101 +111111010000 +010101111010 +100000001011 +101101001000 +011100000101 +011001101011 +110100010101 +011010100010 +110110110010 +100001010000 +000100100111 +001111110011 +101111010000 +000110011101 +111110000101 +000101010011 +001011111101 +110111001111 +000011111110 +011111111000 +000100101100 +100100010100 +001011111110 +101000011000 +001011001000 +111110000111 +000100000011 +100001100001 +100001111010 +101001100111 +110010100110 +001111001001 +001111111011 +101100001111 +011100010111 +100001001001 +101101001011 +110110011010 +001110011110 +100100101000 +110110001111 +110011001101 +011011010100 +000011101010 +100000011010 +001010111000 +101001001100 +101100111101 +011010111000 +000100001001 +101101100001 +010010111101 +101110101001 +000100001101 +111101111000 +110110110111 +010101011010 +000010100100 +010000011100 +011100100110 +010001110000 +001010011000 +011101100111 +011001111001 +001101110000 +011010111010 +010100000101 +001011010110 +110011101111 +101010001100 +111111101000 +111001110000 +100010001000 +111101110001 +011001110100 +111010111000 +110010110010 +100100001001 +000000100100 +100010111111 +011001000010 +101110001001 +001101101011 +000111000101 +110000011000 +110010011111 +001010011110 +110111001110 +001111110010 +111011111110 +100010101101 +000010101000 +001100001100 +011011111010 +111110001010 +110101100111 +110111011011 +101110111000 +010001001011 +101011100101 +011100000000 +011110000110 +111001111001 +101111110111 +110110100110 +011111010111 +010110000100 +011011101100 +010011111001 +101001011100 +010000010101 +011110011001 +100011101111 +010000101111 +001101011001 +011100011100 +011111010101 +101011011001 +011110011011 +001010101111 +110000000100 +010010011010 +010110000110 +011111100001 +011011000110 +101011010011 +011001101001 +001100001001 +010011001011 +111111110110 +000111001011 +110011111100 +010010000001 +001110111000 +000110010101 +101011100111 +000101010111 +101101111011 +111100000010 +001110011111 +001100111010 +001010100011 +000000011000 +101100010101 +100011110111 +001000110011 +100010110010 +111100110101 +001010011010 +000000100011 +001001101010 +000010000001 +111001000010 +110111111101 +101001110011 +010001011000 +100001010101 +101111101111 +000011000111 +101110000101 +011000111110 +111010010000 +100111001001 +011111111100 +111111001011 +011101110101 +001100101010 +001111101000 +111101011111 +011001000111 +011101110010 +000011100000 +110101101011 +011110001010 +101001100001 +001101110110 +100101001100 +111011100101 +001101100100 +010010110001 +001000101111 +100110110001 +111001100110 +101110111101 +001010101100 +010011110111 +100000110011 +100101100100 +110111101011 +000111000111 +110100101000 +001110001001 +101110001010 +101110110010 +111110010100 +001110000110 +000011100100 +000101000010 +000011011100 +011111000110 +110011010111 +100101001111 +110101000010 +101011001101 +111110101001 +010011111000 +101111011011 +101111100100 +000110011001 +100011111001 +001110011100 +011100001001 +110111100001 +111011011010 +111001111011 +001100101000 +011000100000 +100011001110 +011110111001 +011011111110 +001000110010 +110000010001 +010001110110 +100110101100 +100111100101 +000111111000 +001101011011 +000111010110 +010100001101 +001010000101 +110010101101 +001111001111 +000001111001 +101010110111 +100110000100 +001100111011 +000010100001 +000100111111 +100001111111 +000011111000 +101110011010 +001011010001 +001011110001 +010011100110 +000010110010 +001010101001 +110110111100 +100111010110 +101001011001 +000100111110 +101111001010 +110100011111 +010100011100 +111110100011 +000010101100 +100000101010 +111111000000 +111111010110 +001100011011 +110001101001 +101010011110 +101010000010 +000000000111 +000100101110 +101000001011 +100011000001 +000100101101 +001000100000 +110111001011 +111001001111 +110011100110 +100001110100 +010111101100 +011000001010 +100101000000 +001101100001 +110001000111 +010111100011 +000100111101 +010111011101 +000001010111 +011001111110 +110101111001 +100010101001 +010110001010 +111010110001 +000000101001 +010100011110 +000010100010 +100011001000 +100110010111 +001011010100 +011010001010 +000001110101 +010010100000 +010111100101 +010101011101 +110100010010 +101101111100 +100001101101 +100011010110 +011011000101 +011100110101 +010010010100 +101001001110 +001110110010 +010110110101 +100100010101 +000011010100 +010000111000 +101110010011 +101101110111 +110000000010 +001011001010 +000111010011 +100110100010 +001110001111 +100110101110 +010001010010 +111001011001 +111000110111 +010111000001 +001111011010 +001000101010 +111011110001 +100001001110 +001010001011 +000011100001 +101010011101 +000110000110 +100111110010 +010010100001 +010101011000 +010001001100 +011100110100 +000010101010 +001110111001 +001100010011 +000101000101 +100010111000 +111011010011 +100011110100 +110100011000 +000010011111 +011111011001 +011011001111 +111101110000 +101111000110 +100111100000 +111100011101 +001100010000 +001100110101 +011010110100 +010000010100 +111010101111 +000010101101 +010110010110 +110011111110 +100101101001 +111100000000 +110111101100 +100100001000 +100100001011 +111001001011 +011010110011 +001101110011 +000100101001 +001111010011 +011000000110 +111100100110 +010010001001 +110101011000 +011001111111 +100111010101 +111010001000 +001111111001 +001100100110 +110010100010 +011101001000 +110111100000 +011010101000 +000101111010 +101010010110 +100111101010 +000010110000 +100000001100 +101000010000 +010101000011 +100111101100 +101000110110 +010010110110 +111011100011 +111100111011 +100010101111 +011011110111 +100001011110 +110000100101 +011000111101 +010110000001 +100010011110 +001111011100 +110001011110 +111110100101 +001110000111 +110111100011 +110100101010 +010101110001 +110101011101 +110110100101 +110010000100 +100110110100 +010100011101 +111101010101 +010101010011 +100100011000 +101100010110 +001000011111 +010011110001 +100101100001 +101100000101 +000100011010 +100100100011 +000101001111 +110100100101 +001111000010 +100000001110 +110100000001 +001010010000 +010001000110 +101010110001 +100010100001 +111011101101 +011011111011 +010011111010 +111100001001 +001101110010 +111110111011 +101110010100 +001110110111 +110000000110 +000011111100 +001110010000 +000010001001 +101101101110 +010101100110 +010000110000 +101111100011 +101000001111 +001100100111 +111111000010 +110000000101 +110001010100 +010011011000 +110100101111 +110100010100 +101000001000 +111010110111 +101000110001 +111110000110 +001111100000 +100100000110 +101011000100 +100100010110 +110001011001 +011011010010 +001110111011 +010100111111 +010000110100 +111011010001 +001011001110 +110110101011 +100110010000 +001111000100 +101101101011 +110110010110 +010011101110 +000110101000 +001010010111 +101111000010 +001101101111 +111001111100 +101010101011 +111101100010 +110101000110 +011110000111 +010101110100 +100110111100 +010001010101 +001101011110 +110100010001 +100100011001 +101111111111 +001001001111 +011011111000 +101010111100 +000011011110 +111010010001 +111111011011 +111101110111 +100011111000 +110001101101 +001011011000 +001000101011 +010000000101 +011011000100 +100001011011 +001001001101 +000110001101 +000011011000 +000011000001 +000010010111 +011011101001 +110101001111 +011000101010 +011110100101 +100000110101 +011011100110 +110010010010 +011110111011 +000101101010 +001010111110 +100101101111 +111110001100 +010100110000 +110111111100 +010010010000 +010011000001 +100101010011 +001110100010 +110101010010 +100000010110 +001101100111 +010110011011 +010111000101 +100110101101 +010010101010 +000101011100 +101000001101 +110111000010 +101000110010 +010111010001 +100011001011 +111111100010 +001101110101 +011100111111 +110001101111 +011101101010 +001000100011 +011001110111 +100111000110 +111011111111 +001000111001 +011100011110 +110010100011 +111101111101 +011011011110 +100000010000 +000001110100 +110110001000 +111111011010 +011110111010 +111000011100 +100101110010 +011100001100 +010011000111 +011110001101 +000101101000 +001011011010 +011011110000 +111100010010 +000010101111 +011101101111 +001001110000 +110111011100 +101000010001 +100110000110 +000010000101 +001000101110 +001001001001 +011111010000 +111100100101 +010101110111 +010110000011 +110000111011 +100100110111 +100111000001 +111100010011 +100010000100 +111011100000 +010111110100 +101100001011 +000010101001 +111110111101 +001011110010 +110000101110 +000010111110 +110111011001 +110111110100 +001110100001 +001101110001 +010001110011 +110101111000 +000110101100 +111011010100 +000100001100 +110001110101 +100000111110 +100010010111 +100101010001 +011011000111 +111011110110 +001001101001 +010011110101 +111110100111 +000110100001 +110011001110 +101001101110 +100100110100 +000001001001 +011111110100 +010001101110 +100101010111 +110011010100 +011101010010 +100010101011 +011111101101 +101100101000 +111110000001 +101010111010 +101110111001 +101011000111 +110100110010 +101011000001 +111001000001 +001011110000 +000110011010 +101111101001 +101110000000 +011101010001 +110110011101 +110101011111 +101110000001 +111100001111 +000111100101 +010001101101 +000011011010 +011010001111 +111010001101 +101011001001 +111001101001 +001100001101 +111110100010 +000111110101 +010111101110 +010101100000 +100010100011 +000001100001 +111111000110 +001111110100 +000001101100 +011011011100 +011110001011 +001010101000 +101111100110 +111000111011 +100101101000 +100110001010 +010111010110 +110110001101 +010001001111 +000011110011 +010000111110 +101000011001 +111000000100 +011010000111 +010010101110 +001100001111 +000010001000 +001101101001 +110101101110 +110010011011 +000101011000 +101011101000 +010000110101 +110110001010 +110110011110 +011111011100 +001001011011 +110000111100 +110101001100 +100100101110 +001000111100 +111101011001 +011111011010 +011101101100 +100011010000 +001100000001 +001011000111 +011011111100 +001100101101 +110010101111 +011101111100 +011110101101 +110100011010 +101100100001 +000111111100 +001010110010 +110101101100 +111100000101 +110011000011 +110100111010 +011000111010 +101000000101 +101010001000 +000100110111 +110101101000 +101001111101 +010010001010 +110111101001 +010111001000 +110101100011 +111111100000 +100010010010 +010011000100 +010100100110 +101101000001 +001010010001 +111100101110 +110011100001 +101000000111 +111010100110 +111111010111 +110010101011 +001011010000 +001001100110 +011111110110 +000010110100 +110010000111 +111001100011 +101101001110 +011001111101 +100111110111 +000100000111 +010000110011 +000110111111 +011011100001 +101001001011 +110011101001 +011110010010 +001010101011 +110000111001 +010100111110 +011110101110 +011001111100 +111111001100 +011000001111 +000001100100 +101010001011 +000010111001 +000101110111 +101100011111 +101001000111 +111001011100 +111010100111 +111011010010 +101101111010 +111100011001 +101111101101 +001010000110 +100001010111 +011101001101 +010000101001 +011110101011 +011101000111 +000101100001 +010011111011 +101101111110 +001000110100 +011100000110 +100010000110 +011110010011 +000011110000 +100000010011 +011100011010 +111110011110 +000111011000 +000000001000 +001010110101 +110011111010 +001101100000 +001000000110 +110111111011 +001000010110 +001010000011 +101101011010 +011001100101 +001000010111 +100010111010 +011101101001 +101010000111 +001100111111 +111000000111 +001111011111 +000100001010 +101111111000 +010111100001 +010110010111 +111001010011 +001111001011 +000001010101 +100111111101 +010110100100 +011101010110 +110001010010 +010110010101 +010101000101 +100010111011 +001011101010 +011011110001 +100111110001 +000001111101 +111111111011 +000010010110 +101011010000 +010011010011 +110000001111 +010010001100 +100101001011 +101111001100 +111111001110 +010100101001 +010001111110 +011010011100 +111100011110 +010110100010 +100011011001 +001110000100 +011001111000 +110010010001 +010011001110 +011010100111 +010100101100 +101001011011 +110011110001 +100011000000 +000011111101 +000010110110 +001011011110 +010001011110 +001101010010 diff --git a/adventOfCode/2021/4.go b/adventOfCode/2021/4.go new file mode 100644 index 0000000..ec55a0a --- /dev/null +++ b/adventOfCode/2021/4.go @@ -0,0 +1,149 @@ +// Day 4 +package main + +import ( + //"fmt" + "strings" + "strconv" +) + +func returnProcessedInputs(input []interface{}) ([]int, [][][]int) { + var day4NumbersDraw []int + var dar4Cards [][][]int + + // Customize input + day4NumbersDrawString := strings.Split(input[0].(string), ",") + for _, val := range day4NumbersDrawString { + stripedInt := strings.TrimSpace(val) + inte, err := strconv.Atoi(stripedInt) + if err != nil { + panic(err) + } + day4NumbersDraw = append(day4NumbersDraw, inte) + } + + current_card := [][]int{} + for index, val := range input { + if index == 0 { continue } + if (index-1)%5 == 0 { + if len(current_card) > 0 { + dar4Cards = append(dar4Cards, current_card) + } + current_card = [][]int{} + } + curr_row := []int{} + elements := strings.Split(val.(string), " ") + for _, e := range elements { + stripedInt := strings.TrimSpace(e) + if stripedInt == "" { + continue + } + inte, err := strconv.Atoi(stripedInt) + if err != nil { + panic(err) + } + curr_row = append(curr_row, inte) + } + current_card = append(current_card, curr_row) + } + dar4Cards = append(dar4Cards, current_card) + + return day4NumbersDraw, dar4Cards +} + +func verifyWinner(card [][]int) bool { + for i, _ := range card { + rowWin := 0 + colWin := 0 + for j, _ := range card[i] { + if card[i][j] == -1 { + rowWin += 1 + } + if card[j][i] == -1 { + colWin += 1 + } + } + //fmt.Print(rowWin, colWin, len(card[i])) + if rowWin == len(card[i]) || colWin == len(card[i]) { + return true + } + } + return false +} + +func markCard(card [][]int, draw int) [][]int { + //fmt.Println("before marking: ", draw, card) + for i, _ := range card { + for j, _ := range card[i] { + if card[i][j] == draw { + card[i][j] = -1 + } + if card[j][i] == draw { + card[j][i] = -1 + } + } + } + //fmt.Println("after marking: ", draw, card) + return card +} + +func addAllNonVisited(card [][]int) int { + total := 0 + for i, _ := range card { + for j, _ := range card[i] { + if card[i][j] != -1 { + total += card[i][j] + } + } + } + return total +} + +func solve4(input []interface{}) (int, int) { + + day4NumbersDraw, dar4Cards := returnProcessedInputs(input) + + // Solution 1 + sol1 := 0 + winnerDraw := -1 + winnerCardNo := -1 + for _, draw := range day4NumbersDraw { + for i, _ := range dar4Cards { + dar4Cards[i] = markCard(dar4Cards[i], draw) + if verifyWinner(dar4Cards[i]) { + winnerDraw = draw + winnerCardNo = i + break + } + } + if winnerDraw != -1 { + break + } + } + //fmt.Println("winner:", dar4Cards, winnerDraw) + sol1 = addAllNonVisited(dar4Cards[winnerCardNo]) * winnerDraw + + // Solution 2 + sol2 := 0 + winnerCardsDraw := make(map[int]int) + winnerCard := -1 + for _, draw := range day4NumbersDraw { + for i, _ := range dar4Cards { + dar4Cards[i] = markCard(dar4Cards[i], draw) + if verifyWinner(dar4Cards[i]) { + if _, ok := winnerCardsDraw[i]; !ok { + if len(winnerCardsDraw) == len(dar4Cards)-1 { + winnerCard = i + } + winnerCardsDraw[i] = draw + } + } + } + if winnerCard != -1 { + break + } + } + sol2 = addAllNonVisited(dar4Cards[winnerCard]) * winnerCardsDraw[winnerCard] + + return sol1, sol2 +} \ No newline at end of file diff --git a/adventOfCode/2021/4/4-sample.input b/adventOfCode/2021/4/4-sample.input new file mode 100644 index 0000000..49d17bc --- /dev/null +++ b/adventOfCode/2021/4/4-sample.input @@ -0,0 +1,19 @@ +7,4,9,5,11,17,23,2,0,14,21,24,10,16,13,6,15,25,12,22,18,20,8,19,3,26,1 + +22 13 17 11 0 + 8 2 23 4 24 +21 9 14 16 7 + 6 10 3 18 5 + 1 12 20 15 19 + + 3 15 0 2 22 + 9 18 13 17 5 +19 8 7 25 23 +20 11 10 24 4 +14 21 16 12 6 + +14 21 17 24 4 +10 16 15 9 19 +18 8 23 26 20 +22 11 13 6 5 + 2 0 12 3 7 \ No newline at end of file diff --git a/adventOfCode/2021/4/4.input b/adventOfCode/2021/4/4.input new file mode 100644 index 0000000..e5d6094 --- /dev/null +++ b/adventOfCode/2021/4/4.input @@ -0,0 +1,601 @@ +79,9,13,43,53,51,40,47,56,27,0,14,33,60,61,36,72,48,83,42,10,86,41,75,16,80,15,93,95,45,68,96,84,11,85,63,18,31,35,74,71,91,39,88,55,6,21,12,58,29,69,37,44,98,89,78,17,64,59,76,54,30,65,82,28,50,32,77,66,24,1,70,92,23,8,49,38,73,94,26,22,34,97,25,87,19,57,7,2,3,46,67,90,62,20,5,52,99,81,4 + + 7 42 22 92 60 + 8 88 99 13 12 +16 62 86 24 77 +20 57 19 67 46 +36 83 54 63 82 + + 7 86 50 78 16 +83 45 67 94 58 +21 98 99 85 43 +71 19 31 22 4 +70 51 34 11 61 + + 4 95 84 51 36 +43 40 37 23 85 +14 90 8 59 99 + 0 88 68 93 81 +25 6 55 19 48 + +15 39 78 6 13 +71 3 81 95 62 +22 46 67 72 40 +89 69 0 37 41 +68 79 58 16 42 + +63 50 77 34 12 +29 42 20 17 47 +80 10 30 72 66 + 5 89 64 25 21 +91 88 45 44 37 + +78 89 32 26 56 + 8 40 54 25 49 +36 30 21 23 3 +12 58 2 29 7 +33 99 15 84 44 + +96 68 56 49 43 +55 22 16 91 32 + 2 17 61 12 37 +25 72 1 31 88 +57 34 42 8 71 + +18 39 86 94 60 +96 85 64 51 28 +48 14 23 36 35 + 6 84 99 90 81 +43 41 74 68 32 + + 9 58 60 7 61 +96 33 67 0 19 +77 2 14 99 79 +13 36 90 95 29 +86 91 49 72 20 + + 3 79 24 37 97 +86 10 77 31 32 +48 89 35 73 94 +65 21 23 82 36 +26 51 69 12 99 + +66 28 73 6 32 +11 30 35 42 76 +33 40 25 89 52 +46 88 55 50 64 +86 71 75 36 80 + +36 34 35 68 49 +61 3 24 84 71 +47 42 91 39 80 +25 51 38 59 62 +90 21 28 52 8 + +19 93 45 40 55 +41 11 79 9 70 +16 87 32 22 94 +12 4 72 60 0 +36 77 78 33 83 + +43 44 7 39 96 +30 75 62 63 8 +19 12 40 68 45 +50 27 3 52 57 +85 67 33 16 36 + +33 16 66 9 7 +93 34 52 31 13 + 3 49 94 39 37 +76 59 78 51 83 +40 47 22 42 73 + +44 60 52 7 38 +36 53 79 11 93 +46 65 40 68 58 +67 73 99 31 87 +22 49 33 59 75 + +83 61 17 60 86 +38 33 96 75 22 +19 42 76 55 97 +93 94 29 50 88 +34 16 91 3 40 + +92 48 40 69 98 +12 46 37 25 78 +43 11 34 22 32 + 0 18 17 86 1 +89 26 65 76 96 + +66 48 43 99 98 +68 2 51 87 38 +72 77 47 20 97 +36 18 80 10 96 +88 53 30 65 91 + +10 3 65 38 56 +40 14 64 45 23 +42 88 31 85 17 +19 83 46 51 5 +35 47 28 0 50 + +75 53 9 1 29 +92 94 41 82 38 +39 70 80 11 56 +64 28 27 22 60 +66 97 48 65 71 + +91 17 37 49 83 +66 1 79 87 60 +78 46 32 30 57 +50 56 23 6 24 +13 89 42 70 77 + +59 28 58 56 73 +22 4 53 91 23 + 8 41 36 52 80 +30 68 34 70 63 +90 3 61 98 1 + +50 76 99 74 81 +57 25 59 69 96 +26 15 43 64 44 +73 18 61 91 23 +87 13 46 90 60 + +63 1 77 93 47 +12 90 56 46 0 +57 73 79 87 43 +32 13 53 37 14 +22 3 23 78 69 + +49 55 93 57 2 +67 12 81 70 79 +60 44 94 23 54 +48 92 99 1 82 +76 36 62 32 98 + +94 15 97 55 17 +39 40 84 92 49 +72 45 52 95 96 +61 58 88 23 78 +80 48 37 35 66 + +86 88 20 12 7 +72 52 95 34 11 + 1 47 83 63 18 +25 35 76 15 92 +96 64 82 54 31 + +61 83 5 24 36 +88 80 48 26 85 + 2 42 70 98 45 +27 6 65 94 15 +71 73 3 47 38 + +85 49 19 41 53 + 4 99 43 93 60 +34 28 78 23 50 +54 79 35 25 94 +27 63 16 51 39 + +89 49 13 1 32 +85 87 8 38 64 +14 5 63 16 27 +23 76 43 59 94 +78 80 83 15 54 + +26 66 73 74 64 + 9 81 62 75 25 +46 13 55 43 1 + 0 2 10 58 34 +76 11 82 42 16 + +68 93 18 99 84 +96 25 44 69 97 +24 80 74 27 6 +33 14 54 17 28 +10 47 2 63 59 + +12 56 29 63 0 +30 94 5 19 18 + 9 13 24 72 60 +91 46 49 47 51 + 8 54 26 7 21 + +36 16 26 97 56 +22 86 58 94 89 +66 84 50 82 53 +87 29 45 95 33 +49 61 46 2 52 + +87 35 65 27 69 +12 98 94 18 26 +22 79 1 74 84 + 0 72 29 70 19 +96 28 95 25 77 + +79 95 3 91 44 +57 61 77 80 29 + 6 49 37 62 16 +71 73 21 52 48 +92 17 32 2 43 + +29 78 6 94 47 +83 63 68 16 56 +38 85 92 60 35 +81 57 75 79 7 +69 22 93 49 4 + +93 21 2 17 22 +76 70 3 80 51 + 7 88 14 0 61 +18 16 29 86 74 +65 47 8 45 46 + + 1 20 23 79 14 +27 76 3 90 85 +88 35 7 10 92 +67 97 59 41 8 +56 57 65 45 81 + +57 14 41 89 55 +47 75 90 23 94 +26 3 40 17 97 +65 44 12 4 30 +16 81 64 79 13 + +63 3 22 7 10 +36 76 14 77 38 +48 27 40 9 60 +31 56 75 74 78 +86 64 71 90 67 + +52 28 9 19 66 +15 86 61 2 89 +93 3 44 46 91 +11 7 5 32 72 +60 10 92 29 88 + +88 86 59 8 68 +10 48 12 61 21 +54 97 45 55 11 +67 9 22 64 5 + 7 34 32 69 44 + +69 45 14 6 3 +16 32 33 26 73 +79 30 5 1 72 +64 9 60 59 22 +23 56 37 41 2 + +25 65 60 87 39 +41 53 24 91 93 +43 59 26 78 96 +16 33 88 18 7 +74 63 34 30 20 + +38 23 97 73 35 +51 31 90 98 80 +56 44 60 8 7 +71 10 87 0 99 +64 30 20 22 18 + +61 57 31 69 74 +94 0 96 90 59 +21 3 72 81 4 +43 41 58 45 2 +62 7 65 71 19 + +60 20 19 48 11 + 2 68 58 91 76 +57 12 52 29 13 +42 53 38 64 81 +26 70 16 32 54 + +15 93 68 77 49 +80 64 45 10 94 +30 62 5 66 40 +46 51 52 22 56 + 7 90 14 6 47 + +75 87 31 24 11 +47 61 14 69 50 +33 44 12 26 58 +91 10 35 5 29 +99 81 16 92 53 + +50 37 47 13 83 +63 96 30 36 86 +72 66 93 73 74 +98 60 3 84 28 +52 14 70 21 55 + +65 19 32 28 92 + 9 8 51 0 98 +56 26 53 13 86 + 2 70 16 52 4 +69 10 97 38 79 + +34 48 46 66 44 +59 19 18 20 13 +99 26 62 16 2 +91 25 11 84 4 +52 31 70 71 14 + +92 1 49 65 77 +85 8 27 87 84 +41 73 81 15 58 +14 93 33 17 52 +35 90 37 38 0 + +11 46 2 20 31 +97 50 12 79 96 +89 77 57 61 40 +65 75 4 33 17 +66 81 47 83 98 + +34 57 44 0 99 +32 25 17 48 90 +27 73 63 61 81 +50 22 4 28 41 + 6 24 70 13 45 + +96 18 36 16 10 +37 11 50 56 88 +80 40 75 90 12 +19 43 33 61 58 +30 59 99 69 98 + +31 77 98 90 51 +34 10 80 73 97 + 2 37 33 17 0 +59 78 91 87 45 +86 7 44 64 1 + +26 49 66 13 16 +95 89 52 88 55 +77 60 3 93 73 +64 45 98 38 42 +34 86 1 71 68 + +59 71 24 18 99 +23 28 88 54 26 +90 37 6 76 4 +41 64 27 89 67 +29 95 82 83 60 + + 8 0 90 41 61 +29 66 2 35 13 +12 9 5 36 93 +67 94 82 77 37 +30 42 32 80 78 + +53 6 23 57 38 + 8 25 76 18 15 +19 17 20 48 72 +26 54 64 7 40 +50 94 82 67 99 + +93 5 67 10 4 +77 80 97 14 2 +34 9 61 24 21 +63 89 28 76 62 +54 29 38 68 69 + +72 48 66 89 22 +63 39 71 59 68 + 2 95 94 21 92 + 6 28 44 62 15 +35 78 80 11 91 + +82 8 59 66 25 +84 87 95 60 12 + 9 52 83 28 49 +23 34 85 94 96 +43 41 39 2 73 + +81 56 55 29 70 +94 96 7 90 2 +95 45 28 75 12 +48 83 65 22 91 +68 98 5 41 73 + +36 22 45 14 74 +35 60 54 15 30 +86 49 27 82 4 +87 2 52 50 21 +39 62 40 1 19 + +99 7 85 24 65 +26 17 36 35 1 + 2 62 38 45 48 +72 68 32 59 11 +28 53 64 21 76 + +61 63 94 50 55 +34 42 39 66 37 +22 72 18 89 12 +16 23 4 0 41 +75 64 3 44 5 + +87 82 53 5 19 +26 54 36 1 38 +28 30 48 97 95 +34 91 99 23 8 +46 35 33 29 66 + +76 89 94 77 58 +24 31 1 40 25 +44 71 42 61 8 +16 41 28 33 50 + 6 85 66 43 51 + +91 28 70 89 43 + 1 76 26 90 45 +24 2 6 82 23 +77 68 16 51 81 +58 86 52 29 18 + +95 0 25 19 91 +10 65 30 72 42 +41 8 77 58 23 +94 60 34 11 67 +24 1 64 78 44 + +40 76 21 37 15 +44 26 80 77 88 +25 72 38 34 9 +75 81 43 86 68 +59 30 87 61 73 + + 0 63 62 82 93 +70 61 14 56 3 +54 43 92 78 27 +26 7 99 77 73 +21 30 44 50 40 + + 2 60 45 17 73 +75 67 68 20 18 +16 30 24 37 12 +79 50 8 65 19 +85 95 54 90 47 + +69 68 54 66 17 +39 19 20 33 44 +12 27 50 60 36 +53 81 8 7 87 +82 97 18 4 74 + +58 63 8 42 28 +70 95 39 54 61 +30 56 79 37 82 +15 32 83 27 45 +52 13 90 97 62 + +11 50 56 66 84 +96 94 57 17 49 +68 58 90 34 59 +81 36 91 8 45 +62 35 6 93 48 + +82 89 54 87 80 +94 6 45 53 62 +31 34 58 85 77 +24 25 91 99 26 +41 0 59 37 23 + +93 41 53 31 87 + 7 22 39 86 73 +71 34 60 57 6 +52 64 48 99 90 +66 76 62 45 40 + + 5 84 85 67 26 +11 1 0 95 21 +48 59 43 94 62 +22 74 40 49 89 +51 20 90 78 96 + + 0 45 43 79 25 +41 10 95 86 80 + 4 60 82 33 75 +44 46 38 17 76 +22 58 27 73 66 + +54 50 7 92 79 +11 43 38 94 5 +63 80 33 58 4 +12 91 28 70 97 +26 99 41 52 90 + +23 26 95 8 17 +73 77 61 89 82 +78 80 64 19 96 +81 92 47 44 59 +54 24 63 74 32 + +86 85 37 80 45 +47 44 92 29 49 +67 48 95 51 88 +36 8 56 16 30 + 0 97 84 24 13 + +81 61 42 87 92 +30 75 17 67 2 +83 44 96 52 1 +37 78 31 15 19 +40 9 72 7 28 + +10 85 17 38 22 +46 35 90 12 27 +76 42 7 2 30 +55 57 60 9 49 +79 73 97 1 21 + +52 36 11 82 91 +22 7 46 21 12 +62 42 66 68 10 +31 18 76 20 84 +28 79 61 39 86 + +73 99 34 54 45 +43 28 18 76 40 +57 58 63 9 11 +89 65 2 12 90 +38 97 49 15 27 + +28 84 24 17 49 +33 69 75 53 92 +81 48 89 19 34 +59 1 18 72 79 + 6 22 2 86 85 + +72 78 30 40 19 +54 16 25 81 28 +41 99 7 79 14 +83 76 29 8 91 + 5 60 11 51 37 + +77 78 34 59 29 +62 69 54 8 97 +80 53 25 66 85 +81 90 31 51 52 +63 41 57 68 18 + +43 62 11 41 7 +37 44 34 10 51 +67 36 61 77 70 +59 1 25 42 88 +29 71 60 15 24 + +30 65 57 35 84 +34 33 72 73 28 +38 51 4 52 14 +58 59 85 87 39 +88 81 11 93 71 + +19 5 23 71 75 +70 9 57 69 14 +49 29 22 28 10 +42 48 63 73 6 +79 18 4 39 88 + +16 27 31 88 86 +29 40 65 68 39 +15 95 93 69 22 +66 48 18 84 11 + 7 51 92 96 99 + + 0 69 51 12 82 + 4 81 62 2 49 +27 66 95 83 70 +94 97 99 63 19 +87 75 77 73 44 + +82 83 75 95 53 +46 47 31 14 64 +71 70 11 51 87 + 7 16 63 38 29 +89 13 33 41 0 \ No newline at end of file diff --git a/adventOfCode/2021/5.go b/adventOfCode/2021/5.go new file mode 100644 index 0000000..fc48445 --- /dev/null +++ b/adventOfCode/2021/5.go @@ -0,0 +1,283 @@ +// Day 5 +package main + +import ( + "fmt" + "strings" + "strconv" + mapset "github.com/deckarep/golang-set" +) + +func strToInt(num string) int { + n, err := strconv.Atoi(num) + if err != nil { + panic(err) + } + return n +} + +func solve5(input []interface{}) (int, int) { + + var day5Inputs [][][]string + + // Customize input + for _, val := range input { + ranges := strings.Split(val.(string), "->") + lower := strings.Split(strings.TrimSpace(ranges[0]), ",") + upper := strings.Split(strings.TrimSpace(ranges[1]),",") + curr_range := [][]string{lower, upper} + day5Inputs = append(day5Inputs, curr_range) + } + + // Solution 1 + sol1 := 0 + + allPoints := make(map[string]int) + overLappedPoints := mapset.NewSet() + + for _, r := range day5Inputs { + l_x := strToInt(r[0][0]) + l_y := strToInt(r[0][1]) + u_x := strToInt(r[1][0]) + u_y := strToInt(r[1][1]) + + var ll, uu int + if l_x == u_x { + if l_y > u_y { + ll = u_y + uu = l_y + } else { + ll = l_y + uu = u_y + } + for i:=ll;i 1 { + overLappedPoints.Add(curr_point) + } + } + } else if l_y == u_y { + if l_x > u_x { + ll = u_x + uu = l_x + } else { + ll = l_x + uu = u_x + } + for i:=ll;i 1 { + overLappedPoints.Add(curr_point) + } + } + } else { + //fmt.Println("unhandled situation") + continue + } + } + + //fmt.Println(allPoints, overLappedPoints, overLappedPoints.Cardinality()) + sol1 = overLappedPoints.Cardinality() + + // Solution 2 + sol2 := 0 + allPoints2 := make(map[string]int) + overLappedPoints2 := mapset.NewSet() + + for _, r := range day5Inputs { + l_x := strToInt(r[0][0]) + l_y := strToInt(r[0][1]) + u_x := strToInt(r[1][0]) + u_y := strToInt(r[1][1]) + + var ll, uu, lly, uuy int + if l_x == u_x { + if l_y > u_y { + ll = u_y + uu = l_y + } else { + ll = l_y + uu = u_y + } + for i:=ll;i 1 { + overLappedPoints2.Add(curr_point) + } + } + } else if l_y == u_y { + if l_x > u_x { + ll = u_x + uu = l_x + } else { + ll = l_x + uu = u_x + } + for i:=ll;i 1 { + overLappedPoints2.Add(curr_point) + } + } + } else { + if l_x > u_x { + ll = u_x + uu = l_x + lly = u_y + uuy = l_y + } else { + ll = l_x + uu = u_x + lly = l_y + uuy = u_y + } + target := strconv.Itoa(uu) + "," + strconv.Itoa(uuy) + diff := 0 + curr_points := mapset.NewSet() + if ll <= uu && lly <= uuy { + for ll+diff <= uu && lly+diff <= uuy { + curr_point := strconv.Itoa(ll+diff) + "," + strconv.Itoa(lly+diff) + curr_points.Add(curr_point) + diff += 1 + } + } + if !curr_points.Contains(target) { + curr_points = mapset.NewSet() + } + + diff = 0 + if ll < uu && lly > uuy { + for ll+diff <= uu && lly-diff >= uuy { + curr_point := strconv.Itoa(ll+diff) + "," + strconv.Itoa(lly-diff) + curr_points.Add(curr_point) + diff += 1 + } + } + if !curr_points.Contains(target) { + curr_points = mapset.NewSet() + } + + + diff = 0 + if ll > uu && lly < uuy { + for ll-diff >= uu && lly+diff <= uuy { + curr_point := strconv.Itoa(ll-diff) + "," + strconv.Itoa(lly+diff) + curr_points.Add(curr_point) + diff += 1 + } + } + if !curr_points.Contains(target) { + curr_points = mapset.NewSet() + } + + diff = 0 + if ll > uu && lly > uuy { + for ll-diff >= uu && lly-diff >= uuy { + curr_point := strconv.Itoa(ll-diff) + "," + strconv.Itoa(lly-diff) + curr_points.Add(curr_point) + diff += 1 + } + } + if !curr_points.Contains(target) { + curr_points = mapset.NewSet() + } + + //fmt.Println(l_x, l_y, u_x, u_y, " :====> ", curr_points) + if curr_points.Cardinality() == 0 { + fmt.Println(target, "=>", curr_points) + continue + } + itr := curr_points.Iterator() + for elem := range itr.C { + val := elem.(string) + if _, ok := allPoints2[val]; !ok { + allPoints2[val] = 0 + } + allPoints2[val] += 1 + if allPoints2[val] > 1 { + overLappedPoints2.Add(val) + } + //fmt.Println(val) + } + } + /* + if l_x > u_x { + ll = u_x + uu = l_x + lly = u_y + uuy = l_y + } else { + ll = l_x + uu = u_x + lly = l_y + uuy = u_y + } + diff := 0 + var curr_points []string + for i:=ll;i uuy { + diff = -(i-ll) + } else { + diff = i-ll + } + fmt.Println(ll, ll+i, uu, " ++ ", lly, lly+diff, uuy) + if ll+i > uu || (lly+diff > uuy && lly < uuy) || (lly+diff < uuy && lly > uuy) { + continue + } + curr_point := strconv.Itoa(i) + "," + strconv.Itoa(lly+diff) + curr_points = append(curr_points, curr_point) + } + target := strconv.Itoa(uu) + "," + strconv.Itoa(uuy) + if len(curr_points) == 0 { + fmt.Println(target, "=>", curr_points) + continue + } + if curr_points[len(curr_points)-1] == target { + for _, val := range curr_points { + if _, ok := allPoints2[val]; !ok { + allPoints2[val] = 0 + } + allPoints2[val] += 1 + if allPoints2[val] > 1 { + overLappedPoints2.Add(val) + } + fmt.Println(val) + } + } else { + // corner case --> just add the points until target (diagnal) + for _, val := range curr_points { + if _, ok := allPoints2[val]; !ok { + allPoints2[val] = 0 + } + allPoints2[val] += 1 + if allPoints2[val] > 1 { + overLappedPoints2.Add(val) + } + fmt.Println(val) + } + } + } + fmt.Println(l_x, l_y, u_x, u_y,ll, uu, "--->",allPoints2) + */ + } + //fmt.Println(allPoints2, overLappedPoints2) + sol2 = overLappedPoints2.Cardinality() + + return sol1, sol2 +} \ No newline at end of file diff --git a/adventOfCode/2021/5/5-sample.input b/adventOfCode/2021/5/5-sample.input new file mode 100644 index 0000000..1d4e36d --- /dev/null +++ b/adventOfCode/2021/5/5-sample.input @@ -0,0 +1,10 @@ +0,9 -> 5,9 +8,0 -> 0,8 +9,4 -> 3,4 +2,2 -> 2,1 +7,0 -> 7,4 +6,4 -> 2,0 +0,9 -> 2,9 +3,4 -> 1,4 +0,0 -> 8,8 +5,5 -> 8,2 \ No newline at end of file diff --git a/adventOfCode/2021/5/5.input b/adventOfCode/2021/5/5.input new file mode 100644 index 0000000..b818958 --- /dev/null +++ b/adventOfCode/2021/5/5.input @@ -0,0 +1,500 @@ +503,977 -> 843,637 +437,518 -> 437,225 +269,250 -> 625,250 +846,751 -> 646,751 +18,731 -> 402,731 +749,923 -> 749,986 +557,758 -> 557,797 +589,54 -> 589,616 +20,136 -> 819,935 +123,983 -> 12,983 +802,624 -> 709,624 +600,458 -> 128,458 +209,703 -> 459,703 +944,415 -> 742,415 +270,718 -> 656,332 +168,339 -> 283,339 +558,172 -> 695,309 +519,524 -> 480,524 +456,400 -> 134,722 +355,961 -> 352,961 +757,158 -> 49,866 +300,254 -> 618,254 +554,275 -> 859,275 +47,612 -> 622,37 +696,885 -> 696,856 +342,803 -> 342,429 +830,649 -> 254,73 +54,921 -> 958,17 +72,691 -> 818,691 +80,72 -> 80,546 +762,649 -> 762,371 +117,39 -> 605,39 +778,605 -> 610,773 +159,25 -> 67,25 +462,825 -> 766,825 +295,167 -> 357,167 +741,379 -> 11,379 +942,230 -> 942,26 +802,672 -> 802,311 +672,759 -> 330,759 +419,97 -> 848,526 +244,262 -> 938,956 +281,988 -> 281,879 +471,451 -> 471,907 +238,387 -> 238,665 +907,129 -> 907,368 +119,734 -> 155,770 +306,119 -> 306,568 +166,175 -> 166,277 +591,32 -> 591,855 +779,324 -> 916,324 +785,245 -> 884,245 +504,884 -> 781,884 +405,967 -> 664,967 +17,16 -> 989,988 +429,944 -> 729,944 +15,31 -> 918,934 +22,963 -> 971,14 +199,280 -> 481,562 +792,550 -> 792,485 +215,141 -> 215,58 +511,560 -> 511,224 +940,134 -> 166,908 +666,212 -> 666,193 +881,514 -> 117,514 +271,416 -> 614,73 +354,784 -> 354,41 +866,152 -> 866,969 +75,924 -> 868,131 +944,507 -> 944,556 +726,315 -> 624,315 +195,122 -> 593,520 +463,311 -> 946,794 +734,698 -> 734,953 +520,98 -> 915,98 +125,139 -> 616,139 +570,841 -> 206,477 +430,442 -> 430,893 +653,59 -> 653,155 +906,883 -> 314,291 +932,157 -> 100,989 +526,244 -> 362,244 +28,837 -> 792,73 +386,426 -> 386,673 +121,66 -> 203,66 +747,121 -> 392,476 +590,989 -> 230,989 +795,83 -> 795,398 +741,522 -> 741,677 +142,166 -> 470,166 +13,645 -> 493,165 +418,567 -> 418,970 +94,877 -> 782,189 +603,426 -> 603,916 +364,304 -> 191,304 +754,146 -> 754,507 +294,678 -> 438,678 +641,633 -> 217,633 +31,133 -> 831,933 +250,976 -> 250,355 +274,558 -> 899,558 +818,507 -> 693,507 +414,465 -> 924,975 +116,729 -> 116,951 +960,843 -> 149,32 +724,127 -> 498,353 +552,43 -> 964,43 +224,853 -> 224,363 +768,214 -> 768,88 +518,414 -> 518,119 +917,824 -> 948,824 +37,81 -> 882,926 +333,390 -> 967,390 +175,453 -> 388,240 +960,395 -> 960,697 +468,37 -> 468,275 +745,318 -> 425,318 +676,425 -> 903,198 +531,663 -> 86,663 +557,834 -> 557,967 +650,931 -> 383,664 +906,197 -> 906,567 +675,637 -> 326,288 +227,977 -> 51,977 +347,524 -> 793,970 +778,850 -> 778,342 +343,155 -> 343,739 +970,167 -> 161,976 +800,127 -> 800,667 +531,533 -> 193,533 +222,776 -> 222,873 +922,29 -> 13,938 +452,808 -> 452,793 +926,142 -> 926,198 +940,93 -> 55,978 +335,51 -> 938,654 +789,352 -> 307,352 +457,419 -> 469,419 +463,12 -> 463,132 +881,95 -> 431,95 +531,57 -> 531,40 +179,308 -> 516,308 +767,907 -> 629,907 +362,457 -> 362,262 +774,896 -> 154,276 +549,243 -> 247,243 +130,933 -> 202,933 +266,639 -> 189,716 +209,717 -> 209,844 +625,296 -> 625,575 +739,785 -> 873,785 +713,857 -> 94,238 +97,28 -> 937,868 +876,734 -> 344,202 +180,608 -> 557,608 +669,566 -> 669,389 +112,779 -> 267,624 +325,669 -> 449,669 +102,915 -> 357,915 +882,839 -> 882,512 +330,699 -> 330,858 +773,851 -> 773,429 +171,187 -> 450,187 +166,726 -> 166,74 +15,134 -> 750,869 +245,126 -> 245,518 +919,484 -> 919,602 +918,900 -> 918,372 +736,515 -> 708,487 +790,777 -> 790,303 +479,541 -> 381,541 +85,243 -> 317,475 +619,441 -> 619,823 +688,658 -> 688,404 +381,475 -> 891,985 +461,529 -> 145,213 +833,885 -> 404,885 +315,502 -> 315,770 +450,934 -> 740,934 +634,334 -> 634,202 +785,866 -> 785,913 +976,627 -> 976,102 +65,491 -> 570,491 +974,257 -> 503,728 +662,938 -> 720,938 +232,472 -> 215,472 +805,504 -> 805,476 +99,909 -> 99,399 +64,947 -> 926,85 +123,645 -> 153,615 +908,10 -> 92,826 +49,174 -> 819,944 +115,136 -> 863,884 +695,91 -> 695,612 +715,527 -> 550,362 +914,125 -> 914,86 +14,980 -> 981,13 +14,308 -> 14,355 +356,895 -> 766,485 +989,10 -> 10,989 +833,292 -> 833,184 +786,785 -> 733,785 +824,53 -> 116,53 +349,547 -> 349,66 +594,189 -> 636,189 +359,399 -> 769,809 +600,751 -> 600,46 +520,236 -> 228,528 +978,610 -> 978,832 +689,575 -> 258,575 +664,734 -> 850,920 +245,672 -> 245,878 +337,509 -> 578,509 +893,613 -> 380,613 +875,608 -> 875,444 +264,701 -> 946,19 +358,267 -> 358,648 +926,61 -> 926,378 +46,885 -> 190,885 +662,131 -> 82,131 +301,53 -> 301,533 +21,839 -> 915,839 +92,174 -> 113,174 +145,680 -> 294,680 +268,773 -> 268,193 +698,893 -> 809,893 +300,512 -> 807,512 +749,408 -> 279,408 +439,214 -> 439,172 +622,740 -> 339,740 +400,253 -> 400,486 +859,686 -> 387,214 +974,485 -> 974,486 +70,987 -> 951,106 +630,449 -> 630,544 +796,212 -> 608,24 +835,959 -> 835,725 +779,755 -> 96,72 +582,778 -> 440,636 +350,479 -> 827,479 +924,40 -> 605,40 +918,832 -> 918,617 +669,590 -> 191,112 +748,214 -> 748,462 +350,703 -> 163,703 +393,791 -> 393,240 +569,857 -> 569,939 +412,375 -> 412,603 +488,975 -> 22,509 +100,372 -> 100,685 +170,669 -> 212,669 +546,734 -> 546,274 +492,172 -> 492,354 +36,134 -> 801,899 +501,773 -> 582,773 +287,694 -> 287,939 +381,988 -> 367,988 +609,360 -> 609,478 +310,158 -> 25,443 +409,716 -> 409,27 +655,959 -> 383,687 +16,697 -> 611,102 +184,290 -> 930,290 +580,79 -> 598,97 +950,65 -> 777,65 +144,288 -> 821,965 +986,685 -> 986,412 +549,702 -> 549,369 +841,148 -> 259,730 +958,31 -> 958,810 +12,908 -> 856,64 +264,793 -> 264,960 +249,115 -> 249,935 +707,714 -> 108,714 +527,192 -> 982,647 +703,883 -> 703,580 +535,346 -> 543,346 +851,185 -> 83,953 +984,586 -> 984,681 +913,574 -> 350,11 +317,221 -> 405,221 +398,673 -> 160,435 +953,264 -> 547,670 +790,115 -> 538,367 +943,236 -> 295,884 +571,746 -> 571,231 +286,318 -> 131,318 +143,251 -> 436,544 +838,435 -> 793,435 +732,782 -> 732,407 +244,287 -> 244,335 +376,29 -> 75,29 +604,732 -> 738,732 +730,30 -> 533,30 +891,474 -> 891,25 +786,140 -> 368,140 +951,583 -> 828,460 +665,897 -> 44,276 +217,905 -> 742,905 +745,583 -> 256,583 +923,22 -> 23,922 +763,336 -> 943,516 +755,678 -> 755,101 +35,790 -> 706,119 +841,658 -> 841,634 +986,66 -> 986,412 +740,69 -> 740,878 +852,733 -> 453,733 +657,273 -> 215,715 +239,824 -> 239,79 +340,482 -> 340,238 +969,834 -> 303,168 +238,718 -> 931,718 +603,63 -> 603,363 +596,135 -> 367,135 +184,474 -> 184,612 +39,60 -> 920,941 +456,103 -> 894,541 +929,35 -> 738,35 +199,528 -> 707,528 +649,251 -> 134,766 +969,209 -> 719,459 +568,45 -> 306,307 +259,703 -> 426,536 +964,737 -> 342,115 +101,890 -> 604,890 +57,223 -> 812,978 +939,99 -> 167,871 +920,438 -> 920,247 +185,384 -> 643,384 +489,783 -> 121,415 +837,938 -> 250,351 +63,920 -> 945,38 +475,45 -> 510,10 +881,872 -> 141,132 +24,238 -> 24,468 +409,523 -> 409,706 +200,309 -> 631,740 +586,385 -> 900,385 +219,250 -> 219,327 +854,526 -> 854,725 +946,343 -> 946,267 +847,746 -> 717,616 +172,203 -> 346,29 +693,652 -> 545,652 +824,115 -> 192,115 +843,908 -> 333,908 +769,784 -> 662,784 +490,535 -> 490,524 +545,699 -> 11,699 +792,544 -> 287,39 +895,712 -> 895,41 +887,350 -> 624,350 +614,475 -> 924,165 +93,961 -> 265,789 +57,71 -> 852,866 +282,738 -> 844,176 +898,251 -> 898,669 +949,872 -> 866,872 +765,408 -> 545,408 +691,503 -> 235,959 +198,491 -> 227,462 +973,40 -> 56,957 +802,402 -> 752,402 +911,60 -> 911,932 +545,244 -> 110,244 +461,26 -> 461,18 +916,308 -> 161,308 +368,476 -> 515,476 +656,916 -> 409,669 +118,950 -> 118,135 +963,294 -> 365,294 +855,713 -> 323,713 +849,930 -> 48,129 +36,337 -> 588,889 +941,394 -> 941,697 +685,170 -> 323,170 +423,683 -> 423,152 +81,522 -> 121,522 +357,598 -> 159,796 +211,192 -> 211,50 +615,607 -> 270,952 +687,384 -> 687,128 +81,896 -> 925,52 +591,988 -> 20,988 +950,740 -> 605,740 +818,772 -> 623,772 +790,405 -> 790,775 +483,34 -> 718,34 +309,190 -> 309,894 +391,83 -> 483,83 +721,201 -> 721,843 +990,464 -> 990,171 +479,707 -> 688,707 +23,775 -> 510,775 +783,863 -> 867,779 +594,151 -> 208,151 +416,936 -> 416,720 +981,972 -> 120,111 +773,476 -> 138,476 +604,900 -> 604,395 +824,437 -> 531,437 +621,948 -> 32,948 +802,26 -> 887,26 +836,335 -> 836,784 +134,585 -> 634,85 +649,87 -> 649,263 +756,804 -> 638,804 +982,26 -> 21,987 +134,976 -> 914,196 +612,539 -> 612,141 +977,11 -> 22,966 +40,80 -> 40,644 +725,562 -> 604,562 +377,649 -> 352,624 +418,146 -> 130,434 +848,927 -> 848,970 +243,350 -> 342,449 +46,10 -> 46,112 +800,654 -> 272,126 +910,633 -> 910,426 +296,619 -> 882,33 +75,922 -> 497,500 +267,616 -> 864,616 +884,694 -> 624,694 +13,656 -> 831,656 +389,390 -> 389,316 +26,24 -> 987,985 +193,557 -> 589,161 +18,13 -> 978,973 +43,951 -> 614,951 +581,398 -> 885,94 +943,525 -> 279,525 +787,83 -> 137,83 +729,271 -> 729,18 +100,383 -> 100,690 +337,266 -> 102,266 +106,640 -> 298,832 +83,65 -> 543,65 +102,872 -> 663,872 +921,765 -> 921,782 +764,392 -> 471,685 +325,987 -> 802,987 +983,43 -> 983,852 +833,475 -> 416,58 +25,270 -> 686,931 +145,433 -> 151,433 +132,329 -> 973,329 +611,494 -> 98,494 +401,633 -> 866,168 +532,126 -> 532,448 +988,894 -> 361,894 +249,177 -> 249,133 +832,71 -> 832,245 +263,70 -> 263,152 +548,333 -> 548,748 +98,570 -> 438,910 +954,41 -> 41,954 +336,199 -> 336,843 +117,974 -> 845,246 +831,456 -> 890,515 +690,114 -> 804,114 +94,108 -> 94,672 +289,104 -> 107,286 +248,580 -> 229,580 +11,284 -> 885,284 +401,802 -> 186,802 +359,245 -> 558,46 +310,85 -> 310,714 +920,577 -> 979,577 +492,236 -> 276,452 +650,961 -> 49,360 +118,705 -> 118,794 +970,24 -> 80,914 +943,454 -> 943,30 +875,935 -> 716,776 +241,717 -> 392,717 +694,345 -> 620,345 +533,435 -> 467,435 +827,166 -> 374,166 +633,849 -> 884,849 +414,640 -> 875,179 +240,790 -> 709,321 +48,222 -> 104,222 +889,897 -> 44,52 +980,438 -> 455,963 +469,875 -> 469,706 +572,869 -> 250,547 +834,11 -> 834,188 +395,966 -> 395,547 +12,681 -> 567,681 +268,957 -> 947,957 +450,478 -> 893,921 +418,707 -> 602,891 +404,303 -> 218,489 +657,232 -> 657,945 +518,392 -> 518,621 +268,959 -> 896,331 +886,616 -> 841,616 +375,503 -> 375,387 \ No newline at end of file diff --git a/adventOfCode/2021/6.go b/adventOfCode/2021/6.go new file mode 100644 index 0000000..153abf7 --- /dev/null +++ b/adventOfCode/2021/6.go @@ -0,0 +1,150 @@ +// Day 6 +package main + +import ( + //"fmt" + "strconv" + "strings" +) + +func solve6(input []interface{}) (int, int) { + + var laternFishes []int + + // Customize input + for _, val := range input { + group := val.(string) + fishes := strings.Split(group, ",") + for _, f := range fishes { + if f == "" { continue } + fish, err := strconv.Atoi(f) + if err != nil { panic(err) } + laternFishes = append(laternFishes, fish) + } + } + + // Solution 1 + days := 80 + sol1 := 0 + laternFishesSol1 := make([]int, len(laternFishes)) + copy(laternFishesSol1, laternFishes) + + var currentDayFishes []int + for day := 0; day < days; day++ { + currentDayFishes = laternFishesSol1 + for index, fish := range currentDayFishes { + if fish == 0 { + laternFishesSol1[index] = 6 + laternFishesSol1 = append(laternFishesSol1, 8) + } else { + laternFishesSol1[index] = fish-1 + } + } + //fmt.Println(laternFishes) + } + /* + for day < days { + fmt.Println(day) + currentDayFishes = laternFishesSol2 + for index, fish := range currentDayFishes { + if fish-8 <= 0 { + laternFishesSol2[index] = 6-(8-fish) + laternFishesSol2 = append(laternFishesSol2, 8) + } else { + laternFishesSol2[index] = fish-8 + } + } + day += 8 + //fmt.Println(laternFishes) + } + */ + sol1 = len(laternFishesSol1) + + // Solution 2 + days = 256 + sol2 := 0 + + laternFishesSol2 := make([]int, len(laternFishes)) + copy(laternFishesSol2, laternFishes) + + var currentDayFishes2 []int + + totalFishes := 0 + childrenAtLevel := make(map[int]int) + + for day := days; day > 0; day-- { + currentDayFishes2 = laternFishesSol2 + newChildrens := 0 + for index, fish := range currentDayFishes2 { + if fish == 0 { + laternFishesSol2[index] = 6 + if _, ok := childrenAtLevel[index]; ok { + newChildrens += childrenAtLevel[index] + continue + } + newChildrens += 1 + } else { + laternFishesSol2[index] = fish-1 + } + } + //totalFishes += newChildrens*((day-8)/7) + if newChildrens == 0 { + //fmt.Println(laternFishesSol2, days-day) + continue + } + laternFishesSol2 = append(laternFishesSol2, 8) + target := len(laternFishesSol2)-1 + if _, ok := childrenAtLevel[target]; !ok { + childrenAtLevel[target] = 0 + } + childrenAtLevel[target] += newChildrens + //fmt.Println(laternFishesSol2, len(childrenAtLevel), days-day) + } + + for index, _ := range laternFishesSol2 { + if _, ok := childrenAtLevel[index]; ok { + totalFishes += childrenAtLevel[index] + continue + } + totalFishes += 1 + } + //fmt.Println(childrenAtLevel) + + /* + offspringsByDays := make(map[days]int) + offspringsByLevel := [][]int + + index := 0 + for len(laternFishesSol2) > 0 { + currentLevel := laternFishesSol2[0] + nextLevel := []int{} + for _, fish := range currentLevel { + days -= len() + } + offspringsByLevel = append(offspringsByLevel, nextLevel) + laternFishesSol2 = nextLevel + } + + for index < len(laternFishesSol2) { + fish := laternFishesSol2[index] + fmt.Println(index) + if laternFishesSol2[index] != 8 { + laternFishesSol2[index] = days-fish + } else { + laternFishesSol2[index] = days-8 + } + offsprings := 1+laternFishesSol2[index]/7 + laternFishesSol2[index] = 7-laternFishesSol2[index]%7 + fmt.Println(fish, laternFishesSol2[index], offsprings) + for offsprings > 0 { + laternFishesSol2 = append(laternFishesSol2, 8) + offsprings -= 1 + } + //fmt.Println(late + } + */ + + sol2 = totalFishes + + return sol1, sol2 +} \ No newline at end of file diff --git a/adventOfCode/2021/6/6-sample.input b/adventOfCode/2021/6/6-sample.input new file mode 100644 index 0000000..a7af2b1 --- /dev/null +++ b/adventOfCode/2021/6/6-sample.input @@ -0,0 +1 @@ +3,4,3,1,2 \ No newline at end of file diff --git a/adventOfCode/2021/6/6.input b/adventOfCode/2021/6/6.input new file mode 100644 index 0000000..a2ca78e --- /dev/null +++ b/adventOfCode/2021/6/6.input @@ -0,0 +1 @@ +1,1,3,5,3,1,1,4,1,1,5,2,4,3,1,1,3,1,1,5,5,1,3,2,5,4,1,1,5,1,4,2,1,4,2,1,4,4,1,5,1,4,4,1,1,5,1,5,1,5,1,1,1,5,1,2,5,1,1,3,2,2,2,1,4,1,1,2,4,1,3,1,2,1,3,5,2,3,5,1,1,4,3,3,5,1,5,3,1,2,3,4,1,1,5,4,1,3,4,4,1,2,4,4,1,1,3,5,3,1,2,2,5,1,4,1,3,3,3,3,1,1,2,1,5,3,4,5,1,5,2,5,3,2,1,4,2,1,1,1,4,1,2,1,2,2,4,5,5,5,4,1,4,1,4,2,3,2,3,1,1,2,3,1,1,1,5,2,2,5,3,1,4,1,2,1,1,5,3,1,4,5,1,4,2,1,1,5,1,5,4,1,5,5,2,3,1,3,5,1,1,1,1,3,1,1,4,1,5,2,1,1,3,5,1,1,4,2,1,2,5,2,5,1,1,1,2,3,5,5,1,4,3,2,2,3,2,1,1,4,1,3,5,2,3,1,1,5,1,3,5,1,1,5,5,3,1,3,3,1,2,3,1,5,1,3,2,1,3,1,1,2,3,5,3,5,5,4,3,1,5,1,1,2,3,2,2,1,1,2,1,4,1,2,3,3,3,1,3,5 \ No newline at end of file diff --git a/adventOfCode/2021/7.go b/adventOfCode/2021/7.go new file mode 100644 index 0000000..5a07cc3 --- /dev/null +++ b/adventOfCode/2021/7.go @@ -0,0 +1,160 @@ +// Day 7 +package main + +import ( + //"fmt" + "strconv" + "sort" + "strings" + "math" +) + +var ( + visitedTotal = make(map[int]int) +) + +func solve7(input []interface{}) (int, int) { + + var day7Inputs []int + + // Customize input + for _, val := range input { + group := val.(string) + crabs := strings.Split(group, ",") + for _, c := range crabs { + if c == "" { continue } + crab, err := strconv.Atoi(c) + if err != nil { panic(err) } + day7Inputs = append(day7Inputs, crab) + } + } + + // Solution 1 + sol1 := 0 + + visitedOriginFrequency := make(map[int]int) + var sortedFreqs []int + var maxFreq int + var maxPosition int + var farthestCrab int + + for _, position := range day7Inputs { + + if position > farthestCrab { + farthestCrab = position + } + if _, ok := visitedOriginFrequency[position]; !ok { + visitedOriginFrequency[position] = 0 + sortedFreqs = append(sortedFreqs, position) + } + visitedOriginFrequency[position] += 1 + if visitedOriginFrequency[position] > maxFreq { + maxFreq = visitedOriginFrequency[position] + maxPosition = position + } + } + + //fmt.Println(maxFreq, maxPosition) + //for position, freq := range visitedOriginFrequency { + // fmt.Println(position, " ===> ", freq) + //} + + totalCost := 0 + currentCost := 0 + + // (Greedy) Start with highest frequency if there exists one else take midpoint + if maxFreq > 1 { + for position, freq := range visitedOriginFrequency { + currentCost = maxPosition - position + if currentCost < 0 { + currentCost *= -1 + } + totalCost += currentCost * freq + } + } + + // (Greedy Bypass) No maxfrequency meaning we use midpoint + if totalCost == 0 && maxFreq == 1 { + sort.Ints(sortedFreqs) + mid := len(sortedFreqs)/2 + midPosition := int(sortedFreqs[mid]) + //fmt.Print(midPosition) + for position, freq := range visitedOriginFrequency { + currentCost = midPosition - position + if currentCost < 0 { + currentCost *= -1 + } + totalCost += currentCost * freq + } + } + + // (Not doing dynamic) as subproblems dont seem to be related + + // Brute force to ensure all costs + currCost := 0 + for target, _ := range visitedOriginFrequency { + currCost = 0 + for position, freq := range visitedOriginFrequency { + if position == target { continue } + currentCost = target - position + if currentCost < 0 { + currentCost *= -1 + } + currCost += currentCost * freq + if currCost > totalCost { // exit for increasing cost + break + } + } + if currCost < totalCost { + totalCost = currCost + } + //fmt.Println(target, "-->", currCost) + } + + sol1 = totalCost + + // Solution 2 + sol2 := 0 + totalCost = math.MaxInt + + currCost = 0 + for target:=1;target totalCost { // exit for increasing cost + break + } + } + if currCost < totalCost { + totalCost = currCost + } + //fmt.Println(target, currCost, totalCost) + //fmt.Println(target, "-->", currCost) + } + + //fmt.Println(visitedTotal) + + sol2 = totalCost + //fmt.Println(visitedTotal) + + return sol1, sol2 +} + +func calculateCost(diff int) int { + if diff == 0 { + return 0 + } + if _, ok := visitedTotal[diff]; ok { + return visitedTotal[diff] + } + total := diff + calculateCost(diff-1) + visitedTotal[diff] = total + return total +} \ No newline at end of file diff --git a/adventOfCode/2021/7/7-sample.input b/adventOfCode/2021/7/7-sample.input new file mode 100644 index 0000000..2bdd92f --- /dev/null +++ b/adventOfCode/2021/7/7-sample.input @@ -0,0 +1 @@ +16,1,2,0,4,2,7,1,2,14 \ No newline at end of file diff --git a/adventOfCode/2021/7/7.input b/adventOfCode/2021/7/7.input new file mode 100644 index 0000000..599b1e2 --- /dev/null +++ b/adventOfCode/2021/7/7.input @@ -0,0 +1 @@ +1101,1,29,67,1102,0,1,65,1008,65,35,66,1005,66,28,1,67,65,20,4,0,1001,65,1,65,1106,0,8,99,35,67,101,99,105,32,110,39,101,115,116,32,112,97,115,32,117,110,101,32,105,110,116,99,111,100,101,32,112,114,111,103,114,97,109,10,231,350,1278,139,664,182,40,377,157,886,184,138,727,661,904,24,77,349,608,1346,963,12,759,112,129,818,1046,600,43,523,709,1002,2,202,212,11,264,0,505,956,163,560,128,299,0,229,4,33,1402,268,418,1435,151,786,727,100,248,57,763,311,206,67,997,379,378,332,0,23,143,93,389,815,11,66,873,1414,7,7,681,140,288,390,434,314,215,360,3,317,463,294,0,33,801,1417,54,782,937,94,102,95,15,177,649,45,107,695,100,49,193,636,263,177,932,345,706,99,28,211,449,442,117,7,467,101,732,947,818,346,87,78,285,236,707,912,1652,294,333,706,758,1621,782,246,546,663,699,177,94,221,746,66,170,514,364,751,1486,157,54,38,1469,0,79,83,1060,422,252,27,1332,386,523,41,934,988,278,409,438,61,1047,260,300,240,0,496,1392,181,268,413,544,1169,662,566,4,988,267,1259,250,346,319,235,172,728,1621,505,1490,17,104,711,714,1139,497,603,759,393,1184,60,369,1326,333,45,51,118,1171,29,1560,252,139,481,1160,177,555,150,115,129,237,1672,613,1311,999,217,20,936,323,116,60,198,644,718,69,594,1142,607,854,878,926,515,29,2,740,1281,74,1406,47,88,249,1416,1263,943,1477,39,123,1919,37,167,227,478,405,421,316,335,1375,359,498,173,507,456,40,226,160,927,229,848,6,1174,1107,710,13,480,1249,817,85,80,128,12,48,243,576,199,208,338,1521,1167,282,690,16,362,791,25,435,495,1217,1215,387,36,1620,166,1586,345,698,541,590,277,328,85,862,751,1273,950,817,77,749,198,156,212,404,6,197,425,582,453,59,45,1059,1058,389,178,547,847,670,559,81,1180,220,1338,216,1528,629,601,802,903,207,352,228,29,761,477,161,268,228,647,80,110,402,470,714,439,511,13,70,277,746,492,657,1215,146,201,63,84,1158,1615,513,1182,83,73,60,22,221,888,344,27,205,1344,325,1362,102,1396,1117,426,80,497,458,11,218,165,221,649,524,264,251,617,825,172,1120,931,520,112,1286,818,1464,11,1,83,184,320,152,730,744,409,604,73,1205,411,732,1078,775,334,130,202,716,368,734,794,723,1140,367,222,435,596,566,719,1046,1428,797,470,124,380,1833,180,62,714,1112,772,26,89,445,9,147,76,764,267,1400,6,275,69,292,143,522,376,797,73,136,688,30,417,1835,47,54,19,32,565,85,320,426,771,66,1656,740,75,10,284,23,14,65,719,1719,874,426,599,314,445,796,994,467,49,0,1141,248,957,50,1024,427,696,533,1284,811,89,17,597,463,1501,13,199,701,53,318,7,628,608,147,291,22,518,191,1243,333,88,12,138,363,262,753,467,456,74,1047,15,339,234,612,452,424,340,481,13,4,303,30,908,1069,1018,1584,426,192,304,337,326,1087,406,132,449,1142,279,307,315,1445,113,49,705,120,187,4,798,960,431,214,1051,848,54,845,64,83,1059,813,1390,1008,237,469,156,61,635,1074,1621,523,24,140,141,715,1124,402,400,204,18,452,1107,453,377,467,241,340,35,320,799,680,5,123,43,1614,1774,549,651,163,700,776,65,336,145,426,150,1049,113,1346,434,45,521,729,55,1448,85,1133,1421,375,1398,319,206,606,68,1597,716,1507,963,141,95,72,33,1242,251,448,1337,1132,83,1779,284,58,625,253,1247,344,47,1194,1047,190,538,103,322,652,44,422,53,31,345,1346,27,768,1006,179,447,1318,199,92,364,141,121,276,284,847,462,700,780,360,843,1430,185,69,635,292,413,43,71,240,15,787,379,1353,173,305,227,118,844,632,471,523,1139,8,811,355,811,223,37,267,438,1011,58,39,64,422,167,844,165,80,618,1115,194,547,47,99,639,171,43,246,104,1429,510,127,125,1035,290,839,1060,26,160,31,570,623,80,1246,645,1396,99,543,159,525,211,446,209,885,512,1483,479,716,417,268,583,1467,573,553,95,729,1589,207,67,224,243,426,283,398,612,596,248,282,180,94,405,148,429,37,116,582,32,253,282,832,94,154,338,75,404,651,365,1436,60,266,1163,982,69,958,751,1693,850,1257,1294,429,120,133,741,564,328,315,1268,98,20,14,114,478,20,344,631,1296,24,1611,487,659,355,1336,20,1197,515,13,1165,1007,1403,1473,126,461,431,15,136,730,449,1109,1146,1210,944,158,742,1586,380,1051,41,1250,915,1417,681,642,70,1789,54,161,1568,676,113,287,338,127,1168,615,421,215 \ No newline at end of file diff --git a/adventOfCode/2021/8.go b/adventOfCode/2021/8.go new file mode 100644 index 0000000..460aba4 --- /dev/null +++ b/adventOfCode/2021/8.go @@ -0,0 +1,120 @@ +// Day 8 +package main + +import ( + //"fmt" + "strconv" + "strings" + mapset "github.com/deckarep/golang-set" +) + +func solve8(input []interface{}) (int, int) { + + var day8PrefixDisplay []string + var day8SuffixDisplay []string + var day8SuffixDisplayByLine [][]string + + // Customize input + for _, val := range input { + outputs := []string{} + line := strings.Split(val.(string), "|") + pre := strings.Split(strings.TrimSpace(line[0]), " ") + for _, p := range pre { + day8PrefixDisplay = append(day8PrefixDisplay, p) + } + suf := strings.Split(strings.TrimSpace(line[1]), " ") + for _, s := range suf { + day8SuffixDisplay = append(day8SuffixDisplay, s) + outputs = append(outputs, s) + } + day8SuffixDisplayByLine = append(day8SuffixDisplayByLine, outputs) + } + + // Solution 1 + sol1 := 0 + + // segment displays + uniqSegmentCombinations := map[int]mapset.Set{ + 1: mapset.NewSetFromSlice([]interface{}{"c", "f"}), + 4: mapset.NewSetFromSlice([]interface{}{"b", "c", "d", "f"}), + 7: mapset.NewSetFromSlice([]interface{}{"a", "c", "f"}), + 8: mapset.NewSetFromSlice([]interface{}{"a", "b", "c", "d", "e", "f", "g"}), + } + uniqLengths := mapset.NewSetFromSlice([]interface{}{2, 3, 4, 7}) + + for _, val := range day8SuffixDisplay { + for _, uniq := range uniqSegmentCombinations { + temp := val + if !uniqLengths.Contains(len(temp)) { + //fmt.Println(temp) + continue + } + for len(temp) > 0 && uniq.Contains(string(temp[0])) { + temp = temp[1:] + } + if len(temp) == 0 { + sol1 += 1 + break + } + } + } + + // Solution 2 + sol2 := 0 + + // segment displays + newUniqSegmentCombinations := map[string]mapset.Set{ + "8": mapset.NewSetFromSlice([]interface{}{"a", "c", "e", "d", "g", "f", "b"}), + "5": mapset.NewSetFromSlice([]interface{}{"c", "d", "f", "b", "e"}), + "2": mapset.NewSetFromSlice([]interface{}{"g", "c", "d", "f", "a"}), + "3": mapset.NewSetFromSlice([]interface{}{"f", "b", "c", "d", "a"}), + "7": mapset.NewSetFromSlice([]interface{}{"d", "b", "a"}), + "9": mapset.NewSetFromSlice([]interface{}{"c", "e", "f", "d", "a", "b"}), + "6": mapset.NewSetFromSlice([]interface{}{"c", "e", "f", "d", "g", "b"}), + "4": mapset.NewSetFromSlice([]interface{}{"a", "e", "f", "b"}), + "0": mapset.NewSetFromSlice([]interface{}{"c", "a", "g", "e", "d", "b"}), + "1": mapset.NewSetFromSlice([]interface{}{"a", "b"}), + } + + /* + 9, 6 --> 6 segments + 8 --> 7 segments + 7 --> 3 segments (top, right: always) --> start with this + 2,3,5 --> 5 segments + 4 --> 4 segments + 1 --> 2 segments + + 0. if the line has 7 segments lighted, then its easy --> shld be 8 (use that combo) + 1. if the line has 6 segments lighted, then its also easy to conclude it shld be 9 (use that combo) + 2. if the line has 2,3 segments lghted, then conclude --> abc is 7 (defg is left) ---> [1,7], verify with + */ + + for _, stream := range day8SuffixDisplayByLine { + output := "" + for _, val := range stream { + //fmt.Println(val, output) + for num, uniq := range newUniqSegmentCombinations { + if len(val) != uniq.Cardinality() { + continue + } + temp := val + for len(temp) > 0 && uniq.Contains(string(temp[0])) { + temp = temp[1:] + } + if len(temp) == 0 { + output += num + break + } + } + } + if output == "" { + continue + } + //fmt.Println(output) + n, err := strconv.Atoi(output) + if err != nil { panic(err) } + sol2 += n + } + + return sol1, sol2 +} \ No newline at end of file diff --git a/adventOfCode/2021/8/8-sample.input b/adventOfCode/2021/8/8-sample.input new file mode 100644 index 0000000..8614893 --- /dev/null +++ b/adventOfCode/2021/8/8-sample.input @@ -0,0 +1,10 @@ +be cfbegad cbdgef fgaecd cgeb fdcge agebfd fecdb fabcd edb | fdgacbe cefdb cefbgd gcbe +edbfga begcd cbg gc gcadebf fbgde acbgfd abcde gfcbed gfec | fcgedb cgb dgebacf gc +fgaebd cg bdaec gdafb agbcfd gdcbef bgcad gfac gcb cdgabef | cg cg fdcagb cbg +fbegcd cbd adcefb dageb afcb bc aefdc ecdab fgdeca fcdbega | efabcd cedba gadfec cb +aecbfdg fbg gf bafeg dbefa fcge gcbea fcaegb dgceab fcbdga | gecf egdcabf bgf bfgea +fgeab ca afcebg bdacfeg cfaedg gcfdb baec bfadeg bafgc acf | gebdcfa ecba ca fadegcb +dbcfg fgd bdegcaf fgec aegbdf ecdfab fbedc dacgb gdcebf gf | cefg dcbef fcge gbcadfe +bdfegc cbegaf gecbf dfcage bdacg ed bedf ced adcbefg gebcd | ed bcgafe cdgba cbgef +egadfb cdbfeg cegd fecab cgb gbdefca cg fgcdab egfdb bfceg | gbdfcae bgc cg cgb +gcafb gcf dcaebfg ecagb gf abcdeg gaef cafbge fdbac fegbdc | fgae cfgab fg bagce \ No newline at end of file diff --git a/adventOfCode/2021/8/8.input b/adventOfCode/2021/8/8.input new file mode 100644 index 0000000..bdd3643 --- /dev/null +++ b/adventOfCode/2021/8/8.input @@ -0,0 +1,200 @@ +ecgabfd gfbe dgbeaf aeg gfbda eg bgdcaf efgdca abced eadgb | begf decgfa aeg eg +ebfg bfgdea gaf gf baedgc dafec cfdabg ecfabgd fdgea dbaeg | gaedbc egbf dbgcea dagfebc +cfadeg ca bacg dfabe dgcbf dbegafc dac afbdgc gcbedf bfcda | fbdac adbef bgcdfae dcagfe +eag cdgfae cbdge ae fcgad eabdfg ecaf gefbadc dgafcb degca | dacbefg fcdage agdcf fedagb +dga edac gdfbea bgdfec da cfbga dbgec cadgb bdgace dcbfage | acgfb gaecbfd dag gedfab +cefb fb abcgefd fagbde fcbgae faecg cbadg cbfga bfa agcdef | gbacf agbfc bgcaef baf +ebdacf cbgfae cgdebaf afdcb gabdc df cdf eafd ecabf begdfc | cbdaf gdabc fd cbefda +ge daebc fcagb fdebac gaed ecabg egc gacedb cbdfeg adcfbeg | gec gebdca ebagc adbgcfe +bgfade gcefbd eafgd fcae cadgf gcf dgcba cfdega cagbdfe cf | cdgeaf agfed cf cf +abfge ebac acfegbd bc fcged gbfec cfgbad fecabg agbfde fcb | aefgdb cfb egbfca cbfaedg +dfcbag gda dcafe gcdeb ag ecgdaf edagc bcdaef gcbadfe gaef | gbced dga cbadef fgecda +cagb adgceb cdb cfgeda egfbd abcefd decag bc cgebd bgedfca | cegbd dfegac dbc befdg +cbfe bgefdc ceabdfg cf dbgaef gdfbac edcga gcfed dfc fbedg | fgbaed fcd fcegd becf +degabf bfg bcgaf gdacf dbfc gecfda gcaeb fagedbc adfgbc bf | egbdfa gbf adfbceg dcfb +dbfae dfbc ecadg cb cbdea fcebag fgadbec gadebf bec ceabfd | dbfc bgfcead agbedf fdabe +dafcge ecafbg cegaf egdac abegd cd debfca edc cgfd bfdeagc | dec dc ecd dbgae +fgabce bfa acbfegd fcegda bfgd acgfd bcaed bfcda bf cbagdf | bf bafgcd bfdg dgbacfe +fgea gad fcbgaed gdebc afdeb fagcbd cbfeda ag egfdba degab | dgeab badge eacfbdg fdceba +fabdce cagdb gcb bcefag degba dfagbc dgcf dcfab egfcabd cg | befcda dbagc cbdgfa gcdf +be fgaced fdeag badegf fdbea ebdg bea agfbec ebgadcf bcfad | acdfge agbfce debaf dgafe +cdfbeg bg fegca gdefac cadbf eadbcgf cgb egba gcfbea cagfb | gfaced agfcb cbdfaeg cgfdabe +fadcebg cgda ebfag adebc fcebdg fadbce gd begcda bdg gedba | dcga fbage dcabef fcebadg +bfcga adfbgc fbcdage gfedac ab gcfbe cgafd efabgd gab bdca | gcafd cdba gba dfabgc +bdfae gfa cdgabe egfba fg gfeadc acegb fgcb fbecgad ecafgb | bgeaf agfecbd fga agdceb +dgab ebfad cdefgb gbefd fab cefabg fegcbda aedcf ba ebadgf | defbag afb gbfead dbefag +cfabed ecabf cgafdeb bfc fecbgd dcab cb bfeda eagfc adfgeb | fgcae dfbega ebcdfg fabec +eb cbgaef eagcfbd caebd gaedbc badfc abe degac dgeb cgdeaf | aeb gfaebc bceafg abcged +gdecba ecbdgf def fcbade fd fdcg bgfae gdecb gfbde faegdbc | fbage ecgdbf egdfb dfe +dc dac egcadbf gadbe cgaebd abgcd geadbf agfced edcb gabfc | agcbefd edbc bacfg cd +gaebfc gdc cedbg dbeag cefd cd bcfgde cbgfda bcegf dabgecf | bgdea dbgec fecd cfed +afd dfcbga dcbeagf bfecda egbcdf dagec fa bgfa fdbcg fgadc | egbcdf decga gbfa fa +fg baefc gafeb dgaf cbgdea afegbd fbg cebgfd gaecdfb dbgae | ebfag dgbae gafd abgedfc +cbaed gedac cefgbda feba be cadebf gdcefb fcbad bde cdagbf | bcadef cfgdab fdabc feab +cfbdg fdgce adgcbf fb cbf acfegdb adgebc ebafdc dbacg agbf | fgba fgced ecfdabg bf +fceabd gfb agfdb deabg beacgf cfdgbae fcdg gf abfdc dfbgca | dbaeg bfdga dgeab dfcg +gfde facbde dcgbf fg gbf ecafgb cfgdbe ecdfb adcgb ecafbdg | gcdbf fg cfbdg fdeg +fbgdce bg bacefg decab cbg fecgd egdcfa dbfg egdcb fagdbce | gb dcbea fedbgc fagecb +abgcef fgbaedc dfaebg cgad ad egadcb abd cgbea bfecd cabde | efbcd abdfeg afbegd ad +fagecdb bcafg ecadfb fa bagecf cdgba efbdcg befgc fac agfe | bdfcge ecgbf cfedba edagfcb +dgf fcdbg cegbd fd bfcega daebgf dfca abgcf gafbdc fbeacgd | bcfdg fdg dfg adcf +deb cbdgae edfbac dbcgf fbecga gdfcbea bgdec ed ecabg egad | bgcfd faedcb cageb ed +gecfba dfagc afdbc adbcfg cag cabgdfe fdega cbdg dbacfe cg | afcbdeg dabcf cbafed dcfga +feab ae cbgfe agecf bgecda bgecdf eca gfebca fcdbgea cgfad | bgdfec gcfbed eca cbdgaef +fbaceg edcbaf dba becgd egafb degbfca fbadeg dafg da agebd | fbdega gfebca acebdf gbefa +dbce gfbec defgb ed efdagc def gfbeca abfgd bgfedc fcbgade | fdbgce ebdfcg cgfbdea efcbgd +abcdfg fcaegb egf dgcaf bdecf aged bdeacfg ge dgcafe gfcde | acbgfd gcadf cgbdaf gafecb +fb gbfaed eabgdc abcgef adcbfge dgfac fecb bgf fcbga cageb | acebg cfeabg edgcab adgfbce +fad ceafdg dcfag fbcadge geadbf deac da gcfea gdcfb efcagb | aegdfb cgadf aefbcg bgdcf +dagcbf ef dacfg gfdce egf ebdgc dfcgea fabdeg aefc ebdacfg | gdefc dcfag bgdceaf acef +dbegf eabcgd ebdafg fbdac cbg cefg eagbdfc cdbgf gdfbce cg | eabcdgf gecadbf decgbf gc +degf cbefd bfcdeg bfdaec bcage cfgdba fg fcg fbcge cefgdba | fged cfgedab fdgceb efcbd +cgbdae dbeca bcfdeg fcaged edgca be cbdaf ebd gfbadec egba | cefdgab cdfega bcgeda agcbde +cdfgea gbedacf gacbf cdb decag db edcabf gabedc dgeb bgdca | bcfag bcgad ecdgfab bd +ebcg cfgbae acgdbef eag agdfc ge edgabf cgefa facbe dacebf | cbgefa agcfd fgcad dfgac +beagcf dafcgbe da acd bedcf begacd cdbae cefadg bagd bgcae | da fgbecad bdcef bfdec +dg acgfebd fagecb bgeadf ebfgc gdb cdbgf dbafc gecd debfgc | egcbf cafbd facbd afbegcd +geabd cadefb ec eadgfcb cedag gdbeca dec gfbdae dcfag cbeg | ec bdeafgc cbdafe ebcg +be bfade caefgb eab gdbafe bedg agfdb edacfbg gdcabf daefc | acfegb bae fecadgb bgcfea +be acdfb cgfae cbe agbe fgeacbd adegcf bcfae bgcefa fgbecd | cfabeg ecb efcdbg ageb +afbg cfedb dacfgb fgdcb bgfedac cbdage bg acgdf fadceg dgb | cdbgfa fgeadc bafg dfbce +debfc efb adgbce ef fbadec dfcbg feac dacgebf aebdc eadgfb | fcdgb efca cbdeaf edbca +gcbde dgcbf dfc bfcgda df ceadgbf gcabf dbaf gcefab dfcega | adfb egcdb dgbce bdfa +egbdca bgfed baefd cfdgaeb gdefc gcbfed gcfead bg cfgb egb | dcbage cbdgef dgfbe aedbcg +dceaf fc fcge bgdaec agced dfbea cgeabdf adcfbg fdc egcfad | fedca fadeb dabegc aedfb +acfbgd efcda cfagd decg de efcgdab eabfc gdaecf dae bedfag | fceda acdef ed cfeba +defbcg ge egb eagbdc afdgcb cgbae fcadebg geda dcagb efcba | gdecba abgce gbadc daeg +afbd fadgce gbfdea fcgedb bf bgf gefda bfedgac bgcea gaebf | bgfaed fdgecb fbgedc bfg +cbafgd cbdge bc cbd bcef fgbde afgbde fgcbed dgebfca edcga | cb cb acged fdgbec +acgd dceagf dc bafde fbaceg ced cdfbge fdeca egcabfd cgefa | dc egdcfa afegcd efcgbd +bgdfac fb aebgc bfde bdecaf bfa aebcf edabfcg cgdeaf daefc | decfa fb baf fcbdea +bdfegc gebda gecbfa fedbg fed dgfc fabdec dbcagef fd gfcbe | edcfbag dgfeb cdeafb fd +gbeadf fdcga ecadb bceg ge egd dgebacf beafcd aedgc cgbade | dabec dge begdac dgaebc +begc dcgbfa eb dfeag eafgb bae bcgaf gfaebc fbagecd becfad | gabdcfe fdcagb bgcdaf be +eca febdcg fedag ecdaf fcba beagdc fcdeb ca dbefca acebfdg | ebdcgf fdceb gecdab cedfbga +decfbga abgdce gefd afd aecdbf gcfeda acgde cafbg fd fadcg | edgf dafbceg egfd cedga +faedgbc fbgaec dacb eba geacdb bcgefd ba bdegc eadbg gdaef | dfcbge deabcg bfecadg gfcbaed +egfacbd acdgf gecdab ebacf abcfed eg begf caegf aeg bfgeca | dafbcge cadfg fbace cefdbag +dgcfbae ac gbfeca badce gcad dfgcbe defab cea acgdbe dbgce | cgdeba egcdb gcad cagd +dcfg agdfbc caedfgb df bagecf daf gcafb ebcad fdbac agebdf | bdfage fgdbac daf fd +agefbd agcbfde egafb eg adge fge bfaced egdbcf daefb cabgf | bagef afgbe eg efbcdg +adfegb caefgb ade ecgd cafed dbfeacg de fgcae fbcda fgadce | dbefgac eafcg gbaefc fedgac +dbafg ecfga gfbae bae egdbac geabfc gcedfab ebcf eb cagdef | be cbfe bae be +cfgadbe eca bcfadg ebdgac adgcb ebdca adbfe egcb cadfeg ec | adebgc feabd cae cgdfea +caefdg cdfagbe fadbc afd eacbd fd bcadeg cgfba dacfeb bfed | df afcgb fceabdg fda +edcgaf cfbdag cbfdaeg ec cae bgeafc cdafe abfde decg gdcaf | eca dbcafg aec ce +fbgae cagef egdbac cg gcdafbe cfbg bgefda gce ceadf gebfac | gadbce cdegba gc cg +bafgecd bdf ecabfg dgbfe dcefg gbefa bdea bdfcga bd bgfdae | cdfagb cfeabg faebgd fagbe +afg dfcg fg eacdbg fgadeb cfdgea ecagd fcagebd eacfg bacfe | fg dagecb egdca cfdg +dac dc fgcd agbecf gcdaef agbed edcabf fgace caged faecdbg | dabge gceaf gdafecb cdafgeb +aefbg egf bagcf afegdc dfgceab begd gafebd eafbd eg fabcde | egadfb feg bgcfa efg +fa debfg acgfdb eagbc dcebagf cedfbg dafe baf febga eagbfd | af cbfdga dcfgab befcdg +db dbfe fdbga cafdg adgceb egbfa dbg bgfdcea ceagbf befagd | afdbge dceabg gdfab fdaegb +fgeacdb cadg dfg edfga fdagce dg dfaec gebfa cbefgd defabc | geabf dfaec cfdae faegb +abdce bafcg gdecaf cegba fbcadge adbcfe degb eg bdcgae eag | abdec facbg edgb ebagcd +bcaef fg dgbcae adegb bafeg feadcgb egbfad fdgb fecagd efg | agfeb fge fdgb eadgb +dbfage cdab bgcaef ecb cb dgfce dfbce fedbgac deabf beadcf | cbfed dabfe ebadf cefbd +gcedb ceafdg dcg gecdfb dcfaeb cg egdba befdgac fdceb gcfb | begdc bedag eadgb dfecb +bf dbcgea eabdfc feb gbfeac fagb becga fcdaebg dcgef gecfb | efbdcag abceg gcdabef gcbef +ged dagfbe eg cgfe bgfacde gedac dceba agcfd cadegf gcfdba | gefc ge ge acegfbd +gfabed aecdgf ecbag dge gbdae befd bfgad fdcabeg de fagbdc | egbad afdbg dgacef gdafb +dabfegc gbcad gafd acd da fgbadc ecdabf bfgca fcabge gbdec | gbface fgcab bdgac ebdcg +afbceg cdgfb gb afcbed dfcbge gbf adfgc fecbgad egdb bcdfe | fedbc cfeabd edbg cfebgd +cbdae gc gdfc ebgdf gcafbe fbaecdg gbedc ecg fbgecd fdebag | gcedb ebgafc acfgdeb ceg +bdce efacgd dgfbc ebfgad bcfga gdc fgbedac egdfb dc bfdgce | bagdfec efdgb ecbd fdaegc +bdgefc fbca bc gfbcae fdcgae gdaeb cbega gcb efagdcb feagc | gcb bacefgd ecdbgf cfab +fdbe defcbga adf cfgeba gcdae bacef cfadgb df fdeca dcefba | cbegfa degfcab fad acgfbe +gabfdc ebcfd bacgf da fcgbea aedbfcg gdfa eadcbg cdfba abd | dab dabcf afcgb ad +gb bfgcae dbgf cadeg bagdc gefadcb gbc acdbef cgabdf dbafc | gb fbdcae afdbgce dabgc +cfgadbe agecfd ea gedfc edafc fage fbdgce ead aecdbg fabdc | fcbdage cdbage fbadc ae +decgbaf edcgba afgd aebgfd da bfeag gfbcae bad cebfd bfeda | ecfdb eagbf efdba eabgdf +cfdbae dc gbdef fbedag egbfcd gafec edc edacgbf egdcf bdgc | fceag gacfe daegfb bgdcef +cbgda egdfb agebd cgedfb aed bfgdcea ae agdefb efab facedg | gdcaef aefb faeb begfd +fdc begdf adecg gfaced cf efac abedfgc cbedag gdbacf fecgd | cdf fbgadc cabgdf acfe +fedbg gabfe feda gde fcdbg de dbegacf bdfaeg abcdeg cegbfa | bgaef gadebf efgbac gbefa +dgf fgdbea dg dafcb gdec edcfbga dbegfc gbdcf cfbge gcebfa | bdfgc dg egcfab bcdafge +ceg daecb gcfdea fgacbe ecadbfg eg gbacdf cgabf ebfg ecabg | acgeb bfgca geacdf cge +ge geabf gea abecgf fdabg caedbf egbc cgebafd cbfea agdefc | feabc bcdafe age eg +gecdba ebdfg gcdef ecf cefadb fgac cf ecgafd cbfgead adgec | dfecg afcg bcfead ecadg +gd cbfad fdagb cfbeag fabge efabdg aged bdgfec dgf gbfadec | acefgb eabfgc becagf bfgda +ebgc fedabcg fdbgce fdebg eg badgf ebcdf edg adcfeb cfgade | bgefd cbgefd bgefd abfdg +dgbfc abecfg gcdab fcgdbe dfge cbdfea defbc fgc dabgefc gf | gf dbgecf bafgec cgf +degbac fda cdbag eafgbcd df fdbc agfdcb dabfg fbgea fcgade | fd bdceafg fdagbce df +cedaf fgeabc egdbf gbaedcf aeg cgda dfaeg cfdbea fagdce ga | febadc gefad bfacde gae +gea ebfgdc bcae cgafd abecfgd gbced ea gbdeaf dcgae gebcda | efgdab fcegdb cbgade acged +cdabgef gb fceag fgb bfdgac gbcfa cbadfe dfcegb fbdca bgda | bg cbgfa dcfgeb afcgb +fcbage adefc gceda bdegca cbeag dgeb efacdgb cfbgda adg dg | gad gabced gebd dg +ecbdga gedbf dafeg faecbdg eacfg dbaf ad dbfcge gda dfbeag | ad gfbcde dgfea aecfg +agfbde begfca bca baegc bc bcef ecdgbfa adegc bgaef acbfdg | fdbcag baecg cgdbaf bcdagf +beafc badfc daecfb fd fad fdec badefg cbdag fbecgad gecfab | dcfe cbgeaf gdcfabe agdbc +caedgbf fcgead ca gbadf abcd adcfbg fegbc dfaebg gfbac agc | fcgeda dbac afcgb dafebg +gdfeb gdbafe bc ecb ebfagdc bgfce gfeca fdcbge aebdcf bcdg | cdfbeg gdbfe gefcb dbcafe +gfbca gcdfe dbafgc cafgbe eacfbgd cdb agdb db cgdbf ecdbaf | adfcbe abdgfc cdb fcabed +bcdaf fbed edbac cdaegf ed dbgaecf edc ebgac dbagfc fdbace | cbgae efdb gcdafe gbafedc +cdfba cbdfae cfga bafdgc aedfgbc dbgef dag adgfb bdaegc ag | ebacgd adfgcb bdaefc gfac +caefd ce abfdc egcbdf cfe fgaced bdgfea gcae fadcbge eagfd | fcdae fgecad ec cbefgd +eafbd deb aefdg bd aecfbg bdcf abcfe gebcdaf agdbec bcaedf | dbcfae abfecd efabcd cbafe +bdafeg efg gfcdae bagfd dfacgb ef dgfecba befa efbdg dbceg | fe gadbf aebfdg afeb +cgbef ceb bfdgcae gedbac acgfbe be gceafd eacfg fcdgb fbea | abcedg dcgefa be fcegadb +gacb gfbaedc fagdc baf gadcef bfcdea fgebd gfabd cfdgba ba | baf cadfg gbfad fab +gafce df cbdfge gfd gdecb gecdf fdeb cadbeg agdbcf abgdcef | cgfea abgcde decgf fgcdbea +egdbf cbfgde aed befa gfdbae ea abcgd edfcga bcaegdf agdbe | bfae cagbfde cbgda gedcaf +eb dfbacge dbgae becafg abe gadfb cdega cedagb ecfgad debc | cfgeda fagedc afdbg fdcega +efcba becagd gafcdbe eafdbg dagbcf agfbd gefd de bfaed deb | fabce bgaedc ceadbg bed +cbaedf fdgebca gdbe dabce eag ge bacge bagcf decfga bgecda | defgabc bceagd aeg gbacf +dgeabf aefgcdb ad bcfae bdacf dacg bgfdc ebfdgc gfdbac abd | dcga adgc decfbg bafce +fgcba cbdfeag dagfb dcgbaf dcaegb ecbafg bdg bd fcbd faegd | bgdaec feadg cbdage dcgafb +bdc dcfgeb ebgca bdea bdcga abfecg gdcaf bd aecdbfg aebgdc | bade bdecgf bdc cbadg +bcdaeg facgbd caedfb aefdb dgfbe eba ae dcegfab fcea fbcad | cbafed baecdf ae ceabfd +efcbg egd dg cabgef bfdceag fgcbde fdcea gdfb dgebca dfcge | fdgb gd fbgd deg +cbgdfa ebgcfa abdge bdeca efcgbad cd fbedac abecf adc edcf | agebd gfabedc dabfegc abfce +edg abdgce gcefb dcbge dgabfe gcdab de cdebfga cdae fdabcg | gbdafc agcdb dgfceab bafgdec +acdb dgbfec eagfcdb dafbec cae ebdfc ca gfaed acdef gfebac | defac begdfc daegf fdeacb +cgedf gfadce debgcf fedagcb aefbc bcdagf db ebfcd bfd begd | db cgfde dbefc gedcfb +afcbegd dcfge edgbf bdg fabd dabfeg gaebdc abgecf gfeab db | debacg gfbaec fadbegc afcgbe +fcbg cdegf ecdga eacdfb befdg dcf fc dfegba dbfgce agdfcbe | dcf adcge fbcg dgaefbc +bcfea fcbead ecd cgeafb aebcgd bfed bcgedfa de cadfg fedac | de egadfbc debf bfagec +efcdabg afecbd defba cabfd ebca cgdaf dfabeg bc efcdbg fbc | bgdefc afcgebd gdefcb efabgd +edbaf agfbcde gbfcae ag dega aefcdb dfbega dfgbc afdgb bag | dagefb ga decbfa aecbgf +cbdg aegbcfd badce dgaebf abdcfe gad cgeda gd fcage ceagbd | fdcaeb dbeca beafdc bdace +decb dagfe dcgbafe fecbda acfdb adfbcg agefbc fec ec faced | fcadeb cdagfb agbfce gcfdba +acdbef dgca gbfae agecfdb ebdcg bda bgeda gedbfc ad bcadge | cgdbe cdag dcga efdcgab +gc efbdg eadcf ebcafg adecgf gfdbaec gcf gcda dcgfe dcbaef | gc acedbf fcead gdca +bfgce dabfg ecdf cebgfa dfegb ed deb fecbgda becgda cfbedg | cdgbefa ebd gafdb cdgefba +ce gecb ecd debaf ecdfb dcfega dagcbef fbgcd bdcgaf dcgfeb | dec dfbec agcfed bedfa +cgbfd gb dcafg gadb gbfcea bcfdeag fcbde fbg gcbfad agdfec | dcfgab bfgdc dfaceg dfgac +bgacef cdagf bgdcae gd dag dbagfc fecagbd fdbg cfead agbfc | gfcba adgcf facgb gd +efdc adbgc gec acfgde feadg gbecaf fbdgae agdec daefbgc ce | ec cedf cge bdfagce +aecdbg cabfe acfgeb bcefda fgac fdgeb afdcbge bcg cebfg gc | gcbfae febcda facg baefcg +dgbafce gfacdb gecb dcaefg gfaeb egf gebacf bdefa bgcaf eg | abfge fgabe fge deagfc +ceafdb dcbega afd gdbeaf fdgea fgeac gbade cbfadeg fd dfbg | adbcge gdcfeab afd fd +dacegf ed dfcbg cfgea dcfge fcgdbae acgbef ced eagd abefcd | dfbeac fgcdb geda dbfgc +egbcdf ecbdga afegc aefdbgc dgeca dge dg dcfbae dgab cdbea | gcead eabdcf gdeac cfadbe +gca fceagd fdgbc ga fecab fgcabed bgcaf cdbfge adbg acdfgb | agdb bfadcg bfgac gbfca +acgdeb baefd fa gdfa bgdea bdcfe fdagebc fdgbea ecfgba fab | adbecg agcbed febagc feagcdb +fedagc dcfge ef bgdcf gdceba egf fead edcag gfbaec fdgaebc | cgade aecfdg efg eadf +dbagf gcdefab fc badfc cbaed gfadbe dgfc gfbcad gaebfc bcf | cfb cdbea bdagf fc +bae be gcadeb dbge dgebacf eagcd geabc fbcga eagfdc edbafc | gcabf ecdfbag afbcg cbgfa +bd gdbcf cbfegd cfbeag febdagc fbd fcgeb decb afgbed dfgac | cbefg eadcbfg cbegfad egdfcb +febacg dega cegfd cefda ae agebcfd abcdf eca defacg ecgfbd | badcf cae bdcefg acedf +geabcd gdbcfa gaedc cbeagf bdgeacf gdefc bdacg ae adbe cae | gcebad agfbdc gefbcad ea +fa bfdacge adecgb eacf bdfgac gfdbe aegdc egacfd gadfe fga | gedfb egfbd efagd dagfbc +gcdb dg beagdf feacg cebgdfa afbcd adcgf dbfcga ebfdac agd | gd acdfg dcbaf gacfe +aefgbd cgfdb gfdea eabfgc dcgfe cfe ceda gdcaef ce fdeabgc | bdcgf edgaf cbdfg egfbda +facegb cfdabeg bd cedgbf adcfeb cfabe cdb eadb cgdfa dfbca | dfbca eadb adecbgf bdc +bacfeg agfcdeb acegf gfcade ecagbd fdbag afegd cdfe ed edg | dfce egd degaf dagfb +df gdfcea efbadg cegafbd eacfd fad cedbga dgaec dfcg fbcea | caedg dgafbe edgac df +bfdac cdbgfa cefbgd bfag afgbdec cdgafe cbfdg acf ecbda fa | dgcfae af cabfd beadc +befgd dea ecab baefcd gfbcad ea bafcd dbcgefa afebd cadfeg | gfbadc eda cadgfb eda +gf cgadb gebf becfdga gaefcd febac gcbaf cbfdea bfgeac fag | fg afcbg efbg afg +ba aebg gafdceb bca bdacg dagcf fcbdae gcbed cadebg bgcefd | dcagf gdabc afgcd edcfgb +de dbec bfaecdg gdfeca fegcb edg dbgaf fceabg febcgd bgdef | afdbg adbfg debfgc bdgfa +afbced adebfg efagdbc caebf afgec ecgb ega eg fgdac acegfb | aedgbf cbge egbfda badfgec +fg gbfcdea eafbcd fdaeb cdage egf agdefb fdcbge efgda fgab | deacg cdage gedca adfeb +gde gbdc dg fdgec dfaegb fedca bcgefd fbeacg gadecbf fcbeg | cgfabe edcgf fgeabdc cbefg +befcdg agbcef fcbdeag gdfae bdecf eab fcdeab ab efbad bcad | cfgeba befda aefgd degbcfa +abcef dbfaegc aefcg dcgbae fbcg efgacb cg cdabfe gec dfeag | dgfae gdefa agcbde afbced +dgf fcbega afdbeg fgabe dg efadg bged adfbceg agbcfd fedca | aefgb begd fceda debg +cdgaeb ba befgdca defbc gdecaf bae gabc afgdeb gedac decab | fbecd bae gdecfa edcba +ebagfd dfg dcbaeg dgbceaf gf gacdf fcade gacbd gcfb fbagcd | adgfc acbgd edbagf degabc +gba eagbcf gb gbacf dacgebf bceg gcafed acfeg acbfd adegfb | abfcdeg dbcfage faecg afebgc \ No newline at end of file diff --git a/adventOfCode/2021/execute.go b/adventOfCode/2021/execute.go new file mode 100644 index 0000000..3a10cfa --- /dev/null +++ b/adventOfCode/2021/execute.go @@ -0,0 +1,43 @@ +package main +// Iterate the day problems --> read inputs --> execute the solution --> print result + +import ( + ioutil "io/ioutil" + "strconv" + "strings" + "fmt" +) + +func main() { + dayChallenges := map[int]func(input []interface{})(int,int) { + 1: solve1, + 2: solve2, + 3: solve3, + 4: solve4, + 5: solve5, + 6: solve6, + 7: solve7, + 8: solve8, + } + // Iterate day inputs + for day, fun := range dayChallenges { + folderName := strconv.Itoa(day) + inputFiles := []string{folderName+"-sample" + ".input", folderName + ".input"} + for _, f := range inputFiles { + var inputs []interface{} + body, err := ioutil.ReadFile(folderName + "/" + f) + if err != nil { panic(err) } + input_strs := strings.Split(string(body), "\n") + for _, val := range input_strs { + if val == "" { continue } + inputs = append(inputs, val) + } + if strings.Contains(f, "sample") { + fmt.Print("[Samples] Day " + folderName + ":") + } else { + fmt.Print("[Problem] Day " + folderName + ":") + } + fmt.Println(fun(inputs)) + } + } +} \ No newline at end of file diff --git a/adventOfCode/2022/1.go b/adventOfCode/2022/1.go new file mode 100644 index 0000000..6099632 --- /dev/null +++ b/adventOfCode/2022/1.go @@ -0,0 +1,55 @@ +// Day 1 +package main + +import ( + "sort" + "strconv" + "errors" +) + +func solve1(input []interface{}) (interface{}, interface{}) { + + var day1Inputs []int + + // Customize input + for _, val := range input { + typeVal, ok := val.(string) + if !ok { + panic(errors.New("typecast failed")) + } + if typeVal == "" { + day1Inputs = append(day1Inputs, -1) + continue + } + integer, err := strconv.Atoi(typeVal) + if err != nil { + panic(err) + } + day1Inputs = append(day1Inputs, integer) + } + + // Solution 1 + caloriesPerElf := make([]int, len(day1Inputs)) + sol1 := 0 + currentElfCarrying := 0 + for _, calorie := range day1Inputs { + if calorie == -1 { + caloriesPerElf = append(caloriesPerElf, currentElfCarrying) + if currentElfCarrying > sol1 { + sol1 = currentElfCarrying + } + currentElfCarrying = 0 + continue + } + currentElfCarrying += calorie + } + + // Solution 2 + sol2 := 0 + sort.Ints(caloriesPerElf) + sol2 += caloriesPerElf[len(caloriesPerElf)-1] + sol2 += caloriesPerElf[len(caloriesPerElf)-2] + sol2 += caloriesPerElf[len(caloriesPerElf)-3] + + return sol1, sol2 +} \ No newline at end of file diff --git a/adventOfCode/2022/1/1-sample.input b/adventOfCode/2022/1/1-sample.input new file mode 100644 index 0000000..2094f91 --- /dev/null +++ b/adventOfCode/2022/1/1-sample.input @@ -0,0 +1,14 @@ +1000 +2000 +3000 + +4000 + +5000 +6000 + +7000 +8000 +9000 + +10000 diff --git a/adventOfCode/2022/1/1.input b/adventOfCode/2022/1/1.input new file mode 100644 index 0000000..1f757be --- /dev/null +++ b/adventOfCode/2022/1/1.input @@ -0,0 +1,2236 @@ +7896 +4992 +1382 +2920 +7533 +2709 +6020 +5321 +2698 +6806 +8008 + +1340 +1472 +7147 +2707 +5491 +7003 +2337 +1401 +5309 +4385 +2805 + +6019 +1924 +8917 +6303 +9358 +3640 +1563 +1902 + +10946 +10333 +8504 +6110 +10157 + +4578 +1711 +3343 +6159 +4045 +3487 +3070 +5663 +3518 +5839 +5911 +4970 +4852 +4512 + +4277 +3324 +6172 +8272 +2707 +3292 +6599 +1204 +7030 +3075 + +6907 +5595 +10251 +8654 +4036 +11545 + +16787 +11035 +12217 + +2196 +1519 +5810 +6837 +1193 +6480 +1237 +1659 +4323 +2896 +3878 +2894 + +15886 +20356 +23636 + +8795 +7986 +14228 +15738 +13503 + +6598 +17951 +17508 +2446 + +1382 +3232 +6467 +2791 +6250 +2704 +3898 +5569 +8676 + +2582 +8767 +3195 +7957 +6614 + +24737 +34912 + +28868 +34308 + +2703 +20947 + +5548 +5930 +6705 +4227 +6120 +8723 +4597 + +5877 +1223 +5789 +2207 +3488 +5210 +3056 +4300 +3880 +1826 +5366 +4531 +2016 +5304 + +4226 +5314 +6437 +1737 +1229 +3757 +5128 +1058 +5940 +3344 +5188 +4963 +1403 +5498 + +4969 +3096 +7035 +2695 +4747 +5109 +6294 +7990 +1539 +2608 +2944 + +14127 +9751 +4842 +1106 +2779 + +11896 +6643 +15874 +10487 +4141 + +4696 +6644 +6285 +4321 +4080 +6888 +5213 +5048 +6545 +5848 +1690 +5351 +2560 + +17296 +4277 +8327 +7931 + +8374 +3794 +5435 +6968 +4768 +3458 + +5090 +5614 +9448 +10331 +1311 +12604 + +5126 +4860 +1299 +6934 +11746 +2628 +12132 + +6648 +8567 +10219 +2385 +3642 +10478 +7662 + +9206 +2176 +6472 +12314 + +7006 +9478 +2742 +12074 +11993 +3221 + +2458 +4271 +6417 +13749 +5411 + +7826 +4566 +10845 +4535 +5673 +8305 + +8264 +11302 +7040 +9481 +9935 +6624 +8376 + +10460 +20936 + +3456 +3498 +6808 +7408 +5543 +3673 +6672 +6650 +7560 +2477 +6505 + +6943 +3217 +6235 +5079 +1386 +3453 +1736 +4569 +1422 +2804 +5807 + +2241 +1925 +3348 +4805 +2575 +3656 +1379 +5628 +2348 +4652 +5052 +5788 +4128 +2160 + +4839 +3854 +3192 +4055 +1892 +5418 +6415 +1645 +1609 +3844 +3097 +2117 +4043 + +6996 +16021 +23549 + +5493 +5824 +7101 +5017 +8221 +5407 +1963 +6083 + +4896 +18916 +17584 +19464 + +2897 +1198 +1847 +4416 +3086 +2006 +1743 +1387 +3390 +1416 +4713 +3831 +2789 +5146 +2220 + +9452 +8265 +6453 +2831 +3803 +1928 +1047 +5087 +9454 + +2885 +1518 +5218 +2629 +5204 +3715 +4468 +4399 +3020 +5194 +5361 +4566 +5875 +3995 +3081 + +5435 +3159 +1378 +1333 +4491 +5405 +4858 +3744 +5468 +2313 +3014 +2236 + +7027 +5112 +6675 +1149 +5519 +7197 +5210 +3811 +1259 +3794 +2700 +6518 + +6066 +2040 +1948 +2972 +3816 +1477 +4477 +3085 +4169 +1245 +5008 +2016 +4449 +1544 +1511 + +5909 +3378 +12050 +6988 +11093 +8034 +2552 + +5647 +7225 +1416 +4531 +2148 +5176 +1086 +1268 +3907 + +8824 +12672 +6094 +4105 + +9982 +1255 +5102 +2060 +8348 +8610 +9019 + +6442 +8353 +2849 +6823 +5061 +8540 + +1020 +4819 +2371 +6452 +2589 +2140 +3018 +6422 +2079 +1049 +4183 +1959 +6889 + +3370 +20341 +6283 + +3568 +8914 +2474 +1840 +1092 +2901 +4619 + +5489 +5048 +2151 +1275 +4555 +6105 +6393 +5439 +1175 +3143 +1039 +6159 +4280 + +25302 +11104 + +16342 +19486 +6818 +5872 + +4287 +7300 +5106 +6009 +5397 +4743 +8786 +5374 +7723 +3342 + +7830 +4687 +3639 +5942 +8019 +7531 +4763 +8086 + +2928 +12662 +1729 +15599 +7031 + +4504 +8351 +3310 +2860 +7474 +1052 +7088 +7300 +7653 + +3800 +3285 +2244 +6146 +1527 +2496 +3373 +2935 +4073 +2708 +5854 +4532 +4265 + +38782 + +3895 +2886 +3397 +10665 +7954 +5994 + +3830 +4381 +4042 +3631 +2109 +2742 +2748 +1117 +2772 +1921 +4357 +2960 +4504 +6021 +2300 + +5684 +30508 + +5467 +4827 +7991 +4299 +4152 +7070 +1911 +1345 +5607 +6490 +5631 + +2288 +4534 +1402 +2221 +2137 +4623 +5745 +1848 +1638 +2562 +1095 +2539 +4090 +3929 +4330 + +3776 +11693 +1189 +2039 +2662 +11224 +9212 + +3778 +1619 +4008 +1706 +1926 +3844 +5194 +3554 +6272 +2988 +4779 +5481 +1443 +6297 + +1712 +6076 +7332 +5267 +6685 +2555 +4517 +8692 +1819 + +23640 +10894 +25482 + +10592 +9277 +1228 +1197 +9162 +4838 +3783 +2691 + +15579 +16090 +5228 +4273 +5288 + +4044 +10911 +4767 +8658 +5775 +9369 +5332 + +8063 +4322 +5109 +6744 +5653 +9544 +2610 +2241 + +3885 +1140 +10508 +11910 +6096 + +7234 +15371 +10892 +15338 +12191 + +3698 +3413 +3783 +3362 +1828 +1302 +3426 +3147 +5558 +2644 +3636 +5842 +5261 +3312 +3164 + +3088 +1303 +2194 +5841 +5330 +5986 +4108 +4571 +7161 +6276 +5920 +5011 + +6546 +30555 + +5922 +2401 +4792 +7175 +7942 +5040 +3601 +2213 +6802 +2244 +6891 + +2694 +7905 +6046 +3782 +5591 +3665 +4195 +4579 +4300 +1822 + +6308 +2993 +5663 +4780 +6638 +6503 +6307 +4682 +7281 +4580 +7441 +5611 + +9706 +4619 +2108 +8345 +2422 +12140 +9146 + +4984 +10121 +4062 +3797 +5130 +1641 +11492 + +7592 +9412 +5474 +7809 +8073 +2056 +3839 +3557 + +7893 +3556 +9427 +2836 +10256 + +4410 +3041 +2124 +5830 +4200 +4102 +5146 +3355 +4318 +5422 +4992 +1979 +2696 +5277 +4058 + +13134 +35366 + +5363 +1706 +4925 +5967 +8514 +3362 +1424 +4427 +8906 + +2891 +4388 +10112 +3409 +2477 +1138 +3790 +4712 + +9130 +4622 +9723 +4660 +2778 +1083 +2326 +9254 + +3221 +4739 +3752 +1220 +10337 +1159 +2367 +1900 + +2038 +5545 +5904 +5378 +4334 +2897 +5745 +3670 +4773 +3087 +5760 +4026 +3719 +3084 + +8674 +8656 +4162 +5125 +4183 +3496 +7379 +6150 +5225 +8014 + +10321 +16081 +6163 +2030 + +31755 +18352 + +1666 +15493 +8858 +15689 + +1903 +7006 +9002 +5067 +9397 +8703 +7534 +8188 +4983 + +4398 +12055 +6820 +2412 +10308 +11231 + +5914 +9582 +4568 +7679 +5867 +5798 +2955 +7834 +1833 + +2554 +1886 +4590 +3753 +3161 +4039 +2435 +1172 +2690 +4564 +5160 +3715 +2834 +6074 +1251 + +9837 +4501 +3669 +7682 +2762 +6072 +8731 +2324 + +7030 +6956 +3040 +2185 +4717 +2907 +5255 +1194 +1309 +5100 +5630 +5164 + +18808 +5780 +13062 +16131 + +5436 +13758 +12390 +14884 + +5344 +3178 +1907 +6945 +6435 +3985 +3637 +6984 +2108 +2282 + +6870 +3774 +4149 +3361 +3208 +3696 +4265 +2295 +7068 +4365 +6729 + +9828 +3819 +7654 +2391 +11354 +6751 + +5409 +6025 +6772 +4005 +6894 +2723 +2485 +5866 +5744 +1804 +2509 +3285 +5663 + +6630 +7966 +6366 +2854 +3478 +6566 +3790 +4047 +8471 +5911 + +5930 +4813 +10365 +1430 + +13119 +11915 +4732 +9949 +13699 +9790 + +3413 +3027 +5513 +3320 +4421 +2507 +5781 +2622 +5472 +6590 +2021 +2164 +4106 + +49386 + +3656 +7422 +6157 +5982 +3944 +5726 +2628 +6618 +6138 +2186 +4744 + +33805 + +9976 +4213 +4359 +3723 + +4106 +1423 +3334 +5115 +3819 +1308 +2652 +5954 +4439 +2188 +3415 +1104 +2973 +1681 +4704 + +64085 + +1097 +4369 +3803 +3247 +5135 +6928 +3419 +2418 +5130 +2555 +3043 + +4831 +2425 +2023 +1667 +6410 +6422 +5851 +4966 +6721 +5312 +3792 +6700 +1545 + +1742 +5176 +8587 +9261 +15254 + +3097 +6016 +5558 +3004 +4372 +1986 +5576 +6105 +1709 +1326 +4997 +5528 +2823 +3072 + +1228 +2891 +3056 +5874 +2267 +2232 +1754 +3979 +1881 +6633 +1889 +5506 +4377 + +3703 +6310 +1020 +4891 +4911 +2913 +3888 +4642 +1963 +3716 +2222 +4528 +1030 +6081 + +10172 +1472 +6212 +9125 +9365 +7866 +3525 +4752 + +2546 +2326 +5739 +1010 +4724 +5324 +2495 +2999 +5272 +1937 +4396 +6333 +3632 + +2944 +1285 +3457 +1980 +2346 +5712 +5088 +3718 +2036 +6725 + +4335 +5577 +4533 +3275 +4297 +2774 +5029 + +1396 +5993 +4058 +1095 +4388 +1843 +1643 +6192 +2801 +2583 +4286 +5483 +2308 +1577 + +1584 +7552 +8133 +9503 +1989 + +4584 +7691 +4707 +5757 +2519 +2097 +1460 +6651 +3569 +1159 + +9366 +3998 +2020 +2598 +2166 +3298 +6533 +1323 + +10007 +2282 +10952 +3217 +8819 +7164 + +3095 +1126 +1893 +1540 +3172 +2310 +2566 +2438 +4431 +3423 +6675 + +4131 +9513 +11678 +5248 +7769 +3887 +3494 + +5382 +1013 +4021 +7366 +12330 +13746 + +3536 +4407 +1205 +6210 +1388 +6202 +5314 +3286 +6888 +3049 +3946 +3684 +4187 + +1934 +1285 +3262 +4136 +5790 +1340 +2597 +2992 +3008 +5698 +3688 +3086 +2459 +2413 +4769 + +2150 +1030 +3068 +3747 +5417 +4237 +3311 +5081 +4846 +5555 +4650 +3830 +2209 +3069 + +9935 +9564 +15110 + +3038 +2079 +1059 +4905 +4104 +3502 +6338 +1366 +5990 +6073 +4692 +4706 +3474 +3469 + +5845 +1176 +5553 +4578 +3868 +6154 +4799 +5079 +5927 +4185 +1806 +4449 +6248 + +1280 +2823 +1372 +5899 +2547 +5738 +1545 +1046 +2917 +4931 +6094 +3690 +5021 +4657 +1214 + +3046 +4952 +1138 +2373 +1412 +4848 +5772 +4750 +4741 +5752 +5977 +5270 +5526 +3509 +1793 + +3228 +9849 +11815 +6507 +10144 +4756 + +5119 +1764 +1718 +4813 +3662 +4731 +2755 +1315 +1975 +5716 +4859 +4748 +4809 +1296 +1689 + +2909 +7209 +6124 +3235 +4089 +1271 +6220 +10328 + +5630 +10237 +5572 +1065 +2126 +7181 + +32487 +2379 + +2718 +4228 +7834 +6711 +7619 +6321 +1080 +8584 +6860 +6542 + +5106 +8514 +6109 +1204 +5159 +7935 +7292 +8114 + +5898 +4837 +6825 +4587 +1021 +5713 +4862 +3864 +2022 +1129 +4444 +6439 +4369 + +8875 +7916 +2177 +2085 +8103 +7908 +6266 +9099 + +23274 +30650 + +5537 +21092 +21841 + +5852 +9025 +4459 +4883 +2577 +4679 +5673 +1548 +6726 + +4034 +2542 +15179 +6499 +3472 + +2228 +5558 +7863 +5080 +6441 +2064 +1676 +8473 + +18854 +5610 +18471 + +1196 +3063 +13221 +19006 + +37369 +24756 + +4271 +6806 +6381 +6363 +5221 +5729 +3829 +7832 +1150 +3352 +3210 + +1422 +2606 +6070 +4950 +4300 +4023 +1862 +5027 +5668 +5058 +3969 +2359 +5394 +6001 + +12165 +13318 +11945 +12507 +11398 + +9539 +8607 +7451 +11189 +11056 +3209 + +5845 +2759 +4046 +3838 +2768 +1168 +1237 +6370 +3384 +3938 +3946 +5028 +2603 + +20671 +8067 +7232 + +7376 +3530 +3343 +4917 +6712 +5080 +5846 +2774 +3020 +5738 +5500 + +5185 +2455 +6887 +7349 +1917 +2435 +2458 +3676 +1783 +8567 + +5585 +3750 +2664 +6867 +1506 +6830 +1279 +7877 +2757 +4091 +2731 + +11132 + +6128 +2421 +5519 +4390 +6457 +2769 +1410 +3365 +5682 +5685 +1502 +3245 + +1265 +7559 +8923 +1805 +9738 +3780 +9131 + +3052 +5440 +1672 +3462 +1053 +2902 +2137 +5053 +4905 +3544 +4374 +2718 +5799 + +24868 +18500 +13495 + +4653 +5142 +2117 +2908 +2324 +4335 +1096 +6733 +2380 +5352 +1830 +1893 +2491 + +3142 +4111 +4577 +6019 +1075 +2596 +4950 +5814 +5880 +5573 +3672 +2623 +5602 +1032 +5599 + +7365 +2959 +6303 +6111 +4607 +6530 +4873 +4367 +3776 + +16700 +7439 +4758 +6160 + +4203 +1817 +2941 +5662 +1387 +1698 +3031 +3718 +6087 +4971 +5592 +4460 +5271 +3867 +4998 + +22671 +4704 +23657 + +5028 +5059 +4212 +1200 +2284 +6082 +4589 +4383 +4682 +1243 +6449 +1380 +4515 + +10431 +11132 +13078 +3070 +8963 +1329 + +3931 +6924 +5760 +2448 +4709 +13742 + +4493 +4759 +5130 +5004 +7898 +8508 +6718 +2769 +5103 +4254 + +2261 +4383 +1602 +3767 +4634 +3704 +4242 +6316 +5351 +3531 +3470 +3904 + +3541 +2879 +1596 +4477 +1209 +2089 +4365 +4813 +1830 +1069 +2994 +6076 +3379 +4130 +4102 + +11774 +16285 +15432 + +1364 +3558 +5162 +4115 +2730 +3464 +2673 +4541 +5020 +5299 +3199 +3221 +4372 + +2696 +2080 +4206 +1901 +6091 +4955 +2674 +2184 +4977 +4339 +1011 +3766 +5911 +5316 +3703 + +21030 + +6714 +3093 +1168 +1507 +5134 +6516 +1572 +8383 + +5080 +7055 +6559 +4514 +7036 +7348 +5836 +2223 +1996 +4888 +3666 + +25117 +18822 + +2855 +4165 +4812 +8068 +6471 +4447 +4482 +4775 +1002 + +5999 +5674 +4022 +7403 +5593 +6164 +5109 +6856 +3449 +1689 +3727 +2115 + +5781 +4639 +3684 +4010 +4018 +1004 +3081 +1003 +1702 +1457 +1301 +2122 +2014 +5790 + +6373 +1849 +4389 +5772 +4888 +7981 +4238 +1476 +5550 +2922 + +1513 +8603 +5489 +6664 +4505 +7378 +4185 +8087 +6799 + +6482 +3622 +5516 +6214 +6243 +6214 +4711 +3038 +3398 +5483 +3145 +3536 + +9125 +5549 +8576 +5240 +6032 +7952 +5140 +7580 + +6079 +2048 +4407 +5706 +2535 +4588 +5182 +3204 +5287 +5221 +2457 +6932 +4174 + +5505 +1576 +13849 +5436 +2535 +3865 + +2178 +5420 +1013 +6435 +3810 +2903 +5079 +4332 +6257 +1344 +4511 +3127 +6464 + +3805 +2215 +1614 +2501 +1067 +1874 +6199 +1733 +2146 +6581 +3514 +1175 +1099 + +6473 +3376 +4934 +5773 +4970 +7229 +5716 +1014 +7507 +6012 + +3636 +3377 +5729 +2413 +6252 +3314 +2928 +2317 +1157 +2788 +3842 +3906 +4650 +5338 + +5103 +2724 +3794 +1431 +5838 +3971 +2107 +6475 +1746 +5986 +3736 +6345 +4124 +5664 + +3774 +2420 +1478 +2100 +2608 +1168 +1584 +1266 +1346 +1262 +6217 +6392 +2148 +4525 + +3294 +14112 +2438 +13482 +4287 + +10170 +4078 +4238 +3724 +8472 +9110 +5386 +3743 + +10397 +11155 +4476 +7990 +8374 +3340 +4575 + +27723 + +7777 +9699 +8470 +1721 +7728 +1288 +4458 +3428 + +12000 +5191 +8549 +9184 +3081 +11587 +9430 + +13626 +2596 +12534 +7672 +5161 +1160 + +7830 +3505 +7940 +4756 +6977 +3085 +2639 +6439 +4919 +1421 +5196 + +2714 +1424 +7020 +8593 +1436 +7652 +1146 +4168 +2069 +5958 + +38215 + +1436 +6327 +10725 +4280 +4509 +10301 +5183 +5166 + +6068 +8243 +6171 +5575 +9093 +6123 +2831 +5664 +6278 + +4093 +4619 +2578 +5902 +1131 +3288 +4886 +4994 +6088 +6377 +1852 +4254 +1419 +1504 + +7127 +8649 +2523 +8023 +3063 +2677 +1759 +8632 +7805 +2999 + +3419 +1111 +5599 +1055 +3407 +4964 +3556 +7249 +1100 +7148 +1852 +1549 + +5414 +11474 +1685 +8818 +10288 +6138 +1983 + +23129 +2195 + +3104 +1599 +2327 +3640 +2230 +2791 +2344 +1035 +1046 +3399 +5096 +1067 +1987 +5786 +1395 + +32647 +10609 + +6020 +2279 +8718 +3103 +7022 +6464 +6180 +3968 +3275 + +3221 +5381 +6110 +1860 +4557 +4705 +3658 +4172 +5002 +5578 +1355 +4114 +3501 +4821 + +1312 +1921 +2644 +5044 +3336 +4520 +1253 +3184 +3732 +6754 +2139 diff --git a/adventOfCode/2022/10.go b/adventOfCode/2022/10.go new file mode 100644 index 0000000..b45c4e0 --- /dev/null +++ b/adventOfCode/2022/10.go @@ -0,0 +1,114 @@ +// Day 10 +package main + +import ( + "fmt" + "strconv" + "errors" + "strings" + mapset "github.com/deckarep/golang-set/v2" +) + +func printCRT(crt [][]string) { + fmt.Println("") + for _, row := range crt { + fmt.Println(row) + } +} + +func solve10(input []interface{}) (interface{},interface{}) { + + var day10Inputs [][]string + + // Customize input + for _, val := range input { + instruction := strings.Split(val.(string), " ") + if len(instruction) == 0 { panic(errors.New("input error")) } + day10Inputs = append(day10Inputs, instruction) + } + + // Solution 1 + sol1 := 0 + cycles := 1 + register := 1 + for _, ins := range day10Inputs { + if ins[0] == "noop" { + cycles++ + } else if ins[0] == "addx" { + num, err := strconv.Atoi(ins[1]) + if err != nil { panic(err) } + cycles++ + sol1 += calcStrength(cycles, register) + cycles++ + register += num + } else { + panic(errors.New("improper input")) + } + sol1 += calcStrength(cycles, register) + } + + // Solution 2 + sol2 := [][]string{} + cycles = 0 + register = 0 + crt := []string{} + + for _, ins := range day10Inputs { + //fmt.Println(crt, ins) + if ins[0] == "noop" { + cycles++ + if len(crt) >= register && len(crt) <= register+2 { + crt = append(crt, "#") + } else { + crt = append(crt, ".") + } + crt, sol2, cycles = resetCRT(cycles, crt, sol2) + } else if ins[0] == "addx" { + num, err := strconv.Atoi(ins[1]) + if err != nil { panic(err) } + for i:=0;i<2;i++ { + cycles = cycles + 1 + if len(crt) >= register && len(crt) <= register+2 { + crt = append(crt, "#") + } else { + crt = append(crt, ".") + } + crt, sol2, cycles = resetCRT(cycles, crt, sol2) + } + register += num + } else { + panic(errors.New("improper input")) + } + } + printCRT(sol2) + return sol1, 0 +} + +func resetCRT(cycles int, currCRT []string, sol2 [][]string) ([]string, [][]string, int) { + strong_signal := mapset.NewSet[int]() + strong_signal.Add(40) + strong_signal.Add(80) + strong_signal.Add(120) + strong_signal.Add(160) + strong_signal.Add(200) + strong_signal.Add(240) + if strong_signal.Contains(cycles) { + sol2 = append(sol2, currCRT) + return []string{}, sol2, 0 + } + return currCRT, sol2, cycles +} + +func calcStrength(cycles int, register int) int { + strong_signal := mapset.NewSet[int]() + strong_signal.Add(20) + strong_signal.Add(60) + strong_signal.Add(100) + strong_signal.Add(140) + strong_signal.Add(180) + strong_signal.Add(220) + if strong_signal.Contains(cycles) { + return cycles * register + } + return 0 +} \ No newline at end of file diff --git a/adventOfCode/2022/10/10-sample.input b/adventOfCode/2022/10/10-sample.input new file mode 100644 index 0000000..94cd0a8 --- /dev/null +++ b/adventOfCode/2022/10/10-sample.input @@ -0,0 +1,146 @@ +addx 15 +addx -11 +addx 6 +addx -3 +addx 5 +addx -1 +addx -8 +addx 13 +addx 4 +noop +addx -1 +addx 5 +addx -1 +addx 5 +addx -1 +addx 5 +addx -1 +addx 5 +addx -1 +addx -35 +addx 1 +addx 24 +addx -19 +addx 1 +addx 16 +addx -11 +noop +noop +addx 21 +addx -15 +noop +noop +addx -3 +addx 9 +addx 1 +addx -3 +addx 8 +addx 1 +addx 5 +noop +noop +noop +noop +noop +addx -36 +noop +addx 1 +addx 7 +noop +noop +noop +addx 2 +addx 6 +noop +noop +noop +noop +noop +addx 1 +noop +noop +addx 7 +addx 1 +noop +addx -13 +addx 13 +addx 7 +noop +addx 1 +addx -33 +noop +noop +noop +addx 2 +noop +noop +noop +addx 8 +noop +addx -1 +addx 2 +addx 1 +noop +addx 17 +addx -9 +addx 1 +addx 1 +addx -3 +addx 11 +noop +noop +addx 1 +noop +addx 1 +noop +noop +addx -13 +addx -19 +addx 1 +addx 3 +addx 26 +addx -30 +addx 12 +addx -1 +addx 3 +addx 1 +noop +noop +noop +addx -9 +addx 18 +addx 1 +addx 2 +noop +noop +addx 9 +noop +noop +noop +addx -1 +addx 2 +addx -37 +addx 1 +addx 3 +noop +addx 15 +addx -21 +addx 22 +addx -6 +addx 1 +noop +addx 2 +addx 1 +noop +addx -10 +noop +noop +addx 20 +addx 1 +addx 2 +addx 2 +addx -6 +addx -11 +noop +noop +noop \ No newline at end of file diff --git a/adventOfCode/2022/10/10.input b/adventOfCode/2022/10/10.input new file mode 100644 index 0000000..4698f3d --- /dev/null +++ b/adventOfCode/2022/10/10.input @@ -0,0 +1,140 @@ +noop +noop +noop +addx 5 +noop +addx 1 +noop +addx 4 +addx 25 +addx -20 +noop +noop +addx 5 +addx 3 +noop +addx 2 +noop +noop +addx -1 +addx 6 +addx 1 +noop +addx 4 +noop +addx -37 +noop +noop +noop +addx 3 +addx 32 +addx -25 +addx 2 +addx 3 +noop +addx 2 +addx 3 +noop +addx 2 +addx 2 +addx -24 +addx 25 +addx 5 +addx 2 +addx 8 +addx -23 +addx 18 +addx 5 +addx -39 +addx 11 +addx -9 +addx 6 +addx -2 +addx 5 +addx 4 +addx -4 +addx 3 +addx 5 +addx 2 +noop +addx -1 +addx 6 +addx -21 +addx 22 +addx 3 +addx 1 +addx 5 +noop +noop +addx -35 +noop +noop +noop +noop +addx 37 +addx -33 +noop +addx 6 +addx 2 +addx -1 +addx 3 +addx 1 +addx 5 +addx 2 +addx -19 +addx 21 +addx 1 +addx 5 +addx -31 +addx 36 +noop +addx 3 +addx -2 +addx -38 +noop +noop +addx 7 +addx 14 +addx -4 +addx -7 +addx 5 +addx 2 +addx 12 +addx -15 +addx 6 +addx 2 +addx 5 +addx -27 +addx 25 +addx 5 +noop +addx 7 +addx -2 +addx 5 +addx -40 +noop +addx 7 +noop +addx -1 +addx 2 +addx 5 +addx -1 +addx 1 +addx 2 +addx 7 +noop +addx -2 +noop +addx 3 +addx 2 +addx 7 +noop +noop +addx 1 +noop +noop +addx 3 +addx 1 +noop +noop +noop \ No newline at end of file diff --git a/adventOfCode/2022/11.go b/adventOfCode/2022/11.go new file mode 100644 index 0000000..47318ee --- /dev/null +++ b/adventOfCode/2022/11.go @@ -0,0 +1,197 @@ +// Day 11 +package main + +import ( + "fmt" + "strings" + "errors" + "strconv" + "math" + "sort" +) + +type monkey struct { + name int + items []int + op string + opNum int + divisbleTest int + throwTrue int + throwFalse int + inspectTimes int +} + +func printMonkeys(mks []monkey) { + for j, m := range mks { + fmt.Printf("\n %d: %+v \n", j, m) + } +} + +func printMonkeyItems(mks []monkey) { + fmt.Println("\n Items in each monkey are:") + for j, m := range mks { + fmt.Println(j, m.items) + } +} + +func solve11(input []interface{}) (interface{},interface{}) { + + var monkeys []monkey + + // Customize input + currMonkey := monkey{ + inspectTimes: 0, + } + for i, val := range input { + + line := val.(string) + if line == "" { + monkeys = append(monkeys, currMonkey) + currMonkey = monkey{ + inspectTimes: 0, + } + } else if strings.Contains(line, "items") { + items := strings.Split(line, ":") + items = strings.Split(strings.TrimSpace(items[1]), ",") + for _, it := range items { + itemNum, err := strconv.Atoi(strings.TrimSpace(it)) + if err != nil { panic(err) } + currMonkey.items = append(currMonkey.items, itemNum) + } + } else if strings.HasPrefix(line, "Monkey") { + names := strings.Split(line, " ") + stripName := strings.TrimSuffix(names[1], ":") + nameNum, err := strconv.Atoi(strings.TrimSpace(stripName)) + if err != nil { panic(err) } + currMonkey.name = nameNum + } else if strings.Contains(line, "Test") { + divs := strings.Split(line, " ") + divNum, err := strconv.Atoi(strings.TrimSpace(divs[len(divs)-1])) + if err != nil { panic(err) } + currMonkey.divisbleTest = divNum + } else if strings.Contains(line, "true") { + monkeyN := strings.Split(line, " ") + monkeyNum, err := strconv.Atoi(strings.TrimSpace(monkeyN[len(monkeyN)-1])) + if err != nil { panic(err) } + currMonkey.throwTrue = monkeyNum + } else if strings.Contains(line, "false") { + monkeyN := strings.Split(line, " ") + monkeyNum, err := strconv.Atoi(strings.TrimSpace(monkeyN[len(monkeyN)-1])) + if err != nil { panic(err) } + currMonkey.throwFalse = monkeyNum + } else if strings.Contains(line, "Operation") { + line = strings.TrimPrefix(strings.TrimSpace(line), "Operation: new =") + ops := strings.Split(strings.TrimSpace(line), " ") + opNum := 0 + if ops[len(ops)-1] != "old" { + convOp, err := strconv.Atoi(strings.TrimSpace(ops[len(ops)-1])) + if err != nil { panic(err) } + opNum = convOp + } + currMonkey.opNum = opNum + currMonkey.op = ops[len(ops)-2] + } else { + panic(errors.New("line match failed")) + } + if i == len(input)-1 { + monkeys = append(monkeys, currMonkey) + } + } + + // Solution 1 + sol1 := 0 + inspectTimes := make([]int, len(monkeys)) + + // 20 rounds + for r:=0; r < 20 ; r++ { + for i, m := range monkeys { + for len(monkeys[i].items) > 0 { + // 1. Pop the first item + currItem := monkeys[i].items[0] + if len(monkeys[i].items) > 0 { + monkeys[i].items = monkeys[i].items[1:] + } + // 2. calculate worry level + curWorry := calculateWorry(currItem, m.op, m.opNum) + + // 3. round worry level + round3 := int(math.Floor(float64(curWorry/3))) + + // 4. test logical flow + if round3 % m.divisbleTest == 0 { + monkeys[m.throwTrue].items = append(monkeys[m.throwTrue].items, round3) + } else { + monkeys[m.throwFalse].items = append(monkeys[m.throwFalse].items, round3) + } + + monkeys[i].inspectTimes++ + inspectTimes[i] = monkeys[i].inspectTimes + } + } + //printMonkeys(monkeys) + } + //printMonkeyItems(monkeys) + sort.Sort(sort.Reverse(sort.IntSlice(inspectTimes))) + sol1 = inspectTimes[0] * inspectTimes[1] + + + // Solution 2 + sol2 := 0 + inspectTimes = make([]int, len(monkeys)) + + // 20 rounds + for r:=0; r < 10000 ; r++ { + for i, m := range monkeys { + for len(monkeys[i].items) > 0 { + // 1. Pop the first item + currItem := monkeys[i].items[0] + if len(monkeys[i].items) > 0 { + monkeys[i].items = monkeys[i].items[1:] + } + // 2. calculate worry level + curWorry := calculateWorry(currItem, m.op, m.opNum) + + // 3. round worry level + //round3 := int(math.Floor(float64(float64(curWorry)/2.0))) + round3 := curWorry + if round3 > currItem*3 { + round3 = int(math.Floor(float64(float64(curWorry)/2))) + } + + // 4. test logical flow + if round3 % m.divisbleTest == 0 { + monkeys[m.throwTrue].items = append(monkeys[m.throwTrue].items, round3) + } else { + monkeys[m.throwFalse].items = append(monkeys[m.throwFalse].items, round3) + } + + monkeys[i].inspectTimes++ + inspectTimes[i] = monkeys[i].inspectTimes + } + } + //printMonkeys(monkeys) + } + //printMonkeyItems(monkeys) + sort.Sort(sort.Reverse(sort.IntSlice(inspectTimes))) + fmt.Println(inspectTimes) + sol2 = inspectTimes[0] * inspectTimes[1] + + return sol1, sol2 +} + +func calculateWorry(worry int, op string, opNum int) int { + if opNum == 0 { + opNum = worry + } + switch op { + case "*": + return (worry * opNum) + case "+": + return worry + opNum + case "-": + return worry - opNum + case "/": + return worry / opNum + } + return 0 +} \ No newline at end of file diff --git a/adventOfCode/2022/11/11-sample.input b/adventOfCode/2022/11/11-sample.input new file mode 100644 index 0000000..c04eddb --- /dev/null +++ b/adventOfCode/2022/11/11-sample.input @@ -0,0 +1,27 @@ +Monkey 0: + Starting items: 79, 98 + Operation: new = old * 19 + Test: divisible by 23 + If true: throw to monkey 2 + If false: throw to monkey 3 + +Monkey 1: + Starting items: 54, 65, 75, 74 + Operation: new = old + 6 + Test: divisible by 19 + If true: throw to monkey 2 + If false: throw to monkey 0 + +Monkey 2: + Starting items: 79, 60, 97 + Operation: new = old * old + Test: divisible by 13 + If true: throw to monkey 1 + If false: throw to monkey 3 + +Monkey 3: + Starting items: 74 + Operation: new = old + 3 + Test: divisible by 17 + If true: throw to monkey 0 + If false: throw to monkey 1 \ No newline at end of file diff --git a/adventOfCode/2022/11/11.input b/adventOfCode/2022/11/11.input new file mode 100644 index 0000000..825fbe7 --- /dev/null +++ b/adventOfCode/2022/11/11.input @@ -0,0 +1,55 @@ +Monkey 0: + Starting items: 62, 92, 50, 63, 62, 93, 73, 50 + Operation: new = old * 7 + Test: divisible by 2 + If true: throw to monkey 7 + If false: throw to monkey 1 + +Monkey 1: + Starting items: 51, 97, 74, 84, 99 + Operation: new = old + 3 + Test: divisible by 7 + If true: throw to monkey 2 + If false: throw to monkey 4 + +Monkey 2: + Starting items: 98, 86, 62, 76, 51, 81, 95 + Operation: new = old + 4 + Test: divisible by 13 + If true: throw to monkey 5 + If false: throw to monkey 4 + +Monkey 3: + Starting items: 53, 95, 50, 85, 83, 72 + Operation: new = old + 5 + Test: divisible by 19 + If true: throw to monkey 6 + If false: throw to monkey 0 + +Monkey 4: + Starting items: 59, 60, 63, 71 + Operation: new = old * 5 + Test: divisible by 11 + If true: throw to monkey 5 + If false: throw to monkey 3 + +Monkey 5: + Starting items: 92, 65 + Operation: new = old * old + Test: divisible by 5 + If true: throw to monkey 6 + If false: throw to monkey 3 + +Monkey 6: + Starting items: 78 + Operation: new = old + 8 + Test: divisible by 3 + If true: throw to monkey 0 + If false: throw to monkey 7 + +Monkey 7: + Starting items: 84, 93, 54 + Operation: new = old + 1 + Test: divisible by 17 + If true: throw to monkey 2 + If false: throw to monkey 1 \ No newline at end of file diff --git a/adventOfCode/2022/2.go b/adventOfCode/2022/2.go new file mode 100644 index 0000000..910f86f --- /dev/null +++ b/adventOfCode/2022/2.go @@ -0,0 +1,99 @@ +// Day 2 +package main + +import ( + //"fmt" + "strings" +) + +func solve2(input []interface{}) (interface{}, interface{}) { + + var day2Inputs [][]string + + // Customize input + for _, val := range input { + game, ok := val.(string) + if !ok { panic("typecast failed") } + play := strings.Split(game, " ") + day2Inputs = append(day2Inputs, play) + } + + abc := map[string]string{ + "A": "Rock", + "B": "Paper", + "C": "Scissor", + } + + score := map[string]int{ + "Rock": 1, + "Paper": 2, + "Scissor": 3, + } + + winner := map[string]string{ + "Rock": "Scissor", + "Paper": "Rock", + "Scissor": "Paper", + } + + loser := map[string]string{ + "Rock": "Paper", + "Paper": "Scissor", + "Scissor": "Rock", + } + + rps := []string{ + "Rock", + "Paper", + "Scissor", + } + + // Solution 1 + sol1 := 0 + max_score := 0 + total_score := 0 + + for _,i := range [][]int{{0,1,2}} { + xyz := map[string]string{ + "X": rps[i[0]], + "Y": rps[i[1]], + "Z": rps[i[2]], + } + total_score = 0 + for _, game := range day2Inputs { + p1 := game[0] + p2 := game[1] + elf := abc[p1] + bet := xyz[p2] + if winner[bet] == elf { // win + total_score += 6 + score[bet] + } else if xyz[p2] == elf { // draw + total_score += 3 + score[bet] + } else { // loose + total_score += 0 + score[bet] + } + //fmt.Println(total_score, score[bet], bet, elf) + } + if total_score > max_score { + max_score = total_score + } + } + sol1 = max_score + + // Solution 2 + sol2 := 0 + for _, game := range day2Inputs { + p1 := game[0] + p2 := game[1] + elf := abc[p1] + if p2 == "X" { // loose + sol2 += 0 + score[winner[elf]] + } else if p2 == "Y" { // draw + sol2 += 3 + score[elf] + } else { // win + sol2 += 6 + score[loser[elf]] + } + //fmt.Println(elf, p2, loser[elf]) + } + return sol1, sol2 +} \ No newline at end of file diff --git a/adventOfCode/2022/2/2-sample.input b/adventOfCode/2022/2/2-sample.input new file mode 100644 index 0000000..25097e8 --- /dev/null +++ b/adventOfCode/2022/2/2-sample.input @@ -0,0 +1,3 @@ +A Y +B X +C Z \ No newline at end of file diff --git a/adventOfCode/2022/2/2.input b/adventOfCode/2022/2/2.input new file mode 100644 index 0000000..d114be5 --- /dev/null +++ b/adventOfCode/2022/2/2.input @@ -0,0 +1,2500 @@ +A X +A X +B Y +B Y +A Y +A X +A Y +A X +A X +B Y +A X +A X +A X +A X +C X +C Z +A X +B Y +A X +A X +C X +C Y +A X +A Z +B Y +A X +C X +A X +B Y +A X +A X +A X +A Z +C X +C X +C X +B Y +B X +B Z +B Y +C X +A Y +A X +A X +B X +A X +A X +B Y +C X +B Y +A X +A X +A X +C X +B Y +C X +B Y +A X +C X +B Y +B X +B Y +C Z +A X +A Y +C Z +C X +A X +C X +A X +A X +C Z +B Y +C X +B X +B X +C X +A X +A X +A X +C Z +C X +B Y +A X +C X +B Z +A X +C Z +C Z +A X +A X +A X +A Y +A X +A X +B Y +A X +C Z +C Z +A X +A X +C X +A Y +A Y +A X +A X +A X +B Z +A X +A Z +A X +A X +A X +C Z +C Z +A X +B Y +C Z +A X +A X +A X +A X +A Y +B Y +A Z +A X +A X +A X +A Z +A X +C Z +C Z +C X +C Z +A X +B Y +C Y +A X +B Y +A X +A X +A X +A X +A X +C X +A X +A X +B X +A X +B Y +A X +B Y +A X +B Y +B Y +C X +A X +A X +A X +A Z +C X +A Y +C X +C X +B Y +A X +A X +C Z +A X +C X +B Y +A Y +A X +A X +B Y +A X +A X +C X +A Z +A X +A X +A X +B Y +B Y +B Z +A Z +A X +B Y +B Y +A X +A X +A X +B Z +C Z +A X +A Y +A X +A X +A X +A X +C X +A Y +A X +B Z +C Z +C Z +A X +C X +B Y +A X +A X +B Y +A X +B Y +B Y +A X +A X +A X +A X +A X +B Y +B Y +A X +B X +C X +A X +B Y +A X +A X +A X +B Y +B Y +A Z +C Z +B X +C X +A X +A X +B Y +A Y +A X +A X +A X +A Z +B Y +A X +A Y +A X +A X +A X +A Z +A X +B Y +A X +A X +C X +B Y +B Y +B Y +A X +A Y +B Y +B Y +A X +B Y +A Y +A Y +A X +A X +B Y +A X +A X +A X +A Y +B Y +A Z +A X +C Z +A X +A Y +A Z +A X +A Z +A X +A X +A X +A Z +C X +A X +A X +C Z +A X +A X +C X +C Z +B Y +B Y +C Z +C X +A X +C Z +A Z +B Y +B Y +C Z +C X +A X +C Z +A X +A X +A Y +A X +B Y +B Y +C Y +A X +C X +A X +C X +A X +A Y +A X +C X +C Z +C X +B Y +A X +A X +A Z +C Z +A X +B Y +A X +B X +C Z +C Z +B Z +B Y +A X +A X +A X +A X +C Z +C Z +A X +A X +A X +C X +A X +A X +A X +B Y +A Y +A X +C X +C Z +A X +C Z +B Y +A X +A X +A Y +A X +B Y +C X +A X +A Y +A Y +B X +A Y +C Z +B Y +A X +C Z +C X +B Y +B Y +B Y +A X +A X +A X +A X +A X +A X +A X +A Y +A X +B Z +A X +A X +A X +C Z +A X +A X +A X +A X +A X +A X +B Y +C X +B Y +A X +A X +A X +A X +C Z +A X +A X +C X +A X +A X +B Y +A X +B X +A X +A X +A X +A Y +B X +B Y +B Y +A X +C X +A X +A Y +B Z +A Y +A Z +B Y +B Y +A X +A Y +A X +B Y +A X +B Z +A X +A X +A X +A X +A X +B Y +B Y +A X +A X +B Y +A Y +A X +B Z +A X +A X +A X +A X +B Z +B Y +A X +C X +A X +A X +A X +B Y +C Z +C Z +B Y +B Y +A X +B Y +A Y +C X +A X +A X +A X +A Y +C Z +A X +A Z +B Y +B Y +B Y +A X +B Z +C Z +A X +A Y +C Z +A X +B Y +A X +B Y +A Z +A X +A X +A X +A Y +A X +A X +B Y +A X +C X +C Z +A X +A X +C Z +A X +C X +A X +A X +A X +C Z +A X +A X +B Y +A X +C X +B Y +A X +B Y +A X +A X +A X +A X +C Z +B Y +A X +A X +A X +A X +A X +A X +C X +A X +A X +B Y +A X +B Y +A X +A X +C X +A X +A X +A X +A X +C Z +B Y +C Z +C X +A Y +A X +A X +A X +C X +A Y +A X +A X +A X +A X +A X +C Z +A X +A X +A X +B Y +A Z +A X +A X +C Z +B X +A Z +A X +B Y +B Y +B Y +B Y +B Y +A X +B Y +A X +A X +A Z +B X +B Y +A X +C Y +A X +A X +A X +A X +B Y +C X +A Y +A X +A X +B Z +A X +B Y +A Z +A Y +A X +A X +C X +A Y +C X +A X +A Y +A X +B Y +C X +A X +C Z +A X +A X +A X +A X +A X +B X +C Y +B Y +A X +C X +C X +A X +C X +C Z +A X +A X +A X +B Y +C X +B Y +B Y +A X +A X +C X +A X +C Z +A X +A Y +A X +B Y +A X +A X +A X +A X +C Z +A X +B Y +B Y +A X +B Y +A X +A Z +A X +C Y +B Y +A X +A X +C X +B Y +B Y +A Y +A X +C Y +B Y +A Y +A X +A Z +C Y +A X +A X +A Y +C X +C Y +A X +B Y +A X +A X +C Z +A Z +C Z +A Y +A X +A X +C X +C Z +A Z +B Y +B Y +B Y +A X +A Z +C X +A X +A X +B Y +A X +A X +C Z +A Y +A Y +C Z +A X +A X +C Y +B Z +A Y +A Z +A X +C X +A X +A X +A X +A X +B Y +B Y +C Z +A X +C X +B Y +A X +A X +A X +A X +A X +A X +A X +A X +C Z +A Y +C X +C Z +A X +A X +A Y +A X +A X +C X +C X +B Y +A X +B Y +B Y +A Z +A X +A Y +A Y +A X +A X +A X +B Y +B X +A X +B Y +B Y +A X +A Y +A Y +A X +C Z +A X +A X +A Z +C Z +B Z +A X +A X +A X +A Y +C X +A X +B Y +A X +B Z +A Y +A X +B Y +A X +C X +A X +B Y +A X +C X +C X +C Z +A X +A X +C Y +A X +B Y +A X +B X +A X +B X +A X +A Y +A X +C X +C X +A X +A X +A Y +A X +A X +C X +A X +B Y +A X +A X +C Y +A X +A X +A X +C X +A X +B Z +A X +A Z +A X +A X +A Z +A X +A X +A X +A Y +B Y +A X +A X +A X +B Z +B Y +A Z +B X +B Y +A X +C X +B Y +A X +A X +B Y +A X +C X +A Z +A X +A Z +A Z +B Y +A X +C X +C Z +A X +B Y +A X +B Y +C Z +A X +C Z +B Y +C X +C X +C Z +B Y +A X +B Y +C X +C X +A X +B Y +A X +A X +A Y +C Z +B Y +A X +A Z +A Y +A X +A Y +C X +A X +A X +A X +C X +A X +A X +A X +B Y +C Y +B Y +A X +B Y +B Y +A X +A X +A X +A X +A X +C Z +B Y +B X +B Y +A X +A Z +A X +A X +B Y +B Y +C X +C Z +A X +C Z +B Y +A Z +A X +A X +A X +A X +B Z +B Y +A X +A X +A X +A X +A X +B Y +B X +B Y +C X +B Y +C X +B Y +A X +A X +B Y +A X +C Z +B Y +C X +A Z +B Y +B Y +A X +B Y +A X +A Y +B Y +B Y +B Z +C Z +A X +C X +A Y +B X +A X +A X +A X +C Z +B Y +B Y +A Y +B Y +A X +B Y +A X +C X +A X +A X +A X +A Y +A Y +A Z +A X +B Y +A X +A X +A X +A X +A X +A X +A Z +A X +A X +B Y +C Z +C X +C Z +B Y +A X +A Z +A Z +A Y +B X +A X +A X +C Y +A Z +A X +A X +B Y +A X +B X +A Z +A X +A X +A X +A X +A Y +A X +A Z +A X +B Y +B Z +C Z +A Y +B Y +A Y +C X +B Y +B Y +A Z +A X +A X +A Y +A X +A X +A X +A X +C Z +B X +A X +B Y +C X +A X +A X +C X +B Y +C Z +C Z +B Y +C X +A X +C Z +B Y +A X +C Z +A Y +B Y +A X +A Z +A Z +B Z +A X +A Z +A X +C Z +C X +A X +C X +A Y +C X +A X +A X +A Z +B Z +B Y +B Y +A X +A X +A X +A Z +A X +B Y +C Z +A X +A X +A Z +A X +B Y +B Y +C X +A X +A X +A X +C Z +C X +B Y +A X +A X +B Y +C Z +B Y +A Y +A X +C X +A Z +A X +A X +A X +C X +A X +A X +A X +A X +C Z +B Y +A X +A X +C Z +C X +B Y +B Y +C X +B Y +A X +A X +A X +C X +A X +A X +A Z +A X +A X +B Z +A X +C X +B Y +A Z +B Y +A X +A X +B Z +A X +A X +A X +B Y +A X +A X +A X +A X +B Y +A Y +A X +B X +A X +A X +A X +A X +C Z +B Y +A X +C Z +C Z +B Y +C Z +A X +A Y +B Y +B Y +A X +A X +A X +A X +A X +A X +B Y +A Y +B Y +A X +B Y +B Y +B Z +A Y +B Y +C Z +A X +A X +B Y +A X +A X +A X +A Y +A X +A X +B Y +A Y +A X +A X +A X +B Y +A X +C X +A X +C X +B Y +C X +A X +B Y +A Z +A X +A X +B Y +A X +A X +A X +B X +A X +A X +A X +B Y +A Z +B Y +B Y +C X +C X +B Y +A Y +A X +B Y +A X +B Z +A X +A X +B Y +A Y +A X +A Y +A X +C Z +A X +C Z +B Y +A Y +B Y +A X +A Z +A X +B Y +B X +B Y +A X +A Y +A X +A X +A X +A X +C X +A X +B Y +C X +A Y +B Y +B Y +A X +A X +C Z +A X +C X +B Y +A X +A X +B Y +A Y +A X +A Z +A X +C X +B Y +B Y +C X +A X +B Y +A X +B Y +C X +A X +B Y +A X +A Z +A X +C X +A Z +A X +A X +A Y +A X +A X +A X +A Y +A X +A X +A X +A X +A X +B Y +C X +C Z +C X +A X +B Y +C Z +B X +A X +A X +B Y +A X +A X +C Z +C X +C X +A X +A Y +B Y +A Y +C X +B Y +A X +A X +A Y +A X +A X +B X +C X +A Y +B Y +B Y +A X +B Y +A X +A Y +A X +A X +B Y +B Y +A X +B Y +A X +C X +C X +C Z +A X +A X +A X +B Y +C X +A X +A X +B Y +A X +C X +A Y +A X +A X +A X +C X +A X +A Z +A X +A X +A X +A Y +C Z +A Y +A X +B Z +A X +A X +B Y +C Z +A X +B Y +B Y +A X +B Y +A Y +A X +B Y +B Y +A X +C Z +B Y +A X +B Z +C Z +B Y +A X +C Z +A X +A X +A Z +A X +A X +A X +A X +A X +A X +C Z +A X +A X +B X +A X +A X +A X +A Z +A X +C X +A X +C Y +A X +B X +C X +A X +B Y +B Y +A X +C X +A X +A X +A X +A Y +A X +B Y +C Z +B Y +A Z +A X +A X +A Z +C Z +C X +C X +B Y +C X +A X +A X +A X +A X +B Y +A X +A X +A Y +C X +A X +C X +A X +A X +A X +C X +C X +A X +A X +B Y +A X +A X +A X +A Y +B Y +A X +A X +C X +A X +B Y +C X +C Y +C X +B Y +B Z +A X +A X +A Z +C X +A X +A X +A X +A X +A X +B Z +A Z +A X +A X +A X +A X +A Y +A X +C X +A Z +A X +A Z +C X +A X +A X +A X +A Z +A Y +A X +C Z +A X +A X +B Y +A X +A X +A X +A Y +B Y +A X +B Y +B Y +C Z +B Y +A X +A X +A X +A X +A X +A X +A Y +A X +A X +B Y +A Y +A X +A X +C X +A X +B Y +A X +B Y +A X +A X +C X +A Y +A X +C X +B Y +C X +A X +A X +A X +C X +A X +A X +A X +C Z +A X +A X +B Y +A X +A X +A X +A X +C Z +A X +C Z +B Y +C X +A X +A Y +A X +A Z +A X +C X +C Z +A X +C X +A X +A X +A X +A X +C Z +B Y +A X +C X +B Y +C X +C Z +C Z +C X +C Z +C Z +A Y +A Z +C Z +A X +A Y +A Y +A X +A X +B Y +A X +B Y +A X +A Y +C X +A X +A X +A X +C Z +C Z +B Y +A X +B Y +C X +A X +A X +A X +A Y +B Y +A X +C X +C Y +C X +A X +A X +C Z +B Y +A X +B Y +A X +A X +C Z +B Y +A X +A Z +C Y +A Z +A X +C X +A Y +A X +C Z +C X +A X +A X +A X +A X +A X +A X +A X +A Y +A X +A X +A X +C X +C X +B Y +B Y +A X +B Y +A X +C X +C Z +C X +B Y +C X +B Y +B Y +A X +B X +C Z +A X +A X +B Y +A X +B Y +A X +B Y +A X +A X +A X +A X +A X +A X +A X +A X +A X +C Z +A X +A X +A X +A X +B Y +A X +B Y +B Y +C Y +B Y +A X +B Y +B Y +C X +C Z +C X +C Z +A X +C X +A X +A X +A Y +A X +B Y +A X +B Y +B Y +B Y +A X +A X +A X +A X +A X +B Y +A X +C X +B Y +C X +A X +A X +C X +B Y +C Z +C X +B Y +A X +A X +B Y +A X +A X +A Y +C Z +A X +B Y +B Y +A X +B Y +C Z +A Z +A Y +A X +B Y +A Y +B Y +B Y +C Z +A Y +A X +A Y +B Y +A X +A X +C Z +A X +B Y +A X +B Y +B Y +A X +A X +A X +B Y +B Y +A X +A X +C X +B Z +A X +B X +B Y +C Z +B Y +C Z +C Z +A X +A Z +A X +A X +A X +A X +A X +B Z +B Y +C X +A X +A X +B Y +C X +C Z +B Y +C X +B Y +A X +A X +C Z +A X +A Y +B Y +A X +A X +A X +A X +A X +A X +A X +B Y +A Y +B Y +B Y +A X +B Y +A Z +B Y +A X +A X +A X +C Z +C X +C X +B Y +A X +C Z +C X +A X +A X +C Z +A X +A X +A Z +C Z +B Y +C X +A X +A X +B Y +A Y +A X +A Z +C Z +A X +C Y +A X +B Y +A X +B Z +A X +A X +A X +A Y +C X +A X +A Z +B Y +A X +A X +B Y +C X +C Z +A Y +C Z +A Z +B Y +A X +A X +C Z +A Z +C X +A X +A Y +A X +A X +A Y +A X +A X +A Z +A X +A X +A Y +C X +A X +A X +A Y +B Y +A X +B Y +B Y +A X +C X +A X +A X +C X +A Y +A X +A X +B Y +A X +C X +C Z +B Y +C X +A Y +A Y +A X +A X +A X +B Y +B Z +A X +A X +B Y +B Y +B Y +C Z +B Y +B Y +A X +B Z +A X +A X +A X +A X +B Y +A X +C X +B Y +B Y +A X +A X +B Y +B Y +B X +A X +A X +A X +A X +C Z +A X +A X +B Y +A X +A X +B Y +C X +B Y +A X +A X +B Y +A X +A X +A X +C Z +B Y +B Y +A Y +B X +A X +B Y +C Z +A X +A X +C Z +A X +A X +A Y +C X +A X +C X +A Y +A Y +A X +A Z +A X +C X +C Z +C X +B Y +A X +C Z +A Z +B X +B Y +C Z +C X +C X +B Y +A Y +B Y +A X +A X +A Z +B Y +A X +A X +A Y +A X +A X +B Y +B Z +B Y +A X +A X +A Y +A X +A X +A Y +B Y +C Z +C Z +C Z +B Y +A X +A X +B Y +C X +A X +A X +A Y +A X +B Y +B X +A X +C Z +A X +A X +A X +A Y +A X +C X +A X +A X +C Z +A X +A X +A X +A X +A Z +B Y +A X +A X +C X +C X +C X +B Y +A X +A X +A X +B Y +B Y +A X +C X +C Y +A X +A X +A X +B Y +B Y +A X +A X +A Z +A X +A Y +A X +B Y +A Z +B Y +C X +A Z +C X +B Y +A X +A X +B Y +A X +C Z +B Y +B Y +A X +B X +A X +B Y +B Y +A X +A X +A X +A X +A Y +B Y +A Y +B Y +B Y +C X +A Z +A X +A X +A X +A X +C Z +A X +A X +C X +C X +A Z +A X +A Z +C X +C Z +B Y +B Y +A Z +B Y +B Y +B Y +A X +C X +C X +A Y +B Y +A X +A X +A X +B Y +C Z +C X +A Z +A X +C Z +A X +A X +C X +A X +B Y +A X +A Z +B Y +A X +A X +A X +C X +A X +A X +A X +A X +A X +A X +B Y +B Y +B Y +B X +A X +A Z +C X +A X +B Y +A X +A X +C Z +C X +B Y +A X +A X +A X +C X +A X +A X +B Y +A X +C Y +A Y +A Z +B Y +A Y +B Y +B Y +A X +A X +A X +A X +A X +A X +A Y +A X +C X +C X +C X +C Z +A Z +A X +B Z +B Y +B Y +A Z +A X +A X +C Z +B Y +B Y +C X +A X +B Y +B Y +A X +C X +C Z +B Y +B Y +B Y +A X +B Y +B Y +A X +A X +A X +A X +B Y +B Y +B Y +A X +A X +A X +B Y +B Y +A X +A X +C X +A Y +B Z +C X +A X +A Y +A X +A X +C Z +A X +C X +B Y +A X +C Z +C Y +A X +C Z +A Z +C Z +C X +B Y +B Y +A X +B Z +A X +A X +B X +A X +A X +A X +A X +C Z +C X +A X +B Y +A X +C X +A X +B Y +C Z +A X +C X +A Y +A X +A X +A X +A X +A X +B Y +B Y +A X +A X +B Y +B Y +C Z +C X +A X +A X +B Z +A X +A X +A Z +A X +A X +A X +A X +C X +A X +A X +A X +B Z +C Z +B Y +B Y +C Z +C X +A X +A X +B Y +A X +A X +B Y +A X +A Y +C X +B Y +A X +C X +A X +B Y +C X +B Y +A X +C X +A X +A X +C X +A X +C X +A X +C X +A X +A X +B Y +A X +A X +A X +A X +A X +A X +A X +A Y +A X +A X +C X +B Y +C Z +A X +B Y +A X +B Y +C Z +C Z +B Y +A X +A X +A X +A X +A Y +A X +A Z +A X +C Y +C X +C Z +A X +A X +A X +A X +A X +C Z +C X +A X +A X +B Z +A X +C X +A Z +B Y +C Z +A X +A X +A Z +B Y +A X +B Z +A X +A X +A Y +A X +A X +C Z +A X +B Y +B X +A X +C X +A X +C X +B Y +A X +A X +B Z +A X +A X +B Y +B Y +A Z +C X +A X +A X +A Z +A X +A Z +A X +A X +A X +B Y +A X +C X +C X +A Z +B Y +B Y +A X +A X +A X +A X +A X +A X +C X +A X +A Y +C X +A X +A X +A X +C X +A X +A X +A X +A X +A X +B Z +A X +A X +C Y +B Y +C X +A X +A X +A X +A X +A X +C X +A Y +B Y +A X +A X +A X +A Y +A X +C X +A Z +A X +C Z +C X +A X +A X +A X +A X +C X +C X +B Y +A Z +A Y +B Y +C X +C Z +B Y +B Y +A X +C X +A X +A Y +B Y +A X +C X +C X +B Y +A X +B Y +A Y +A X +B X +A X +A X +B Y +A X +B X +B Y +A X +C Z +A X +A Z +A X +A X +C X +A Y +A X +C X +A X +A X +A X \ No newline at end of file diff --git a/adventOfCode/2022/3.go b/adventOfCode/2022/3.go new file mode 100644 index 0000000..45797a3 --- /dev/null +++ b/adventOfCode/2022/3.go @@ -0,0 +1,106 @@ +// Day 3 +package main + +import ( + //"fmt" + "errors" + mapset "github.com/deckarep/golang-set/v2" +) + +func solve3(input []interface{}) (interface{}, interface{}) { + + var day3Inputs []string + + // Customize input + for _, val := range input { + compartments, ok := val.(string) + if !ok { panic(errors.New("typeCast")) } + day3Inputs = append(day3Inputs, compartments) + } + + // score + scores := map[string]int{} + currScore := 1 + for i:=97;i<=122;i++ { + scores[string(rune(i))] = currScore + currScore++ + } + for i:=65;i<=90;i++ { + scores[string(rune(i))] = currScore + currScore++ + } + //fmt.Println(scores) + + // Solution 1 + sol1 := 0 + duplicateItems := []string{} //mapset.NewSet[string]() + allCompItems := []mapset.Set[string]{} + + for _, compartments := range day3Inputs { + visited := mapset.NewSet[string]() + n := int(float64(len(compartments))/float64(2)) + for len(compartments) > 0 { + items := mapset.NewSet[string]() + currCompartment := compartments[:n] + //fmt.Println(compartments[:n], compartments[n:]) + if len(currCompartment) > 0 { + compartments = compartments[n:] + } + for _, c := range currCompartment { + char := string(c) + items.Add(char) + for _, iterItem := range allCompItems { + if !visited.Contains(char) && iterItem.Contains(char) { + visited.Add(char) + duplicateItems = append(duplicateItems, char) + } + } + } + //fmt.Println(duplicateItems) + allCompItems = append(allCompItems, items) + } + allCompItems = []mapset.Set[string]{} + } + for _, dup := range duplicateItems { + sol1 += scores[dup] + } + + // Solution 2 + sol2 := 0 + duplicateItems = []string{} //mapset.NewSet[string]() + allCompItems = []mapset.Set[string]{} + + for i:=0;i<=len(day3Inputs)-3;i=i+3 { + //fmt.Println(i, i+1, i+2) + compartments := []string{day3Inputs[i], day3Inputs[i+1], day3Inputs[i+2]} + visited := mapset.NewSet[string]() + for len(compartments) > 0 { + items := mapset.NewSet[string]() + currCompartment := compartments[0] + if len(currCompartment) > 0 { + compartments = compartments[1:] + } + for _, c := range currCompartment { + char := string(c) + items.Add(char) + matched := 1 + for _, iterItem := range allCompItems { + if iterItem.Contains(char) { + matched++ + } + } + if !visited.Contains(char) && matched == 3 { + visited.Add(char) + duplicateItems = append(duplicateItems, char) + } + } + allCompItems = append(allCompItems, items) + } + allCompItems = []mapset.Set[string]{} + //fmt.Println(duplicateItems, i) + } + for _, dup := range duplicateItems { + sol2 += scores[dup] + } + return sol1, sol2 +} \ No newline at end of file diff --git a/adventOfCode/2022/3/3-sample.input b/adventOfCode/2022/3/3-sample.input new file mode 100644 index 0000000..9919ffa --- /dev/null +++ b/adventOfCode/2022/3/3-sample.input @@ -0,0 +1,6 @@ +vJrwpWtwJgWrhcsFMMfFFhFp +jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL +PmmdzqPrVvPwwTWBwg +wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn +ttgJtRGJQctTZtZT +CrZsJsPPZsGzwwsLwLmpwMDw \ No newline at end of file diff --git a/adventOfCode/2022/3/3.input b/adventOfCode/2022/3/3.input new file mode 100644 index 0000000..dd22ec4 --- /dev/null +++ b/adventOfCode/2022/3/3.input @@ -0,0 +1,300 @@ +zBBtHnnHtwwHplmlRlzPLCpp +vvhJccJFGFcNsdNNJbhJsJQplQMRLQMlfdfTPCLfQQCT +GPhjcjhZDjWtnSVH +BNhHVhrGNVTbDHdDJdJRPJdSQQSJwPjR +lvtsfbsqzwSnJcvjSm +MftttFLftZMLgtgMbltMqZzbDNrTpVGhNWrDTrpTGNpZGZhD +VSSHcTgTtTdtllZlzmmbljTn +RqMqsFfQLLFLQFMMfRLPZLvPpCfWrbpmCbjCnfjlWmnrmmnm +hqRDqPDRsqNHwtHSNBZtJd +tNFDpDFrtdjfmjjjFmFFdScpZhZScTJgpHccHhMJgS +lLzSlSCQqbsVhBghggBZgCcJ +zRLVVLQnvQqVVzRldfWrwffjjdwSdfjv +bpWqqqWvHBpwGBCCRl +hJdjdJFQqdBBDMMC +tFFzJZFtJSqtZJQsWLbNSTnffHfvTH +lFhRZhFjPlqMlJqZJlJcRLwrLrwStRwtsVVtVSrgRV +WcpDvDfBmpDHzWBDbpbmWmNVSSTzLTtrVswgttVVzwwr +pbWfmGBpHfDmWnvvGbmWnjjMqPJMlMFPdGcjqPqPhP +NjFNRlpVLFCSSlbBWWfw +pssPZQQsMnzmtnQPttzDBbBJBcrrJWbrZSBJSbfC +QTHPHspMNGHdhvRR +QfPdSJfFJmthSthtwbsNLbPLlLTLpbvP +nHnMBnZqqgBMnWrZMqnZVcbCqRwNsvblRwppbllTsRNp +nZHBHznMnWgcrnVBtjFdfmzQNtNddjNF +hFhfPghppPhpRNhzsjsvHVzjpsGnWz +tTjlCCwMqtdMjMctGJWHwWnVwWnwvWGs +rZdrjBBtqdCtlcdgFZQLfhRLFSgRNP +RDHSWrJWffJFlJCgCMCDjCvzjPMP +QtGTndBwBtNzBVjBCMgB +LdwwMpTdwsRHsqSHqHJl +RfsfzvLLFvFzCSvSbDsTpTGMPMZPPTMt +jqWBjwBBNwWqwPGZbTwVwVtD +BnhgglhhNNngqjBjHNWrZLlFLSCJSFFCCQzQvQFCFF +HLvLDQbvnDQDvbHTLhntSnGBSlfGldddcmfMMf +NgFjZjrZZJrlfJfSVcBJGc +scWCNFZpsjzrDLwLhbQzhQwD +SlqJlThDPqpwSTwhcbDdbWDbZGcZNcDb +MsnWWjHjvLvfscjjgdzNdbgbcc +vQQvWVQFLLHfHVBWfsfmFFpJRhhSplqlRJqpBwlqTCPC +DZbDzzZDjQbPGZFFSSgSlFCzTgzm +qLnvwvhddrqMrwrCTLLFJjmtSlFlSH +VdhvsWqdVWvvRhsvqbpbPcZfPpjZGBQNRj +mJNtNFmzDZtzdzrLtwwRqJSchgfGcRfwRB +pWpjQjCTQnHMWCCpjQpHvTqcwTwScfRcBcSGBRThwS +MQHjvjVCCqsvljWnVQzLtNPZzmzLVNLddtPN +QVRPRVDgsRjLssnL +TTGDJDJfbfLHSnsMWWbs +qGqqTFFDqgQgQQQq +nlMnRRjbMjCdJVQJCZ +nGqfLwfNLFNLnPPGFVVCdVGZJtCtCCVzJz +LHHfPNHnPqqLwqPqDPWfNFvMglbhhbMgmclgcllDmgmrcl +cLLWWSThtdLpRcddcgPRZFDMCVPPMCCPCPCZ +NfGbGNzrBNffGNJjbPPZsZmZZPmDHpMH +zlJBfzlQzNjNjfJcpwSdvWhcvLwQWt +cVVQfVCJVrVcTJnfNvlDFmDrmlvrFWlL +snZHpMhZtMbtPNvzHWWvNFNvNW +gppnbbbRgMnZbswRqRwbqTcCCSTCJJdGjgfVGTdcCG +jplgNdrHrrNZgdHmlHNJHddlDSPPSTlzTSlTSDSzCQLfzf +vscvWWWvGWGGscbFMpRWFwQTPzfLQwQwPfLbzSzzDL +GvGBWpqcMVRNNZHgdHdtBJ +LchbZhjjZFjwSmPRqRffqbdtggdR +vWHMWlHJdGqtRqHV +MvzCJlnMnlTNnNNLLdhjjCdjjhDjjL +FNCllHFvCGvwQcPQJfgfmwgh +zjtRpbDLjtsrzbLLQmfBTgTBQQfhbfQB +WLgqRzqsrWvFGFZFZC +qjLlNcLjcNWpQLlQMmvmhCvCgsMZZghj +tGSDJtRGJzHMMGDVZCfvmfhzmZZgZsmv +BSSRDRHBGHtSSSbGJSwHbNcLQddqMNlrqcMQMldBWc +JSfctrtctDpszHvzVQHr +glCWjhWmFjlmlhmdWPhVVznvcHjszbvvpHvznv +FgBmFhCBCGFqglgmhCFmSTSRLJLLZfSRJcDSGMtM +vZGlFFtLMLdShSSShRVtVf +rQNvmznWPNCPNsrCsbWbsPCvjShhhfHBBHJjSJRhjSRnHhSj +mCNsQCmqszNcQzrzrrzWvGgGMgpdFpMLlFZGwcLDdg +QJRJQDlcqLlWbNGL +HCnwwsCrnstLWqtWNgZNgg +rsnTrTCHTnnVwnsVPqqDQcRjcczMPvPRzM +qCzjqnzVdzrdhnhddDbDBMPttcGBDBDPnc +sZgRQWHgWHHLsgsRRZsJbpJlDcDGNcTDFtGNFFcJNFPBPBTc +WggbRQSRRgRSsWWmbHqvVffVwhzvCdmfhmdV +lhqWcNpQGcNmmHmNPWCsQzQsgrQrBMCMbMVM +wDLFFDJvSFFZRDZSzCrzTzsRgVWbCrMW +dFwDtZfdjFZWFFfmHGPnPPmqfmPNcN +lcMRNJRGGLJnNVFbVrwrwZrD +tjCzQjQhQwgWFShVFS +ffHQsQssQTzBsPnLpMPRwsJP +MQSMSBSRFMQLJChLChjTBh +WmVlPrwnpwDlflNpDrNnDlDwThJCCdLJhhdhCfJTccGjvscd +gnDVnNnwgglwDwptSZFzgQHqbjZgZZ +nwBcFgwTDcNrpZMD +WQWCLZmvhMRvNjsNSD +CGGWmZGHHhtVzHbTqgTdbgzz +RmcTCwvssRbsThTcVRJJfSPqfJwJFqfjfMFq +zQNZDWtQlDZGBQPfFQqjJLjL +rrglggZGWnrnrrHlDhsbsPTVCsCVsTRpHv +wFGfzSvCPGttSzqwmtqmvvPRDDRCWgWWDTBTMcBcBWbCRM +hVJJHQHnpWnDTNnnDb +LJsVVdhQqvmdbbSf +srlJztzsVVsSsVtRlNllTWzzmqGhqWLPCDCgmChPLDdqCmCP +bZQMZpbvMBMgmDGmZLSPZd +MpScMSMpvfjMBcBcfMfSBnzlTjssNszrNrtlTVzlzFVN +rCtgrgClprGGClnJCZmwtMjZRjbjjcjZQv +PWVfBHWPdbNfbbRmRj +sPsVqFPsHWLhBVVqHFqPVddWSDLJgpTCnnrRRLGpJSSTRrgT +zjqpGjrQjGqSHCVvCrRZDN +cTdshMhdmcMNmddRHBhvCCBCCvHZDC +JTmTmJnLTdwzNQpPWJWgpP +BmpZmrzZnznHbpprSbQSQbqdSVqbPQcV +fRGTGJZRTTDwJTJRGDfgJgNFlSSFcldfdccFVlPlFFQPSQ +GvTTTZZLmsntzmCL +VhMcrmbhvzMSnhvftbRbllLtglBBtf +HqqqJqDqPjJPNjjDVFDZCdqBtRtGBGlGRfQQgttQfHlTQl +pCZJPqqZpmhvhpVh +dWLBJHJhGJGMBJRcDLDSQsSQpvcR +ZlnnPqglblfRRpSvSsnz +sPTgZVjjmwVTljrwTTlbwVGdJhBNNdFdMGNHHJMjBNFN +FhFrfbfgbLRdfqfrmvDgLdjrcQtSNStHHHQlSjJJPllt +CnspzZWTpCnMVzzZZGZRCzttHNjNlQlSNtNlNjVcjlQS +GCZsZBRwnvwfbqwFwb +bZnJFJgLFRnqQZqJQJFQGpCLNcGlLllClNtccjGc +rVfvwPDhPHGtlcbClr +mBhshsfMvBvqsQJdTbgnqQ +jgWHqMSWMGqWjWjqbWGJQDfVqLfrfDfJhVLfTr +pPplwsRZPFZFtLhfwgfwrhJL +zlRsdgFcRgmjdBCMHdjHWB +qJSGJSPQWzcprtQZtt +mBMVfsNBnZzcNtcc +LMLBsmMlvBgFsghVVvfgLBvbJJSqgGHqPGPtCWwbJHqCPG +ZvZLcdMGVMlHDvDpvqhH +NNSrQNbJbrTnnWZDDZqqhqpW +wbgNJrsrCwwJQZbsrJBFzjCCdzGdjcGzMdzj +JbVmdVLJJJdQMnzmmMgHjPqqjNgvqwngHNNP +ZfffDZZsRpcpRDcCRrlpplcWSSgwgSwjvvsjPSwhNSWggh +cCtfppZrpjtMMmdQQTLz +TtbnmbdmTmgTlPNhqvqj +wrwrLsVZRsJJJsfHjvPPWfhjHqRN +sDZwDvsCCQLJZQJQsMCMzZBtSMpndcSFnnSBFtSBmdBc +mWFTZdmQdZFrFQbCRsrspjSjnvCLRS +GwlDqcNHDzwGfHSRqCgJsSpnvpSL +NGlcNwHLLGfDDHDhDwDcwVczbPddZtMFWttWWtdPPdQdhPWd +mnfcZgcdZqnqdfFqPmHfhqsbgVMCJNMtvCJtMvtblTJtvb +rRLDDjPSjjPDGBQSBNbtLVtbMNNJlTMtbl +SzjDDzRRpGQDDDPHzdsmnnhsqcqdFq +ZDGNRDGjSdwnnmnsVNsHJJ +tMBWWrddLPLhvWTTPLccvmmbVpgsJHmccppJ +ClPrtBWWrhrFLBPlCRzjzGqdRzjRdRGZjF +csTRNQNJcNBDLfhfMf +qGmWpGHqrqPLChPRhVFPDD +tgHrtnrrJnZRTZcv +FLqrfmLDrqCmqjTqcbGqRTGVvb +FMtWMSWzzFStJzPzhWzhQvTvHVjjTjHTTHvbHc +PgtWWstWtSpZWPzWwnrBsdBDdFLfllLlfC +mThbMDMQDCDbwLqWpqPpdhwR +zgrcffgHNZltZSgHLsRsLLWRWgLqppsW +SVlSrfSHlSSVlrJfVctlNDMCmMFbnbRDbDBFJFbBRM +PrBrWqtRPdBLLrBwqpswgpwhgpnZhhzsgw +FTFRSVJQVJflFfQQgggGMZngGQZszZ +TbmfFJFSDFblSTDSFFbmVSDrPLLWtcmBqqRmBtmcLtcrjP +DjPsMwDjLVVTsvNNRTNTRT +ztdQQHqHlFNtfRNNNMgg +FzhMhHQlDcCrhCCc +zSHGzzmHgnnMDLTNTG +lPVBtvhQjpNSMWTLBD +VCftbjvbVCfPbZwsJsrSgSSZwC +CbwgmvMnmnCwMmwRQqJBGBgHZHpJHdtdZpJt +zVSlNSDlrzNhqlNTScDzVWfBBZZZZGBstGsdsWFpdHdJsW +NDlLzhrVcqRPCMRwLLLw +TjTHHLwnLjVlTwLjgVfvsFvDsdWfvDvFMd +qbRRRpmpcmDcczppztSqSvWFssFGfWdMvfQWdfsG +RZpqDBmtrzhzphjTgjHlnwjgJhgJ +dLmMgdgzwDLzDWFhBWvzFzzBZJ +tTVcppbSTfstTMMHfTbhBchhJFCWcjWBZhjGGB +SSSSNbsNRpRRsRrfVHfRpNtlPgQDLPdMmlDLlrPnqPdPLl +qqbTCSqdqqFZdRLZhwhZ +HWWlHtlrBfGtVssnsLnHfJVPPMMFzhPRwMPwFhzPZzPMGM +nfmtsrlsnrfVnHJrVBWlsVfgbbNTNSvmvvpcTjLjLbqvvS +GGhFvGPFcThqffPdnfNLqZZCSwtQSwZpwQQBsL +RglMRrJJgHBCBZSQQpdr +WmbRHHbzDgJMDzRDMdWmWHzHNFFvvGGhnvVvvfcvnFfcbvnT +QsfQmsLfZZZcshnJ +dSgdWgSVVFvzSpqFdqTgWRHbJNcbZNCTJCNNZRRCCh +FcpVjgDvVVFdVWFvzjwwQtBMLtBBGDwftPrB +rqsRrHsvsPqswNcJcNJrnnBrNn +bFjgGFdbVRNNnpRQpV +GSthhggGDSvMRqtHvMfM +ZwVPgMsgVsGzVsRZpgpzzgpFMrNbbLFrDLFFrrSDLfrNBN +qvnjBhQhntbfDLrF +CJlHHcHcTWqvpBdsWRpdPdgs +BjmTDjJBCBWrgQRPFlWWlW +dHphshtdtVHVhpJqspdvRrqFPgrLPPFPrrRPvQ +sdMsMtStVszpwMzHjJGjCcZjmScNfCDf +DmGdDffgDSDDdJstqdJldlRt +MhnvMCZCbbZHMvsCHtrcVrPjJcRqVtlt +LsQbsFZvZhQzZwhQWTNgBWpNwSGpTmfS +RRJQnCzbZZLTZJCBtWvFtsfqBqtfWb +prjlChGNldGNdlSVMhWfqWtfsvwvqsFtdtsq +GGjNDNhpMGMGVhrnZZTzcTHCCJcDHc +RmbMmjgpPjMBsBMfchhVsc +HwFWFTztSrtFpcQvBsSqVscBBC +zWwnJFHtWWHDgbGgdpGpnl +mnbWbRRLRFnmmWcCDTBVwCDBlwNW +ggJPtpdHGfdZtMHgtZgVPPBCVsPNBcsBTTDDCC +hpvJJTpGhdhtJdMHqvmmnLvSbmnFnRFm +WWtrWrNgVbRjMrQCNzqJFwQJFNTJ +LdHPhcdchQQssLzJrz +pBccnHpnrrcGHnnSlWjnRMSlbt +NMMfNFnZgMVThhTMcgTDJDJjsVvvJJqJmHsqHG +LQpwwprCQzBNBdGjGjHswswdvm +CBCzzCrbWbSlNQnTRgPPfFRWnfgc +RFwHVQRwFgTQSFVhdsdHsBdDBnnqnq +LGftLtPGGMzlNrhlPqPsrJ +fvGpWpMtccpTwwpRRQhh +TTJCGdTGtZRQQCnzcnCv +FWWHPSFNFbDbDDqSWnVmLRRjRRQLhcmLjS +qPwPWwFppbwggGZGfdJZgdnGdd +zSTWzrzWTLWpCtCGpqqGgplc +nZWwsJVZZBnJHJCclHllgtChgCgc +DFnVBJsFssVVFBFnBdfvjDSmTMWzrmMfRmTv +MJmgMssrsggqqMVstbwTcTbPbTTwThmw +NRBBGRjHVRRcRbCp +QnSfzLWzNHzNVQQVjrglJMsMFvgJdFWrgZ +ggLLGnhgnPvJHZnN +VBtmVSldbSBVlcNPHvjmNcwNZZ +tdWqSVSSBztVWGrThLhfrfvG +TDqrjdSwLqDppdTCdzPBFmmjQmhHFPFQhPFR +zlGbMcVcVtsPHFRhWRRsPF +btgvlVVcDZZZqgrz +DgwlgbbFDDjjPTHDrmddPhPV +WqtMBBtQsttMNWQBqsbJpGGzdPdTHLVmTzJhmTPhHHPTmH +qQsqGZNQtZGMNsNtZpFnjnCRbZffwwSRljFf +gMdFLCdnMZCTFFCqnTgWLCHfSgPgPHStcQQmfSBBSfHg +vrwwrwzbGjjswjvhGGsjPQmqRmHPbBtcBQtqfmcH +qzJllVsGVGljjsrzwDzhwzDGTddNLFnZWNdpCVWTNTZTLZCF +LtwMhDtctwbwwppdWBJQJBWPvPfDfqvG +FTzrNrgSRFrgzFRHNVFQJvlqHjBvQWlQWqPBfq +sFgNzmVmNzgTvVTMwhMhstMwZtsbsc +MrBDQVzzlrvhQzQrDMVQrzrzgRJnRRwwRbwSwwVRRNSgwwwJ +qFTPTvfTHcqqncpcwR +LmtdGGPmTPGCTLHLWsZMhvZMMMzrzzdlMQ +ZVNpjfpZNpfNgNjzNVfWtnbbWmBHtsZWBSZBGS +MrDrQvvDrPLDMvFvdmBGGsBBCtsHrnrGCm +ltRMwLLDDRlvQwvlQcwhqfcJNpgzjJpjhJ +sRRRlRbcFbBBdnFBwCGppNvGrTCDDGVNlr +PPSLQzHjzZZPLZPjgTNTgpCbVJvGrNCTGr +ZLHHPQjhQmWWSRRnssdtbnmfwF +GRwrMrHJGwJPGWsgfqQgsc +VbTvLQCZLSWWsgWf +TVDvVCvppvTDmzZVTbZpTzBBNQQQJlJBBJBNNJmRBwRH +shJRWJsjZGNjSTrjFS +dMLCddggldQzMCCVgzVVLmLvTwNFFSqpNSqSbFGSqTTpMTFN +VGQvVglCLcVzgdddCDVvlsPZRRBDJPHZWZZnBsWJRR +CrwlwhRCMrswnsHBFccHHWFc +QJTmtfQgLtzQfLQfdPcWSFHHDDSpcFpFBg +jTQTqbfQfmLbLQJbJrRCWjljZGjNrZlZlC +JmthDmLShtJmHphphJQCwjdjdFDzFgzFdgdNlC +sbMTVBrWMbNvVMnsWMnVzjsjwCfjFgfZzfdgdzlj +NvqbbBcMMPPSqLSpGGthmp +RfGWFHlPFFNWGFZRZBjvwCvzBwhhrvvjzmrr +sLJSLMSTSJTbStJtMSqSqbpMrvmrzWdvhmjDCzzwrrpjdDDv +SbQqsqsWcZPcQGFG +BjqbMqMVBsfqGqFqGLmF +ZZQbQPddPcwbPnRQltdtQZdnmFNrvfhGrhrWWFNWWtmNFNNW +dJJQccnRPpcbQcMHsSgSMsDMTJSg +WWGBBvPflnWbBWhvhbPvNfnnVCFZmVRVZmVGMVwRLCCCGwVC +gjszgTMrgzgqCRRdmJRjJLVw +grzQHzqczMSzqSHcgQsqPvPlbNblpPhhPPbHvnhp +sJDDNWdnRLTTvqwSFPCmLCCrCq +thzplgfjglflFcbMclpppMfcwPqCZQCmqCwrzCqmQmHSqPqq +MhcpFBMBlhjbBTdnNJWvNvsvBd +czwwghnWWfcfgwfWthfrvVvrjdrdvDDVrbzrLF +RHPPMRpQPRMPPJRjJQsZsrrvvJBDDVDVdFqrBrFdBv +smjMsGZHRsHSmRQNGHPpSTwwttCflwngnChcCtWW +bprrrwrtLDtrWwrQjRDQDbPPVHVmmmmHNWlPlVNPZZlv +hqqhfnBCTfnnhzJwzsqzfPZZMCCVZVHHFvZMFvZmlC +TzhhdJTqJzcBdJJnzjtQrLdjwgLtpbgrLQ +qzQvzzgWSCqtqqGpddGc +jLrZNZhZrNRLHNffhrjNjNdtdZtGcPFwFwpbGwbVpdwC +nHnhrLNCCMHmhHBMhrzvgJvsWSWMWzzWzSlv +RzcbzdRFzbbzbzbFdZFTHMZPhVhVQMLrlrQPhLZlMM +BNGfBvsNttVmMhlMLm +BwGjpllswfjwpcFDWcWcbpdb +SjzpswrLSDjVSpwlmZJBTBdNJLvBNvHQZT +rCcCtbqgCfthggtbGGMqqghqZQvvQTBNJQHQZQTcZTJFZFFd +CggGMtqMfWbbGghPhhbCMtmsSppSspjpmWzjVSWlVrrm +PmWTPThTQWnLWQFl +VNcSVfMbtsddBQNnNpdl +sSjctwjVSzzccjgnTnDTHRDhqjRR +WfMWfCNCjWWHNTccMjRjfRcMbqSwfVwqwsfGGbssrJSrswVw +llLFQLlvlPFnhQBPBZQBqvBwzSzGGhShJVwShmsJbbmzSG +lnPqvQZBFFBnnpgplFvtvHDjTdcTjTMMjCRNCMWgRC +rprFNFFNjNLmMdgcqL +BvzCQQbBQgffsDbvVHMdbcVqmLVqlmqq +JvJCzBDJwnsRnQDszCBnnnQBrjZPjFpgZFTFZRpTrpZFGFtT +wBHQQZHVCcpwDgdZdMsZjvMZFn +GPSzlNlJLfzzzvsWdWLMmFWLMM +NfqGSfrTNzRTqJfRbptQHFQFrwrFHBHw +sNjVMVNVMzPzQgghcMsNzJtjSJtTFDTJtJnnDLjDnL +CHwrdCpvCrwrWdpZqcpFttJSFJTLLHLJfbnbfD +qrlZCwlqZrqqpWdlRqCRqdqcVNsVMzQzmNgNPBsRhVQVVzMs \ No newline at end of file diff --git a/adventOfCode/2022/4.go b/adventOfCode/2022/4.go new file mode 100644 index 0000000..f5046da --- /dev/null +++ b/adventOfCode/2022/4.go @@ -0,0 +1,65 @@ +// Day 4 +package main + +import ( + //"fmt" + "strings" + "strconv" + "errors" +) + +func withinRange(target int, lower int, higher int) bool { + if lower <= target && target <= higher { + return true + } + return false +} + +func solve4(input []interface{}) (interface{}, interface{}) { + + var day4Inputs [][]int + + // Customize input + for _, val := range input { + ranges := []int{} + pairs := strings.Split(val.(string), ",") + if len(pairs) != 2 { + panic(errors.New("error")) + } + for _, pair := range pairs { + rnge := strings.Split(pair, "-") + for _, r := range rnge { + rint, err := strconv.Atoi(r) + if err != nil { panic(err) } + ranges = append(ranges, rint) + } + } + day4Inputs = append(day4Inputs, ranges) + } + + // Solution 1 + sol1 := 0 + for _, rnge := range day4Inputs { + lowerElf1, upperElf1 := rnge[0], rnge[1] + lowerElf2, upperElf2 := rnge[2], rnge[3] + if withinRange(lowerElf1, lowerElf2, upperElf2) && withinRange(upperElf1, lowerElf2, upperElf2) { + sol1++ + } else if withinRange(lowerElf2, lowerElf1, upperElf1) && withinRange(upperElf2, lowerElf1, upperElf1) { + sol1++ + } + } + + // Solution 2 + sol2 := 0 + for _, rnge := range day4Inputs { + lowerElf1, upperElf1 := rnge[0], rnge[1] + lowerElf2, upperElf2 := rnge[2], rnge[3] + if withinRange(lowerElf1, lowerElf2, upperElf2) || withinRange(upperElf1, lowerElf2, upperElf2) { + sol2++ + } else if withinRange(lowerElf2, lowerElf1, upperElf1) || withinRange(upperElf2, lowerElf1, upperElf1) { + sol2++ + } + } + + return sol1, sol2 +} \ No newline at end of file diff --git a/adventOfCode/2022/4/4-sample.input b/adventOfCode/2022/4/4-sample.input new file mode 100644 index 0000000..99a66c5 --- /dev/null +++ b/adventOfCode/2022/4/4-sample.input @@ -0,0 +1,6 @@ +2-4,6-8 +2-3,4-5 +5-7,7-9 +2-8,3-7 +6-6,4-6 +2-6,4-8 \ No newline at end of file diff --git a/adventOfCode/2022/4/4.input b/adventOfCode/2022/4/4.input new file mode 100644 index 0000000..b301c26 --- /dev/null +++ b/adventOfCode/2022/4/4.input @@ -0,0 +1,1000 @@ +49-51,31-50 +96-99,2-95 +2-62,62-98 +34-76,10-59 +28-83,27-84 +40-41,41-86 +15-46,16-47 +53-93,54-93 +19-98,97-97 +29-52,44-71 +21-67,14-83 +11-93,11-12 +15-88,18-89 +5-87,6-6 +1-96,96-97 +64-88,64-91 +3-98,2-3 +33-87,34-86 +21-23,16-22 +63-95,63-99 +1-99,1-2 +11-26,26-39 +43-45,14-82 +11-94,65-98 +46-67,6-50 +26-64,17-63 +54-54,55-97 +60-93,60-99 +40-78,58-74 +27-64,2-33 +25-48,32-80 +65-83,64-66 +21-69,65-88 +37-74,36-75 +4-66,66-66 +6-14,6-47 +17-73,41-74 +79-95,20-92 +63-87,54-54 +72-93,24-72 +2-94,3-96 +9-94,8-48 +17-91,16-87 +3-84,9-84 +44-94,92-95 +55-56,56-96 +65-77,66-90 +7-40,7-30 +20-89,89-90 +14-15,17-45 +1-70,50-50 +28-92,91-92 +5-7,6-57 +32-50,36-67 +81-82,80-82 +58-89,13-59 +64-90,1-65 +29-96,28-29 +83-83,16-83 +14-84,85-85 +14-67,14-68 +41-58,40-42 +18-49,19-48 +66-85,26-72 +5-89,88-90 +5-97,5-6 +14-87,14-14 +26-76,47-92 +17-97,73-99 +28-88,27-28 +2-4,3-54 +3-98,16-16 +61-62,52-62 +22-53,21-22 +8-81,15-30 +5-75,4-74 +43-96,95-96 +39-41,41-90 +33-49,33-50 +10-12,11-81 +63-64,63-70 +10-55,10-91 +9-32,8-8 +60-61,60-77 +10-11,10-69 +2-77,65-76 +1-41,3-22 +28-70,29-71 +44-45,11-44 +1-99,2-98 +45-77,44-78 +15-96,95-99 +7-98,6-6 +28-98,49-99 +61-79,75-75 +13-84,46-62 +15-36,15-36 +54-80,80-93 +2-91,22-91 +32-85,32-33 +29-55,55-56 +45-66,45-46 +6-63,6-62 +2-91,5-91 +96-97,1-97 +39-60,31-60 +5-94,6-94 +8-94,7-8 +6-85,5-85 +12-88,11-26 +4-79,4-46 +1-8,10-96 +1-76,75-76 +6-81,77-82 +35-96,52-98 +29-82,29-83 +22-86,86-87 +17-57,17-63 +57-58,17-57 +48-99,48-97 +25-26,25-26 +16-17,17-93 +31-74,30-30 +18-25,18-94 +56-77,30-30 +8-61,50-61 +58-70,21-59 +2-3,2-70 +8-12,9-14 +5-98,97-98 +35-55,35-87 +20-60,20-36 +39-39,40-68 +39-76,40-88 +20-29,29-88 +61-62,61-84 +19-86,38-95 +56-68,1-71 +13-58,12-19 +12-54,12-68 +3-71,3-3 +71-72,35-71 +9-10,8-16 +20-71,21-70 +43-66,65-73 +3-88,4-87 +73-74,4-74 +62-97,15-95 +59-98,98-99 +10-90,89-99 +11-85,10-86 +4-6,5-6 +7-92,2-92 +54-78,78-78 +78-81,69-84 +18-44,17-19 +7-17,4-16 +71-90,70-88 +82-83,82-88 +47-72,39-72 +22-95,28-98 +98-98,68-98 +5-96,4-97 +76-92,1-77 +17-62,16-63 +20-41,20-83 +59-74,58-60 +8-83,8-9 +30-94,64-97 +18-67,12-67 +32-54,18-33 +31-81,31-81 +14-15,14-14 +89-92,18-90 +16-23,1-34 +1-98,1-51 +3-98,2-3 +16-97,97-98 +32-82,32-33 +1-11,2-12 +88-90,37-92 +2-15,3-15 +19-57,5-60 +15-17,14-17 +83-83,50-84 +2-32,27-54 +16-30,2-29 +37-38,38-93 +11-29,16-99 +78-83,37-77 +40-58,17-57 +9-35,8-10 +2-96,2-3 +20-43,20-70 +95-96,15-96 +10-37,4-16 +53-54,54-90 +90-99,49-91 +4-73,4-74 +55-56,56-76 +83-88,83-86 +82-83,69-82 +2-30,4-77 +6-8,8-49 +44-45,18-44 +6-66,66-67 +74-76,10-76 +25-53,24-25 +1-2,5-22 +6-96,96-96 +68-79,80-98 +43-98,42-44 +79-91,27-91 +17-17,17-17 +48-49,1-48 +4-58,20-58 +18-20,19-87 +86-87,7-86 +34-35,21-35 +18-67,17-68 +19-95,18-24 +44-77,38-76 +70-72,50-71 +19-99,20-99 +98-99,19-96 +22-57,5-20 +95-97,5-96 +4-98,3-97 +10-58,10-59 +5-8,7-95 +10-94,8-17 +1-11,12-72 +37-56,55-56 +32-78,19-78 +29-92,10-90 +11-73,60-73 +16-95,17-72 +90-93,43-91 +27-73,72-73 +25-57,28-57 +32-87,31-85 +96-99,2-97 +24-51,23-52 +25-54,32-55 +2-91,2-66 +15-82,14-15 +24-40,24-80 +14-34,13-34 +30-95,21-94 +53-74,53-73 +77-81,79-98 +9-98,6-6 +13-94,14-95 +46-81,23-80 +6-89,14-90 +42-56,43-51 +96-97,4-96 +11-11,12-26 +50-71,50-72 +81-85,27-82 +10-36,11-11 +30-31,30-75 +34-39,34-88 +30-65,30-64 +1-98,1-36 +67-73,63-67 +8-94,7-99 +64-65,64-81 +64-94,41-94 +8-53,7-8 +17-91,18-92 +30-80,31-81 +4-72,5-71 +5-81,80-82 +1-7,6-82 +72-73,29-73 +7-73,4-4 +4-6,5-95 +8-92,8-9 +12-82,81-83 +76-76,76-77 +42-67,42-84 +1-75,5-66 +3-99,3-91 +34-35,11-34 +7-98,97-98 +15-66,14-26 +83-83,63-83 +2-4,3-67 +4-96,4-4 +5-5,5-89 +5-94,5-6 +6-52,7-51 +1-64,1-63 +37-94,36-38 +50-87,50-88 +24-77,28-77 +12-91,77-91 +29-92,28-30 +41-42,41-57 +62-84,83-85 +46-95,19-42 +31-87,30-30 +2-21,1-2 +72-75,1-73 +59-98,59-94 +65-78,51-71 +11-58,12-58 +52-67,34-37 +55-62,53-60 +26-27,27-76 +12-97,33-98 +95-95,56-94 +17-90,17-91 +7-39,39-63 +45-98,37-46 +41-62,42-69 +5-98,2-5 +43-44,43-44 +34-35,34-35 +8-89,7-90 +33-87,32-86 +38-47,38-46 +2-93,93-93 +25-77,19-41 +15-81,16-81 +7-68,67-78 +52-77,18-69 +8-9,8-59 +4-82,3-5 +23-49,24-71 +10-93,4-92 +21-53,22-54 +5-50,5-99 +14-90,13-22 +14-75,15-94 +6-81,72-84 +22-99,22-99 +11-80,5-12 +79-96,22-78 +27-83,21-27 +88-94,72-89 +10-32,9-80 +3-5,5-99 +3-97,3-61 +15-83,29-68 +82-84,45-82 +50-95,10-50 +41-98,78-93 +19-89,10-92 +78-80,31-79 +22-71,21-71 +82-84,38-83 +13-19,13-14 +13-44,43-84 +43-82,43-97 +1-52,2-89 +21-30,31-88 +49-71,49-88 +36-81,80-92 +65-66,65-91 +75-87,22-76 +57-91,86-91 +16-23,16-16 +95-97,2-91 +64-68,65-95 +15-42,32-60 +55-98,70-96 +4-5,4-69 +10-51,10-52 +17-95,16-17 +30-69,29-40 +72-73,24-73 +13-87,12-88 +12-47,29-85 +19-20,20-51 +67-90,56-78 +27-85,1-86 +1-97,1-2 +54-60,34-58 +7-97,6-98 +41-84,42-84 +74-80,29-79 +22-52,14-22 +36-54,36-62 +32-88,22-89 +10-54,5-5 +6-36,7-17 +7-93,7-8 +38-81,37-37 +43-85,14-88 +20-90,89-90 +50-78,46-68 +18-59,5-59 +24-84,83-85 +10-63,10-11 +95-95,15-95 +58-84,59-59 +76-82,75-79 +48-51,48-55 +43-68,8-56 +67-96,68-96 +9-10,10-53 +8-68,6-6 +75-75,34-76 +52-53,53-54 +12-24,24-66 +41-42,19-42 +70-89,36-71 +52-87,49-86 +36-91,90-92 +16-52,17-52 +8-95,7-91 +92-95,9-93 +3-96,15-96 +58-79,57-73 +85-87,9-95 +60-61,2-60 +11-23,3-11 +14-90,3-15 +8-60,13-26 +82-91,85-91 +56-99,51-57 +5-95,9-96 +6-44,45-62 +63-99,62-98 +24-35,34-36 +51-52,51-98 +37-52,31-53 +51-51,50-72 +2-55,51-55 +6-83,82-95 +11-89,11-93 +30-62,8-41 +32-82,26-82 +8-87,7-86 +33-34,12-33 +35-93,36-87 +46-47,9-46 +3-87,3-3 +83-94,93-94 +5-98,4-99 +48-50,45-50 +35-50,35-43 +14-43,5-43 +48-97,10-96 +9-78,9-78 +59-61,58-60 +7-73,72-73 +4-97,3-5 +11-49,49-50 +42-99,99-99 +8-73,7-63 +4-82,34-87 +14-76,13-40 +26-95,25-98 +5-62,61-62 +28-45,22-45 +29-41,36-42 +85-98,61-86 +12-97,11-97 +6-78,5-60 +61-67,39-62 +58-77,58-73 +92-98,5-96 +41-98,39-41 +2-77,25-78 +62-71,1-49 +11-84,10-11 +25-42,26-78 +32-97,3-12 +36-73,7-73 +26-71,25-27 +1-48,19-48 +11-37,11-99 +49-76,42-50 +2-34,1-97 +60-66,66-66 +4-4,3-5 +37-37,38-40 +94-94,35-94 +82-84,5-83 +55-56,5-56 +20-93,20-95 +57-61,11-60 +86-87,15-87 +11-73,11-42 +10-35,2-34 +35-47,48-70 +12-94,2-97 +3-81,80-82 +18-49,18-70 +27-96,95-96 +38-39,39-57 +75-94,6-94 +19-60,56-56 +77-87,81-87 +4-7,3-9 +89-98,18-88 +2-2,3-75 +10-62,7-7 +10-23,9-35 +3-95,1-94 +32-83,82-83 +37-66,37-70 +36-45,45-70 +9-79,78-80 +2-96,1-1 +39-44,43-44 +10-95,11-98 +32-34,33-90 +17-93,29-94 +50-97,97-98 +21-90,21-73 +3-3,3-71 +32-96,11-95 +18-98,19-98 +39-93,92-93 +39-77,38-40 +30-91,6-92 +39-73,39-74 +38-96,39-56 +5-91,6-14 +19-19,20-87 +7-95,6-7 +38-94,2-95 +4-99,3-73 +23-99,24-74 +1-24,4-25 +10-25,25-86 +9-90,8-91 +20-26,23-72 +80-82,3-81 +8-38,8-9 +57-86,35-70 +6-90,3-4 +21-28,21-23 +11-96,10-90 +41-51,50-50 +30-57,13-31 +7-77,6-77 +87-88,2-88 +40-86,36-85 +73-75,9-74 +75-91,21-74 +1-89,12-90 +28-85,23-23 +79-79,11-79 +10-93,59-96 +38-38,39-48 +3-93,56-94 +8-13,7-8 +4-43,5-42 +22-22,20-24 +5-56,5-30 +43-83,66-83 +28-94,27-93 +22-23,23-88 +8-76,1-75 +29-94,28-29 +6-89,5-7 +22-97,22-89 +2-92,3-92 +19-19,18-69 +30-49,3-12 +2-38,32-96 +32-71,66-90 +10-51,14-51 +17-97,17-96 +42-49,59-64 +96-98,29-96 +7-8,7-43 +93-94,1-94 +57-71,58-73 +4-98,4-4 +89-90,6-89 +79-81,80-81 +52-94,51-75 +5-73,4-6 +90-91,34-91 +45-87,69-96 +13-30,14-57 +78-79,12-78 +10-45,9-10 +12-78,12-68 +3-14,10-16 +73-88,14-76 +14-14,10-15 +42-83,43-79 +15-94,94-95 +13-94,3-22 +9-62,9-62 +76-87,76-76 +3-11,2-11 +27-57,4-27 +28-60,27-60 +49-63,49-62 +58-69,65-69 +2-99,2-98 +33-89,33-97 +32-47,32-36 +56-56,41-56 +16-94,26-74 +91-91,10-92 +8-28,7-29 +6-91,5-6 +21-93,20-21 +57-74,22-29 +33-33,5-32 +78-82,80-82 +1-72,1-37 +72-94,13-73 +44-51,45-60 +2-97,1-1 +37-94,25-56 +16-71,17-72 +24-25,21-25 +9-81,44-97 +18-85,85-86 +40-93,92-98 +89-90,48-90 +3-74,3-3 +9-99,4-92 +17-27,27-98 +25-72,72-73 +41-99,72-99 +23-23,23-92 +47-78,39-48 +58-96,5-94 +7-90,89-92 +60-61,61-87 +43-67,28-67 +23-97,22-24 +1-31,19-32 +5-88,2-88 +1-34,2-97 +28-86,7-86 +16-80,16-80 +6-59,20-60 +68-89,73-95 +46-94,38-81 +20-25,21-78 +78-80,77-78 +33-97,96-98 +48-98,47-49 +4-98,2-98 +26-69,26-88 +26-75,75-78 +72-92,72-93 +4-92,4-93 +66-76,65-67 +2-97,3-97 +41-57,41-42 +6-77,76-97 +16-43,17-56 +49-51,4-50 +95-97,56-96 +1-97,80-97 +35-38,36-37 +10-84,18-84 +20-84,6-59 +18-81,36-82 +79-81,80-88 +41-96,89-95 +66-94,3-88 +71-72,56-72 +74-88,73-74 +57-73,58-60 +31-73,1-27 +14-25,9-25 +8-9,8-82 +3-96,95-97 +75-77,4-76 +16-89,15-16 +3-62,61-71 +20-28,19-48 +31-31,32-69 +5-61,6-60 +67-76,76-76 +82-93,70-89 +49-96,29-77 +3-14,7-15 +9-24,24-44 +10-82,9-59 +91-92,82-92 +4-61,3-73 +42-43,43-67 +63-78,64-64 +8-8,9-94 +54-55,54-64 +12-35,18-96 +12-55,53-53 +3-85,23-85 +26-93,32-93 +9-23,3-9 +49-82,48-48 +61-84,61-83 +35-37,36-91 +6-78,4-4 +73-80,4-76 +8-77,8-94 +18-22,20-22 +75-84,76-76 +51-91,24-90 +24-94,3-88 +17-17,18-59 +1-93,55-97 +15-75,5-75 +7-11,11-47 +3-85,3-4 +14-86,13-15 +13-93,33-95 +4-6,3-3 +33-56,33-89 +42-42,43-84 +46-77,76-77 +57-60,36-60 +23-24,24-53 +87-94,88-97 +1-83,1-52 +22-41,20-27 +12-86,85-87 +53-87,50-56 +8-51,8-50 +27-71,10-71 +7-62,8-63 +17-28,27-97 +1-90,90-90 +3-94,2-4 +3-98,2-24 +11-12,12-83 +18-37,19-36 +9-98,9-90 +4-98,3-99 +82-82,53-82 +5-54,6-88 +75-91,91-91 +20-98,19-98 +2-48,10-62 +16-42,41-42 +61-71,59-71 +3-92,3-4 +12-47,12-69 +23-26,26-65 +20-57,67-97 +65-95,64-65 +1-92,3-88 +5-83,5-89 +44-81,80-82 +30-32,31-84 +10-51,50-50 +25-52,16-25 +37-45,38-44 +46-47,47-62 +59-85,84-85 +13-86,12-87 +29-76,4-30 +79-93,12-80 +61-86,61-68 +13-85,15-85 +33-35,34-94 +68-69,33-71 +55-90,55-82 +20-94,23-94 +82-98,6-83 +26-78,26-79 +14-16,14-15 +6-47,46-49 +4-98,1-97 +17-76,37-65 +13-71,13-59 +24-67,14-58 +13-47,48-92 +37-38,37-60 +30-90,30-71 +62-74,33-86 +39-40,26-40 +6-81,5-16 +10-70,10-10 +4-84,83-92 +87-89,68-87 +47-95,16-84 +23-86,29-86 +30-98,30-62 +28-85,29-83 +87-98,56-97 +91-92,12-92 +89-99,67-90 +52-99,29-97 +5-92,3-16 +3-74,2-84 +54-83,55-55 +1-39,39-94 +1-98,97-98 +20-98,7-17 +27-47,10-27 +3-4,3-64 +86-87,4-86 +12-68,21-47 +78-79,37-79 +23-48,8-36 +5-88,4-82 +10-96,9-96 +1-99,2-99 +57-77,56-56 +66-85,65-68 +73-87,87-90 +13-96,12-89 +15-90,60-66 +75-75,12-75 +15-86,85-91 +26-67,25-44 +15-86,16-87 +23-58,43-69 +2-86,16-87 +18-78,9-19 +92-94,13-93 +8-46,2-45 +39-60,39-50 +76-85,75-77 +52-63,36-63 +4-66,3-4 +51-70,70-89 +4-7,7-97 +38-93,38-84 +2-9,9-96 +14-19,18-20 +3-79,2-37 +25-84,83-96 +21-36,22-65 +41-82,42-96 +2-77,38-78 +84-88,59-97 +3-70,4-71 +53-93,17-93 +94-95,2-99 +71-88,9-70 +12-41,13-41 +12-54,11-53 +72-73,73-78 +4-81,18-33 +23-52,10-94 +23-91,5-57 +45-45,43-45 +48-83,47-47 +12-96,11-11 +68-81,72-93 +14-92,8-14 +84-99,28-97 +21-81,22-82 +12-37,11-32 +40-45,39-39 +23-34,25-27 +23-23,24-65 +77-85,85-98 +91-98,91-96 +88-90,11-89 +5-5,6-98 +23-28,4-13 +20-58,19-58 +3-96,4-94 +16-22,8-19 +78-79,78-84 +67-80,62-68 +80-94,79-97 +12-79,78-79 +29-50,29-51 +2-41,41-42 +68-69,17-68 +38-39,2-39 +13-14,14-78 +9-80,8-9 +42-92,64-93 +67-78,66-73 +14-65,14-15 +6-59,1-35 +16-17,17-48 +15-28,16-33 +2-9,48-91 +3-4,4-86 +28-45,50-56 +15-23,16-86 +50-79,50-78 +9-62,8-8 +4-91,4-12 +24-25,25-65 +38-39,38-61 +8-8,18-76 +56-86,1-56 +13-68,68-74 +15-42,26-42 +40-45,40-61 +92-99,4-93 +20-35,25-32 +15-28,15-69 +26-94,8-94 +16-94,3-96 +16-98,16-21 +17-17,18-23 +26-30,26-27 +33-49,31-34 +13-99,85-90 +12-74,6-74 +54-60,53-57 +10-94,11-95 +37-53,37-38 +2-79,2-48 +46-55,53-60 +7-95,7-8 +7-83,8-98 +6-7,7-32 +47-82,46-47 +63-85,64-87 +77-78,57-77 +3-5,3-4 +5-98,97-99 +59-92,2-92 +4-97,1-99 +37-86,2-86 +46-47,9-47 +38-86,37-38 +24-48,52-71 +14-85,85-86 +20-83,20-21 +49-83,50-70 +44-63,45-88 +43-70,3-43 +34-76,2-75 +1-72,73-84 +49-89,45-89 +45-85,13-45 +29-98,28-30 +7-8,7-58 +20-20,21-41 +52-63,18-52 +81-95,76-81 +3-95,2-95 +74-84,68-75 +51-63,51-64 +19-72,40-72 +53-57,4-80 +21-88,19-87 +29-93,30-99 +4-98,7-98 +20-62,49-63 +5-71,5-70 +35-83,35-66 +12-71,35-78 +7-59,7-95 +7-62,7-70 +2-9,9-97 +5-11,8-12 +6-17,18-20 +5-87,3-3 +83-92,5-92 +12-95,12-54 +37-83,23-83 +39-48,40-53 +14-95,51-95 +37-98,70-80 +16-90,19-91 +2-27,16-46 +3-87,6-17 +49-49,49-79 +7-30,35-71 +21-40,22-29 +77-87,76-78 +11-68,23-69 +18-19,18-80 +21-79,13-21 +9-89,8-90 +4-85,7-89 +36-44,18-36 +1-21,2-44 +1-98,2-99 +56-57,3-56 +23-24,23-81 +22-25,10-24 +6-94,93-99 +13-37,12-14 +13-29,30-86 +65-88,66-90 +90-92,6-91 +42-43,43-67 +27-33,28-31 +31-90,37-90 +5-97,2-3 +25-55,1-26 +90-91,10-90 +35-52,36-53 +41-42,41-41 +7-75,18-75 +8-69,2-82 +56-96,11-96 +13-79,12-78 +5-11,11-94 +18-18,17-72 +4-94,1-93 +32-38,33-71 +3-5,4-98 \ No newline at end of file diff --git a/adventOfCode/2022/5.go b/adventOfCode/2022/5.go new file mode 100644 index 0000000..3c4a827 --- /dev/null +++ b/adventOfCode/2022/5.go @@ -0,0 +1,129 @@ +// Day 5 +package main + +import ( + "fmt" + "strconv" + "strings" +) + +func printContainers(stackBuilder [][]string) { + for _, level := range stackBuilder { + _ = level[0] + fmt.Println(level) + } +} + +func solve5(input []interface{}) (interface{}, interface{}) { + + stackBuilder := [][]string{} + moves := [][]int{} + + // Read stack from input + for _, val := range input { + if strings.Contains(val.(string), "[") { + currStr := val.(string) + currLevel := []string{} + for len(currStr) > 0 { + current := "" + if len(currStr) > 4 { + current = currStr[:4] + currStr = currStr[4:] + } else { + current = currStr[:3] + currStr = currStr[3:] + } + if current == "" { + continue + } + current = strings.TrimSpace(current) + if current == "" { + currLevel = append(currLevel, "EE") + continue + } + current = strings.Trim(current, "[]") + currLevel = append(currLevel, current) + } + stackBuilder = append(stackBuilder, currLevel) + } else { + break + } + } + + // Read moves from Input + for _, val := range input { + if strings.Contains(val.(string), "move") { + curr_move := []int{} + curr_moves := strings.Split(val.(string), " ") + for _, c := range curr_moves { + intVal, err := strconv.Atoi(c) + if err == nil { + curr_move = append(curr_move, intVal) + } + } + moves = append(moves, curr_move) + } + } + + + // Build stacks + stacks1 := make([][]string, len(stackBuilder[0])) + stacks2 := make([][]string, len(stackBuilder[0])) + for _, level := range stackBuilder { + for index, value := range level { + if value != "EE" { + stacks1[index] = append(stacks1[index], value) + stacks2[index] = append(stacks2[index], value) + } + } + } + + // Solution 1 + sol1 := "" + + + for _, m := range moves { + n := m[0] + from := m[1]-1 + to := m[2]-1 + + for n > 0 { + asset := stacks1[from][0] + if len(stacks1[from]) == 1 { + stacks1[from] = []string{} + } else { + stacks1[from] = stacks1[from][1:] + } + stacks1[to] = append([]string{asset}, stacks1[to]...) + n-- + } + } + + for _, s := range stacks1 { + sol1 += s[0] + } + + + // Solution 2 + sol2 := "" + for _, m := range moves { + n := m[0] + from := m[1]-1 + to := m[2]-1 + + asset := make([]string, n) + copy(asset, stacks2[from][:n]) + if len(stacks2[from]) <= n { + stacks2[from] = []string{} + } else { + stacks2[from] = stacks2[from][n:] + } + stacks2[to] = append(asset, stacks2[to]...) + } + + for _, s := range stacks2 { + sol2 += s[0] + } + + return sol1, sol2 +} \ No newline at end of file diff --git a/adventOfCode/2022/5/5-sample.input b/adventOfCode/2022/5/5-sample.input new file mode 100644 index 0000000..e98aba4 --- /dev/null +++ b/adventOfCode/2022/5/5-sample.input @@ -0,0 +1,9 @@ + [D] +[N] [C] +[Z] [M] [P] + 1 2 3 + +move 1 from 2 to 1 +move 3 from 1 to 3 +move 2 from 2 to 1 +move 1 from 1 to 2 \ No newline at end of file diff --git a/adventOfCode/2022/5/5.input b/adventOfCode/2022/5/5.input new file mode 100644 index 0000000..08ba37e --- /dev/null +++ b/adventOfCode/2022/5/5.input @@ -0,0 +1,513 @@ +[D] [N] [F] +[H] [F] [L] [J] [H] +[R] [H] [F] [V] [G] [H] +[Z] [Q] [Z] [W] [L] [J] [B] +[S] [W] [H] [B] [H] [D] [C] [M] +[P] [R] [S] [G] [J] [J] [W] [Z] [V] +[W] [B] [V] [F] [G] [T] [T] [T] [P] +[Q] [V] [C] [H] [P] [Q] [Z] [D] [W] + 1 2 3 4 5 6 7 8 9 + +move 1 from 3 to 9 +move 2 from 2 to 1 +move 3 from 5 to 4 +move 1 from 1 to 8 +move 1 from 3 to 9 +move 1 from 5 to 7 +move 1 from 5 to 3 +move 4 from 4 to 2 +move 2 from 3 to 4 +move 1 from 3 to 2 +move 6 from 1 to 5 +move 1 from 4 to 3 +move 1 from 3 to 9 +move 4 from 2 to 4 +move 4 from 8 to 7 +move 3 from 2 to 6 +move 1 from 2 to 7 +move 5 from 5 to 6 +move 1 from 5 to 8 +move 5 from 8 to 7 +move 7 from 4 to 6 +move 15 from 6 to 4 +move 1 from 8 to 7 +move 1 from 1 to 5 +move 1 from 2 to 4 +move 2 from 4 to 8 +move 1 from 5 to 2 +move 5 from 6 to 4 +move 2 from 2 to 1 +move 1 from 9 to 4 +move 1 from 6 to 9 +move 3 from 9 to 3 +move 3 from 4 to 3 +move 1 from 6 to 1 +move 5 from 3 to 4 +move 2 from 8 to 5 +move 1 from 3 to 6 +move 1 from 6 to 2 +move 1 from 2 to 8 +move 6 from 4 to 2 +move 1 from 2 to 7 +move 1 from 5 to 3 +move 4 from 9 to 3 +move 1 from 9 to 1 +move 3 from 1 to 6 +move 1 from 9 to 7 +move 14 from 7 to 6 +move 1 from 8 to 3 +move 4 from 2 to 6 +move 3 from 3 to 8 +move 9 from 4 to 9 +move 1 from 1 to 5 +move 2 from 5 to 8 +move 3 from 8 to 2 +move 4 from 2 to 6 +move 1 from 3 to 9 +move 10 from 6 to 1 +move 5 from 9 to 8 +move 1 from 9 to 3 +move 6 from 1 to 8 +move 3 from 7 to 4 +move 2 from 4 to 5 +move 2 from 9 to 8 +move 15 from 8 to 3 +move 3 from 7 to 9 +move 8 from 4 to 3 +move 2 from 5 to 9 +move 6 from 6 to 5 +move 6 from 5 to 8 +move 1 from 7 to 8 +move 6 from 9 to 2 +move 5 from 2 to 4 +move 6 from 3 to 5 +move 5 from 5 to 8 +move 1 from 5 to 7 +move 1 from 9 to 7 +move 2 from 6 to 4 +move 12 from 8 to 2 +move 7 from 2 to 4 +move 3 from 7 to 5 +move 3 from 5 to 7 +move 3 from 7 to 9 +move 2 from 9 to 7 +move 1 from 9 to 3 +move 2 from 7 to 4 +move 3 from 1 to 9 +move 4 from 6 to 5 +move 6 from 2 to 8 +move 14 from 4 to 9 +move 7 from 9 to 6 +move 9 from 9 to 2 +move 1 from 5 to 8 +move 5 from 6 to 3 +move 3 from 1 to 9 +move 3 from 8 to 9 +move 1 from 8 to 3 +move 5 from 2 to 5 +move 1 from 4 to 9 +move 2 from 6 to 1 +move 2 from 3 to 6 +move 3 from 8 to 3 +move 2 from 6 to 3 +move 1 from 4 to 9 +move 4 from 3 to 6 +move 7 from 6 to 9 +move 10 from 9 to 2 +move 10 from 3 to 2 +move 7 from 2 to 8 +move 2 from 1 to 7 +move 13 from 3 to 7 +move 7 from 5 to 1 +move 1 from 9 to 6 +move 4 from 8 to 4 +move 2 from 3 to 2 +move 4 from 4 to 6 +move 1 from 3 to 4 +move 5 from 6 to 5 +move 3 from 5 to 7 +move 12 from 2 to 5 +move 7 from 5 to 6 +move 2 from 8 to 3 +move 7 from 6 to 2 +move 3 from 9 to 6 +move 1 from 6 to 7 +move 1 from 4 to 9 +move 2 from 7 to 6 +move 13 from 7 to 4 +move 3 from 7 to 5 +move 1 from 9 to 6 +move 12 from 4 to 3 +move 1 from 8 to 1 +move 2 from 6 to 4 +move 1 from 7 to 9 +move 2 from 9 to 8 +move 12 from 3 to 5 +move 1 from 8 to 2 +move 15 from 5 to 6 +move 2 from 4 to 6 +move 1 from 9 to 6 +move 5 from 5 to 4 +move 4 from 4 to 2 +move 2 from 1 to 5 +move 4 from 1 to 5 +move 1 from 8 to 6 +move 7 from 5 to 2 +move 22 from 2 to 3 +move 9 from 6 to 3 +move 1 from 1 to 8 +move 1 from 8 to 7 +move 23 from 3 to 6 +move 2 from 2 to 4 +move 1 from 7 to 8 +move 1 from 8 to 2 +move 19 from 6 to 9 +move 2 from 2 to 4 +move 4 from 4 to 6 +move 13 from 6 to 8 +move 12 from 9 to 1 +move 2 from 5 to 9 +move 2 from 4 to 8 +move 1 from 2 to 7 +move 1 from 7 to 1 +move 4 from 6 to 2 +move 10 from 1 to 9 +move 1 from 6 to 7 +move 11 from 8 to 2 +move 6 from 3 to 6 +move 1 from 7 to 2 +move 1 from 1 to 8 +move 2 from 6 to 7 +move 7 from 6 to 3 +move 9 from 3 to 1 +move 7 from 9 to 6 +move 1 from 8 to 7 +move 4 from 2 to 6 +move 1 from 8 to 3 +move 6 from 6 to 5 +move 9 from 9 to 3 +move 5 from 6 to 1 +move 1 from 7 to 8 +move 2 from 8 to 4 +move 1 from 4 to 2 +move 1 from 4 to 5 +move 2 from 5 to 6 +move 1 from 6 to 9 +move 9 from 1 to 4 +move 4 from 4 to 6 +move 2 from 4 to 7 +move 7 from 2 to 8 +move 5 from 6 to 7 +move 6 from 3 to 8 +move 8 from 1 to 9 +move 3 from 5 to 2 +move 2 from 3 to 9 +move 3 from 9 to 4 +move 7 from 2 to 3 +move 1 from 7 to 2 +move 10 from 3 to 2 +move 6 from 9 to 4 +move 1 from 3 to 1 +move 1 from 1 to 8 +move 4 from 8 to 5 +move 10 from 8 to 4 +move 2 from 8 to 9 +move 7 from 4 to 9 +move 6 from 2 to 6 +move 3 from 6 to 5 +move 4 from 4 to 9 +move 8 from 7 to 5 +move 1 from 9 to 2 +move 7 from 2 to 1 +move 4 from 9 to 8 +move 2 from 6 to 3 +move 2 from 3 to 2 +move 13 from 5 to 7 +move 5 from 4 to 9 +move 5 from 1 to 7 +move 3 from 5 to 8 +move 17 from 7 to 2 +move 15 from 2 to 6 +move 15 from 9 to 5 +move 1 from 9 to 5 +move 4 from 8 to 6 +move 1 from 4 to 6 +move 5 from 4 to 7 +move 5 from 2 to 7 +move 18 from 6 to 2 +move 2 from 7 to 6 +move 10 from 2 to 8 +move 2 from 2 to 3 +move 11 from 8 to 7 +move 7 from 7 to 5 +move 9 from 7 to 5 +move 3 from 7 to 5 +move 2 from 1 to 7 +move 4 from 2 to 1 +move 30 from 5 to 1 +move 1 from 3 to 1 +move 35 from 1 to 9 +move 2 from 2 to 5 +move 2 from 8 to 3 +move 20 from 9 to 2 +move 3 from 7 to 9 +move 1 from 3 to 6 +move 5 from 5 to 3 +move 18 from 2 to 5 +move 4 from 5 to 8 +move 7 from 9 to 7 +move 1 from 6 to 2 +move 3 from 8 to 5 +move 6 from 3 to 5 +move 3 from 7 to 4 +move 2 from 2 to 3 +move 1 from 4 to 5 +move 2 from 4 to 5 +move 4 from 7 to 2 +move 26 from 5 to 6 +move 2 from 2 to 7 +move 1 from 2 to 9 +move 1 from 7 to 8 +move 1 from 5 to 3 +move 2 from 8 to 3 +move 11 from 9 to 3 +move 6 from 3 to 4 +move 27 from 6 to 4 +move 33 from 4 to 3 +move 4 from 6 to 8 +move 1 from 2 to 8 +move 1 from 7 to 3 +move 4 from 8 to 9 +move 1 from 8 to 6 +move 34 from 3 to 8 +move 1 from 8 to 5 +move 1 from 2 to 9 +move 8 from 3 to 9 +move 3 from 5 to 4 +move 1 from 6 to 5 +move 27 from 8 to 9 +move 1 from 3 to 4 +move 1 from 5 to 7 +move 3 from 8 to 1 +move 11 from 9 to 1 +move 1 from 7 to 5 +move 11 from 9 to 3 +move 1 from 5 to 1 +move 1 from 8 to 7 +move 2 from 9 to 2 +move 1 from 2 to 1 +move 1 from 2 to 7 +move 2 from 8 to 2 +move 6 from 3 to 8 +move 1 from 4 to 2 +move 7 from 1 to 2 +move 1 from 7 to 1 +move 19 from 9 to 1 +move 3 from 2 to 9 +move 10 from 1 to 4 +move 2 from 9 to 1 +move 1 from 7 to 9 +move 7 from 1 to 6 +move 10 from 4 to 3 +move 14 from 1 to 7 +move 2 from 9 to 1 +move 3 from 4 to 6 +move 9 from 7 to 6 +move 1 from 3 to 5 +move 4 from 8 to 5 +move 10 from 6 to 8 +move 3 from 5 to 6 +move 10 from 3 to 4 +move 4 from 3 to 7 +move 1 from 5 to 9 +move 2 from 7 to 9 +move 1 from 1 to 9 +move 6 from 2 to 4 +move 1 from 5 to 3 +move 11 from 4 to 9 +move 3 from 4 to 9 +move 1 from 2 to 7 +move 2 from 3 to 5 +move 1 from 3 to 2 +move 7 from 7 to 2 +move 2 from 5 to 8 +move 8 from 2 to 1 +move 2 from 6 to 8 +move 9 from 6 to 8 +move 3 from 8 to 2 +move 3 from 2 to 6 +move 9 from 9 to 5 +move 3 from 5 to 8 +move 5 from 9 to 4 +move 3 from 6 to 4 +move 1 from 6 to 3 +move 3 from 1 to 6 +move 3 from 6 to 9 +move 17 from 8 to 5 +move 12 from 5 to 4 +move 21 from 4 to 3 +move 1 from 4 to 9 +move 7 from 5 to 4 +move 22 from 3 to 7 +move 3 from 1 to 8 +move 3 from 9 to 1 +move 4 from 4 to 6 +move 1 from 6 to 2 +move 3 from 4 to 1 +move 1 from 6 to 7 +move 4 from 9 to 3 +move 2 from 5 to 7 +move 1 from 9 to 6 +move 2 from 6 to 9 +move 8 from 7 to 9 +move 1 from 6 to 2 +move 1 from 9 to 3 +move 4 from 3 to 4 +move 14 from 7 to 4 +move 1 from 3 to 2 +move 3 from 7 to 8 +move 12 from 8 to 9 +move 8 from 4 to 1 +move 1 from 7 to 4 +move 2 from 5 to 1 +move 3 from 2 to 9 +move 17 from 9 to 3 +move 6 from 9 to 1 +move 1 from 9 to 2 +move 13 from 3 to 9 +move 4 from 3 to 1 +move 3 from 9 to 1 +move 22 from 1 to 9 +move 1 from 8 to 1 +move 6 from 9 to 5 +move 4 from 1 to 9 +move 3 from 1 to 9 +move 4 from 4 to 8 +move 4 from 4 to 2 +move 1 from 4 to 3 +move 3 from 8 to 9 +move 1 from 3 to 4 +move 1 from 1 to 3 +move 1 from 8 to 2 +move 1 from 5 to 8 +move 4 from 2 to 1 +move 1 from 8 to 7 +move 10 from 9 to 6 +move 1 from 7 to 9 +move 1 from 2 to 3 +move 1 from 6 to 1 +move 3 from 5 to 7 +move 1 from 8 to 7 +move 1 from 6 to 1 +move 1 from 2 to 4 +move 1 from 5 to 2 +move 19 from 9 to 2 +move 1 from 4 to 7 +move 1 from 3 to 7 +move 3 from 7 to 9 +move 4 from 1 to 2 +move 10 from 9 to 4 +move 1 from 5 to 8 +move 3 from 6 to 4 +move 1 from 3 to 4 +move 10 from 2 to 8 +move 12 from 2 to 5 +move 3 from 5 to 9 +move 5 from 6 to 5 +move 5 from 1 to 4 +move 22 from 4 to 3 +move 3 from 8 to 7 +move 1 from 7 to 2 +move 3 from 2 to 9 +move 19 from 3 to 5 +move 2 from 7 to 8 +move 7 from 5 to 6 +move 5 from 9 to 6 +move 1 from 9 to 3 +move 16 from 5 to 1 +move 2 from 3 to 1 +move 3 from 7 to 3 +move 7 from 8 to 4 +move 2 from 8 to 1 +move 5 from 5 to 9 +move 1 from 5 to 2 +move 1 from 2 to 3 +move 1 from 8 to 5 +move 4 from 5 to 7 +move 2 from 3 to 8 +move 2 from 1 to 5 +move 4 from 7 to 6 +move 6 from 4 to 7 +move 4 from 9 to 8 +move 14 from 6 to 7 +move 8 from 1 to 7 +move 7 from 1 to 3 +move 3 from 5 to 9 +move 28 from 7 to 5 +move 1 from 1 to 8 +move 4 from 8 to 3 +move 9 from 3 to 1 +move 1 from 9 to 5 +move 6 from 3 to 2 +move 10 from 1 to 6 +move 1 from 1 to 9 +move 5 from 9 to 7 +move 14 from 5 to 3 +move 1 from 4 to 1 +move 1 from 7 to 2 +move 1 from 7 to 1 +move 1 from 1 to 7 +move 3 from 8 to 5 +move 4 from 6 to 3 +move 3 from 7 to 2 +move 15 from 3 to 6 +move 16 from 5 to 7 +move 4 from 2 to 8 +move 1 from 3 to 1 +move 5 from 7 to 3 +move 12 from 6 to 4 +move 4 from 8 to 5 +move 1 from 4 to 2 +move 2 from 5 to 3 +move 8 from 6 to 3 +move 7 from 4 to 5 +move 9 from 7 to 6 +move 1 from 7 to 9 +move 1 from 1 to 9 +move 1 from 1 to 9 +move 5 from 2 to 8 +move 5 from 8 to 2 +move 11 from 5 to 9 +move 1 from 4 to 2 +move 4 from 9 to 6 +move 12 from 3 to 7 +move 3 from 4 to 9 +move 14 from 6 to 2 +move 2 from 2 to 4 +move 2 from 3 to 5 +move 10 from 7 to 2 +move 1 from 4 to 8 +move 1 from 2 to 7 +move 28 from 2 to 9 +move 4 from 7 to 5 +move 1 from 2 to 4 +move 6 from 5 to 1 +move 2 from 4 to 3 +move 1 from 8 to 1 +move 40 from 9 to 1 +move 10 from 1 to 6 +move 5 from 3 to 5 +move 1 from 9 to 8 +move 3 from 6 to 7 +move 11 from 1 to 2 +move 9 from 2 to 3 +move 3 from 5 to 1 +move 4 from 7 to 1 +move 2 from 2 to 4 +move 2 from 5 to 8 +move 19 from 1 to 7 +move 8 from 3 to 2 +move 14 from 1 to 8 +move 14 from 7 to 1 +move 4 from 6 to 5 +move 1 from 1 to 9 \ No newline at end of file diff --git a/adventOfCode/2022/6.go b/adventOfCode/2022/6.go new file mode 100644 index 0000000..9d8d5a4 --- /dev/null +++ b/adventOfCode/2022/6.go @@ -0,0 +1,72 @@ +// Day 6 +package main + +import ( + //"fmt" + "errors" + mapset "github.com/deckarep/golang-set/v2" +) + +func procedure(input string, cont int) int { + window := []string{} + window_check := mapset.NewSet[string]() + surpassed_seq := []string{} + + for _, chr := range input { + charac := string(chr) + // reset + if window_check.Contains(charac) { + for i, val := range window { + if val == charac { + if i+1 < len(window) { + window = window[i+1:] + } else { + window = []string{} + } + break + } + } + window_check = mapset.NewSet[string]() + for _, v := range window { + window_check.Add(v) + } + } + + // iterate + surpassed_seq = append(surpassed_seq, charac) + window_check.Add(charac) + window = append(window, charac) + + // exit criteria + if window_check.Cardinality() == cont { + return len(surpassed_seq) + } + } + return 0 +} + +func solve6(input []interface{}) (interface{},interface{}) { + + var day6Inputs []string + + // Customize input + for _, val := range input { + sequence, ok := val.(string) + if !ok { panic(errors.New("panic")) } + day6Inputs = append(day6Inputs, sequence) + } + + // Solution 1 + sol1 := 0 + for _, ip := range day6Inputs { + sol1 = procedure(ip, 4) + } + + // Solution 2 + sol2 := 0 + for _, ip := range day6Inputs { + sol2 = procedure(ip, 14) + } + + return sol1, sol2 +} \ No newline at end of file diff --git a/adventOfCode/2022/6/6-sample.input b/adventOfCode/2022/6/6-sample.input new file mode 100644 index 0000000..361d057 --- /dev/null +++ b/adventOfCode/2022/6/6-sample.input @@ -0,0 +1,4 @@ +bvwbjplbgvbhsrlpgdmjqwftvncz +nppdvjthqldpwncqszvftbrmjlhg +nznrnfrfntjfmvfwmzdfjlvtqnbhcprsg +zcfzfwzzqfrljwzlrfnpqdbhtmscgvjw \ No newline at end of file diff --git a/adventOfCode/2022/6/6.input b/adventOfCode/2022/6/6.input new file mode 100644 index 0000000..0fd53a8 --- /dev/null +++ b/adventOfCode/2022/6/6.input @@ -0,0 +1 @@ +pqffvllhrhthvhshhpnhpnpqpvpvrpvpwvwjjdssmcsmccjvjmjjwnjwjwhjwwwzswwhvhwwlvvlbvbtbzbfbzbtbqbgbpbggwzggvjjdpdffbmffntncchtccbcffcjfjnjfnntssvtstzssmnnhrhlhbbwfwjfwjfwwbhhfhmmpsssbnssssfzzfpffdrdpdqqvnncjjgrjjmhhpqqcjqcjjzdzzpvvprrlglrrcmcqqtltdltddswsrrzzwgzzgssczcmzzmgmwgmggwwzttpccmcsmmvfvnvppzlzvzllgclggpfggfnfrfvrvwwvhwwvgwwrbbgfglflblzblzbznzhzffplffnrrcqqsgsvshvhlldhhvnhhmdddnssdvdwdwccggmddsmswwtctdtqqjsshhjzzdpdmpdmppjtjwjswjsjjjsdjjtrtbrbjjwwvnvppqphqhwhcwhwbbpgbbnhbnhhswwdswwlcczdztzbbbnwwtmmpvvgjjqgqdqzzdjdpjjnnffhccscvvchhbmbcbffpdpggvdvttpvpqqhggdtdhtdhhmghmgggzwgwrgwggwlggvpggcfcttzmtmgmvgmmpqmqlmqllsqqjbjwjsszczlzrzgrzzhshlhjjwttwnntbtjtjpplccqrqhrhssbmbttrddfvfwwjcwcvwcwwvpvggqwgwjgwgccvqqcmqqtqnqpnqnffdqfqhhqnhnmhmvhmhwwfrwrggnmmmcnmmgsszmzlmzmddcwwthtssgjsgjjgpgnppdqqcgqggzjgjngnrnggvffgddvtvctcftcftfnnnnhssbgsgwwthtqtltftqtnqttsrtrggwcgwcwmwgmgvmmzrmzrzjzmmcclmmtjmjhmmlhlwlppnpccbbrlrqrcrjrdrlrnngmnmvmcmzczztbblglccvzvppzspsddrzzlsllfzfsspnpdnpnvvvgmmpccmpcpgcpcwcddtmddgwgngqqcpqqlhqqczqqbvqqgdqgqmgmlmmvrrgfgzffbccldcdmmcmcgcngnghngngdngdndcncbbpqbbphbphpccpcwwjswwfttbqbsszccrbbdndsdrdqrqjrjjbmbtbdbbgbvgvcggwdwcccttqccnffjpjqqzpzlzvlljhhschhzlhhfhcfhchvcvtvtgvgzvzrvrdrgrwrjwjljhljlssszsqzsswhhmlhlrhlhzzgghjhzjjcllwrwtrrbdbrbnrnprnrffjvvphhvbbqbbscstsmslmlvmvrmmvvngnlnzzwqzzjqqsqbqrrtmrtmmfgmgrgjjtmjmrrddmrrqmrrjmjqmqnqmmcmlmfmffcgcclplffzvzwvzzjtztftqftqffjjpwjjbpjjggzdgzgwzzfrfvvhfvvwcvvbccfcvffpcpgpbbqhbbhmmzfmfvvnjvnjjhzhqqmffndndmmzhmmqnnlglvvjhjddvggqwgwdgwdggqbqgqrqlrrtptsswlssqwssbdsdrsddjsszjszjjpnjnvnjvnnmznmnddccpwwhshzzcfcqcwcddsjjmnjmjljwwgmglllqlhhctcvvqrvrrhfrrbcrrfbrfbrfrqffbwbqwbbjggsjjjnqqrqsqhhwnhnshnhhdjjqfqpqmmqgqgqggzmmnncrrpgglgqlqclqlsqqwnnfntnzttrnnmtmvvfppbrprzpzzdzvvtctnncpclpccsbbswwcscjssvhvhhqggzmgmqgmgwwgcwgccrllzhzzlzlbljbllmqqpjqqhrhqhjhbbjmjmhmddmwmcmvvmbbmvbmmznnwvwlwtllhwlwgwpgplgpgmgngjgglbglgmllvvlttgrrrlsrllghlggjdjwwfjwfjfvhjmgqnwhwpbdtzrphsqbmmvscslhbdzffsfshgsdjbqbwlgmrtschcnfhdlnndsvpwmwttfglpghhznmgfcjsdlwhnmfqvmpvhgpnnwtjfztbmtprqhsqtjwzhwcqjtjbtqwlcldnvggrwddmpllwnrqwdljwzfzqwcdwgqwvnthnrpcsfwrmqvbzjvzqnmdnfgtbzgtnrvblfwmhdsddgbffnjzvjzfpwglctpqhnqdvtblcchrlmndzhlsczgnsmnbwgnjngnjtlrdpfhqjrwcrqvcpspbtwcvgvvmpnwqjjpdpnslmcrcjnjmhqmrmfbcmrcmpbcbhpcvwqwflljfpgdvqhgdwgcphjqfnqzjjpsqnbtfzhftjtfcbhhcmmlwcfznsflfpphprrgvqwfgjcwfgjfsghzcbqrldwrjlzlbjhpgrbmgdpgzmfsqsphqbbslwwpzspccrhcfrgcjlfwhlcmzdcltbbpcrzglqgqntpwtmgstqlmcsqqbsqgmsmfznwcrfdgvsmnfqmwtsvqvlhwwjlrlhnsvcnrtwwmrjcgfncvlrcqrllndlvmrjpfjpgrrjcwhsqvlbtnlqgwjjqzwcvtvlnfnmqqshbcnqtcbvnwtwbfdgqmvnpmjhlsfdntfwwntvsrrsmspzqmglfnprjtdbmbgnplzzclsjpnzwdhcbhpfnqrgmgqtpfhgnfbqhrpmznbrshjhntzctslwhtgtjvpqhntmchhtncfjmbzcgnpcbpmldrtnpvrzqfftbjjcjlpwwgvmnstjghftcczjzfsftgzpfhbspqmrbfhcdfmqbrgrbsmjvgpbrnvbblwwvqzzpmqrspzvzppjfbgfftdvsdvmrjzhfslptzmgndnqqgmrrfnbbpvbmvpngwjhzvfbwfnzlrgwffvjsfdldfgchfjmnzfnzhwrwttrzlrhmnwvjjdqfmbpfllhrgmddjgnwjnbqwjnslcrdjrmnldcpsgzjpdhrpdfwhbvwhwnhcsmwcwstvqrcrqsnvjrzljfgbljfszchbsqnldgntvcscwqqmpnlwtlfmswtmvrlpzgbrjhtgjgpnhggnprpvwfqpjffqhtfvpnrptgrtwzzlvplgnfjmqphgmnssccrdndqgpljtwtntshrpgsjcdrpmccjnjdgmpmzbfhqjzphcswtwvvqcrwsjhtdqgrhqjmjjcrblpswcblnpzvfztqtbpgjcgngqmwrjtlmhvlsbmrdzwlgqlfqcqnsnjcnddssqbftjvnlgcwwfcgdpdmqrdsjmcnzrfrpnvjmbsltpzwjhjzqqvbgrltczbgvcpwdzqsvhddsbjgjgcmnldrfhnhddlvjcvsnghprjwlghhtghldcqsdcdgnmbcjglvjjvvlbhzczlmjsdqtdpzdtvfztgsdfjsdtfchvzcgvhjnnncmsrfvvmcsjjdftmlpczgvtwngssqmzlmsrrsrbhhhrnwqhmpcdvqmdsvvtsgsqfdcpgsdgzvmbzpbpgtcbshnvdzlmpnwmqrvnmrjprmvppjwfbjhlhzsfhqqzmpbclqvsvfrcqwprrcvqcbbwvnqfwnrgjhlwmgzpfspqrvqrhmqnwvzjrhvvgdgswlvzjjhjtdctlthlpzqhjvwwbpsclpgflcnsdshrqbhmczcwljqlndfnfrcdgmptpsltrcjccnpdchgnswdcpsslcslcjznzpgfhznhbgqhdqvddmqzdnmpshhdcjrsmfjllhfvjvmzzhzrvlbpzqngwmlwcmqnppqzncvjshfrpjlptvnqfrfcrfnbhwhpdqqvjhsqvsmprtgfrddwzjzlwhhqvjpfrwgwvwpszzsfzwjtwngdjfllhjrmqjtmvwsvggnswpqpjbtcrnhhhlzbrvhjdstnpctjlgsffrrbfdvjzhwsgthgfsqnvqdcjffsttlrjnhtqqdpfqpjtdgfwcdwzmwfvqgglsrmmqwbszclpzwldwcswpwfwldrfmmdndcptjbmnvgcpntqcdrcffvgnlpjmcqjpfmbmwjfpqzbzhqtqbzsghbnfvhphfzzhfznttpfrqwpmzjchpzzrdclhdltlqbjmjdfdjqlqbwptsghcnvtdscwgpqnlhhvsvglplhlrwpnzmdbsbrlhmpczzfz \ No newline at end of file diff --git a/adventOfCode/2022/7.go b/adventOfCode/2022/7.go new file mode 100644 index 0000000..b686544 --- /dev/null +++ b/adventOfCode/2022/7.go @@ -0,0 +1,191 @@ +// Day 7 +package main + +import ( + "fmt" + "strings" + "errors" + "strconv" + "path/filepath" + "math" +) + +type Node struct { + name string + typ string + size int + childrens []*Node +} + +// Furnish directory size in tree +func dftFillSize(curNode *Node) int { + dir_sums := 0 + for _, n := range curNode.childrens { + if n.typ == "file" { + continue + } + dir_sums += dftFillSize(n) + } + curNode.size += dir_sums + return curNode.size +} + +// Print nested tree for verification +func printTree(curNode *Node, depth int) { + meta := fmt.Sprintf("(%s, size=%d)", curNode.typ, curNode.size) + fmt.Println(strings.Repeat("| ", depth) + "- " + curNode.name + " " + meta) + for _, c := range curNode.childrens { + printTree(c, depth+1) + } +} + +func solve7(input []interface{}) (interface{},interface{}) { + + var day7Inputs []string + + // Customize input + for _, val := range input { + day7Inputs = append(day7Inputs, val.(string)) + } + + // Solution 1 + sol1 := 0 + + // tree construction with root directory + sol1Tree := Node{ + name: "root", + size: 0, + typ: "dir", + childrens: nil, + } + + // Init control vars + + // track levels + levels := map[int][]string{ + 0: []string{"root"}, + } + // memo nodes visited for easy access + nodes := map[string]*Node{ + "root": &sol1Tree, + } + + // tree control variables + curr_level := 1 + curr_parent := &sol1Tree + curr_dir := "root" + + // Logic + + // iterate until input ceases + for len(day7Inputs) >= 1 { + + // pop the current input + input := day7Inputs[0] + if len(day7Inputs) >= 1 { + day7Inputs = day7Inputs[1:] + } + + // Proccess only commands (diff from output like ls) + command := strings.Split(input, " ") + if command[0] != "$" { + continue + } + + // Command processor + switch command[1] { + case "cd": // Directory traversals + switch command[2] { + case "..": // backward directory traversal + curr_dir = filepath.Join(curr_dir, "../") + curr_level-- + curr_parent = nil + case "/": // root primitives (reset) + curr_parent = nodes["root"] + curr_dir = "root" + default: // change directory + if curr_level >= len(levels) { + panic(errors.New("levels out of bounds")) + } + for _, n := range levels[curr_level] { + relative_path := filepath.Join(curr_dir, command[2]) + if n == relative_path { + curr_parent = nodes[n] + curr_dir = relative_path + } + } + if curr_parent == nil { + panic(errors.New("current parent not found: "+command[2])) + } + curr_level++ + } + case "ls": // construct file system + listOfAssets := [][]string{} // [ [size, file/dir_name] ] + for len(day7Inputs) >= 1 && !strings.HasPrefix(day7Inputs[0],"$") { + listOfAssets = append(listOfAssets, strings.Split(day7Inputs[0], " ")) + day7Inputs = day7Inputs[1:] + } + for _, asset := range listOfAssets { + + // directory/file primitives + sizeInt := 0 + currType := "dir" + if asset[0] != "dir" { + conv, err := strconv.Atoi(asset[0]) + if err != nil { panic(err) } + sizeInt = conv + currType = "file" + } + + // current node primitives (create a file/dir) + relative_name := curr_parent.name + "/" + asset[1] + currNode := Node{ + name: relative_name, + typ: currType, + size: sizeInt, + childrens: nil, + } + + // tree hierarchy arrangement and memo + curr_parent.childrens = append(curr_parent.childrens, &currNode) + curr_parent.size += sizeInt + nodes[relative_name] = &currNode + if _, ok := levels[curr_level]; !ok { + levels[curr_level] = []string{} + } + levels[curr_level] = append(levels[curr_level], relative_name) + } + } + } + + // calculate size by traversing the tree from root + dftFillSize(nodes["root"]) + //printTree(nodes["root"], 0) + + // sol1 + for _, c := range nodes { + if c.typ == "dir" && c.size <= 100000 { + sol1 += c.size + } + } + + // Solution 2 + sol2 := 0 + total_fs := 70000000 + req_space := 30000000 + current_free_space := total_fs - nodes["root"].size + current_req_space := req_space - current_free_space + delta := math.MaxInt + var selected *Node + for _, n := range nodes { + if n.typ == "file" { continue } + curr_delta := n.size-current_req_space + if curr_delta >= 0 && curr_delta < delta { + delta = curr_delta + selected = n + } + } + sol2 = selected.size + + return sol1, sol2 +} \ No newline at end of file diff --git a/adventOfCode/2022/7/7-sample.input b/adventOfCode/2022/7/7-sample.input new file mode 100644 index 0000000..bcbb513 --- /dev/null +++ b/adventOfCode/2022/7/7-sample.input @@ -0,0 +1,23 @@ +$ cd / +$ ls +dir a +14848514 b.txt +8504156 c.dat +dir d +$ cd a +$ ls +dir e +29116 f +2557 g +62596 h.lst +$ cd e +$ ls +584 i +$ cd .. +$ cd .. +$ cd d +$ ls +4060174 j +8033020 d.log +5626152 d.ext +7214296 k \ No newline at end of file diff --git a/adventOfCode/2022/7/7.input b/adventOfCode/2022/7/7.input new file mode 100644 index 0000000..a8dc94d --- /dev/null +++ b/adventOfCode/2022/7/7.input @@ -0,0 +1,1060 @@ +$ cd / +$ ls +150961 cmnwnpwb +28669 hhcp.jzd +dir jssbn +dir lfrctthp +133395 lfrctthp.tlv +dir ltwmz +dir nmzntmcf +dir vhj +256180 wbs.vmh +257693 zsntdzf +$ cd jssbn +$ ls +89372 dvlb +dir lfrctthp +dir pjzpjjq +dir rbtbtt +203148 sppmmj +130200 sppmmj.bmm +dir tlhttrgs +248929 vsbvlr +$ cd lfrctthp +$ ls +dir lfrctthp +dir srf +165285 vlfc +202701 wbs.vmh +$ cd lfrctthp +$ ls +25083 gsb.flc +$ cd .. +$ cd srf +$ ls +20386 hcnjd.nsq +143480 jjlz.mtq +dir rwvdvvsf +88782 sbmhf +143464 wbs.vmh +dir wvhhr +$ cd rwvdvvsf +$ ls +20009 bqz +133188 czdm +$ cd .. +$ cd wvhhr +$ ls +10445 vrwdvnh.jhf +$ cd .. +$ cd .. +$ cd .. +$ cd pjzpjjq +$ ls +14329 chgbd.zjf +dir dvlb +212284 pjc +dir qlrn +225566 rhzgmnb.nhd +145766 sppmmj.dzz +dir vpltwcs +125853 wbs.vmh +$ cd dvlb +$ ls +dir bjfqsb +dir fnwsmj +154127 gplzm +264923 qcp.qvc +dir wlhfvwl +dir wrgqqts +dir zhj +$ cd bjfqsb +$ ls +dir jgltcw +$ cd jgltcw +$ ls +264579 shmqqjf.fwd +$ cd .. +$ cd .. +$ cd fnwsmj +$ ls +dir lfrctthp +dir rddpmj +$ cd lfrctthp +$ ls +dir qdgqdtn +198919 qhjbh.fbc +dir sgddcfdn +$ cd qdgqdtn +$ ls +230357 lbcgfp.vzq +$ cd .. +$ cd sgddcfdn +$ ls +110212 cwjbzd.npb +dir lnjln +207550 wlvdsjj +$ cd lnjln +$ ls +28970 tdw +$ cd .. +$ cd .. +$ cd .. +$ cd rddpmj +$ ls +dir fhlnmw +$ cd fhlnmw +$ ls +228871 mcgdrzg +$ cd .. +$ cd .. +$ cd .. +$ cd wlhfvwl +$ ls +dir rbwq +$ cd rbwq +$ ls +139444 jdczdlwb +66039 mnbq.sdq +$ cd .. +$ cd .. +$ cd wrgqqts +$ ls +124869 dvlb.cfl +$ cd .. +$ cd zhj +$ ls +dir hww +192363 lqn +dir nqv +$ cd hww +$ ls +14681 czhd.bdn +232222 fgcfbrs.wqt +dir pnsbrd +155416 vsw.npv +199792 wbs.vmh +44877 znpdrr.rmd +$ cd pnsbrd +$ ls +179442 vsbvlr +55431 zbhj.wnh +$ cd .. +$ cd .. +$ cd nqv +$ ls +262693 hnz.czd +259429 lptljbz +dir rjgbm +dir tlhttrgs +76496 tlhttrgs.jlv +260003 vsbvlr +$ cd rjgbm +$ ls +45885 fgfh.tch +42899 lfrctthp.fbc +159401 nnmg.tvz +144595 trzgtn.scg +$ cd .. +$ cd tlhttrgs +$ ls +dir cqtnvzn +220458 wbs.vmh +$ cd cqtnvzn +$ ls +49609 czdm +$ cd .. +$ cd .. +$ cd .. +$ cd .. +$ cd .. +$ cd qlrn +$ ls +150270 bflnzt +203988 bgq +dir jwgd +256702 sppmmj +dir wbgvqpc +$ cd jwgd +$ ls +57414 lmlbtpg.wdp +$ cd .. +$ cd wbgvqpc +$ ls +dir dvlb +dir qfhvjtv +dir tpcwhmv +$ cd dvlb +$ ls +118388 hhcp.jzd +$ cd .. +$ cd qfhvjtv +$ ls +82966 lfrctthp +dir mhbbpdpj +139234 wbs.vmh +$ cd mhbbpdpj +$ ls +dir ghrbbh +$ cd ghrbbh +$ ls +24686 tlhttrgs +$ cd .. +$ cd .. +$ cd .. +$ cd tpcwhmv +$ ls +3666 hhcp.jzd +$ cd .. +$ cd .. +$ cd .. +$ cd vpltwcs +$ ls +dir tlhttrgs +146745 vsbvlr +$ cd tlhttrgs +$ ls +dir cchd +32682 cvbr.rmh +209102 mpdpnb +96179 wbs.vmh +$ cd cchd +$ ls +126044 wmrv +$ cd .. +$ cd .. +$ cd .. +$ cd .. +$ cd rbtbtt +$ ls +169793 hzgdsb.tbs +dir wqmvzg +$ cd wqmvzg +$ ls +dir lzbj +$ cd lzbj +$ ls +dir tnhdmqjh +$ cd tnhdmqjh +$ ls +5150 lfrctthp +$ cd .. +$ cd .. +$ cd .. +$ cd .. +$ cd tlhttrgs +$ ls +dir zjghthcb +dir zmlpwlm +$ cd zjghthcb +$ ls +dir dvlb +dir ghzsqrn +dir hvwjc +dir lfrctthp +$ cd dvlb +$ ls +167639 dvlb.fhs +70305 qnhgn.mgn +$ cd .. +$ cd ghzsqrn +$ ls +74556 dbrtz.lrn +dir fngzpjm +dir mdqbvhrr +220711 mrfjpgwj +dir sfhqmzhd +67424 tlhttrgs.thf +202325 vsngvn.ttq +$ cd fngzpjm +$ ls +dir dvlb +dir ghzwdw +$ cd dvlb +$ ls +59824 bmvzg +184952 lfrctthp +51434 qwcttnh.pbs +206348 wbs.vmh +$ cd .. +$ cd ghzwdw +$ ls +132594 lfrctthp +99032 tlhttrgs.cvp +$ cd .. +$ cd .. +$ cd mdqbvhrr +$ ls +32598 zsfv.qqv +$ cd .. +$ cd sfhqmzhd +$ ls +58893 wpmbm +$ cd .. +$ cd .. +$ cd hvwjc +$ ls +233454 ccpnsjm.cwc +72232 lfrctthp +dir nchvqtdq +248368 ptrlpt.gdf +222059 qgjv +69105 wbs.vmh +dir wnj +$ cd nchvqtdq +$ ls +49931 gjwjq.jrc +$ cd .. +$ cd wnj +$ ls +182139 ccpnsjm.cwc +dir dvlb +72806 hhcp.jzd +156378 sppmmj +$ cd dvlb +$ ls +dir cwjbzd +$ cd cwjbzd +$ ls +dir tlhttrgs +$ cd tlhttrgs +$ ls +240264 vdp.wzt +$ cd .. +$ cd .. +$ cd .. +$ cd .. +$ cd .. +$ cd lfrctthp +$ ls +168164 ccpnsjm.cwc +68428 dcmfjn +133121 dvlb +146217 sppmmj.zjm +dir thgh +dir zzffz +$ cd thgh +$ ls +dir nrntbh +dir qlhbf +$ cd nrntbh +$ ls +139964 lfrctthp.brp +$ cd .. +$ cd qlhbf +$ ls +115891 vsbvlr +$ cd .. +$ cd .. +$ cd zzffz +$ ls +170513 tlhttrgs.hsw +$ cd .. +$ cd .. +$ cd .. +$ cd zmlpwlm +$ ls +232644 wvjrtvps.hrb +$ cd .. +$ cd .. +$ cd .. +$ cd lfrctthp +$ ls +dir cwjbzd +dir dvlb +65658 fclf +191985 hhcp.jzd +dir lwqdqm +dir mpb +dir ndn +dir rtpwjds +185299 smp +dir sqhvvsb +dir vzh +dir zzvnq +$ cd cwjbzd +$ ls +172122 ccpnsjm.cwc +dir dfqpqqw +dir lfrctthp +123102 lfrctthp.cms +73991 lqhjcbms +207693 mcnwp +dir sppmmj +114128 tzrrgl +$ cd dfqpqqw +$ ls +67239 dgssm.crl +dir rjm +$ cd rjm +$ ls +25830 nnwdzf +$ cd .. +$ cd .. +$ cd lfrctthp +$ ls +dir fqswn +241343 jllwj.wjc +$ cd fqswn +$ ls +76154 ccpnsjm.cwc +dir dhgghnm +dir vpbwj +$ cd dhgghnm +$ ls +36757 jbmlssv.ndp +dir sppmmj +$ cd sppmmj +$ ls +dir dsss +$ cd dsss +$ ls +201519 vsbvlr +$ cd .. +$ cd .. +$ cd .. +$ cd vpbwj +$ ls +154042 ccpnsjm.cwc +dir tlhttrgs +271666 vsbvlr +$ cd tlhttrgs +$ ls +125785 cwjbzd.lqr +19315 jdcm.mrz +$ cd .. +$ cd .. +$ cd .. +$ cd .. +$ cd sppmmj +$ ls +dir sppmmj +$ cd sppmmj +$ ls +161387 fwh.wtt +$ cd .. +$ cd .. +$ cd .. +$ cd dvlb +$ ls +dir dnqvhtr +dir jqpzj +dir jvvsgbl +dir tlhttrgs +$ cd dnqvhtr +$ ls +dir jzm +dir phcfgqfs +dir sppmmj +dir vhrst +$ cd jzm +$ ls +143413 sgsbj.qtr +dir smtpdcpf +$ cd smtpdcpf +$ ls +95947 lgzlj +$ cd .. +$ cd .. +$ cd phcfgqfs +$ ls +257801 hhcp.jzd +$ cd .. +$ cd sppmmj +$ ls +230280 ccpnsjm.cwc +261954 hhcp.jzd +dir hmcn +dir mrhsrrm +dir nlqmghj +dir rqbtcvfw +70788 vsbvlr +114344 wbs.vmh +225265 wjnf.wrv +$ cd hmcn +$ ls +206476 dvlb +214973 lfrctthp +$ cd .. +$ cd mrhsrrm +$ ls +126589 wbs.vmh +$ cd .. +$ cd nlqmghj +$ ls +113621 mdqvh.flp +$ cd .. +$ cd rqbtcvfw +$ ls +259673 wbs.vmh +$ cd .. +$ cd .. +$ cd vhrst +$ ls +102273 sppmmj +$ cd .. +$ cd .. +$ cd jqpzj +$ ls +7675 vwls.wjz +$ cd .. +$ cd jvvsgbl +$ ls +217539 bgjgtfbv.wcf +dir fbvls +dir gtwrhhd +dir tlhttrgs +59720 wbs.vmh +$ cd fbvls +$ ls +146823 ccpnsjm.cwc +$ cd .. +$ cd gtwrhhd +$ ls +59762 wbs.vmh +$ cd .. +$ cd tlhttrgs +$ ls +7093 ccpnsjm.cwc +dir dvlb +dir hjclnb +$ cd dvlb +$ ls +62683 trww +$ cd .. +$ cd hjclnb +$ ls +245444 bcnlmstj.bsj +167166 czdm +$ cd .. +$ cd .. +$ cd .. +$ cd tlhttrgs +$ ls +53060 czdm +217177 hzwn +$ cd .. +$ cd .. +$ cd lwqdqm +$ ls +dir bdgnmf +dir dvlb +89596 vsbvlr +$ cd bdgnmf +$ ls +146880 wbs.vmh +$ cd .. +$ cd dvlb +$ ls +184438 vsbvlr +$ cd .. +$ cd .. +$ cd mpb +$ ls +dir dvlb +$ cd dvlb +$ ls +dir prqfqf +$ cd prqfqf +$ ls +dir ltmjppj +$ cd ltmjppj +$ ls +241963 bjgzsq.srr +$ cd .. +$ cd .. +$ cd .. +$ cd .. +$ cd ndn +$ ls +184702 cnv.vtn +52486 dvlb +dir hfq +52100 hswnvlq.frd +$ cd hfq +$ ls +dir bsjgglbs +263904 cwjbzd.sht +265639 phpvlfw.jmm +178105 wbs.vmh +25124 wcq.qct +$ cd bsjgglbs +$ ls +121761 czdm +$ cd .. +$ cd .. +$ cd .. +$ cd rtpwjds +$ ls +117111 qjvrwsfl +132235 rwjf +dir sdssvrst +223399 wjfdgt.ldj +$ cd sdssvrst +$ ls +114380 ccpnsjm.cwc +$ cd .. +$ cd .. +$ cd sqhvvsb +$ ls +7812 gjhj +239114 hhcp.jzd +dir ldmwm +230777 vsbvlr +$ cd ldmwm +$ ls +67855 blcbqb.wpz +dir cwjbzd +250365 czdm +249613 dvlb.mfq +dir jdsbt +95934 tlhttrgs.wgw +$ cd cwjbzd +$ ls +147822 cwjbzd.lff +122632 hhcp.jzd +dir llcflrds +dir tlhttrgs +67326 tvptb.fzl +dir wtcttdzg +$ cd llcflrds +$ ls +dir cngdgq +$ cd cngdgq +$ ls +235724 lqqcfphg +$ cd .. +$ cd .. +$ cd tlhttrgs +$ ls +dir cgf +67714 csb.hcw +dir cwjbzd +dir jvs +119180 lfrctthp.qgm +dir ppsmqwn +dir qqmtj +dir qzmpwzvz +dir zmsbqrqf +$ cd cgf +$ ls +dir dvlb +$ cd dvlb +$ ls +77864 thff +$ cd .. +$ cd .. +$ cd cwjbzd +$ ls +208459 ccpnsjm.cwc +17127 dtqglmf.zgb +$ cd .. +$ cd jvs +$ ls +142337 cwjbzd +$ cd .. +$ cd ppsmqwn +$ ls +147277 rmwh +$ cd .. +$ cd qqmtj +$ ls +153442 vqld.lsd +$ cd .. +$ cd qzmpwzvz +$ ls +223666 cwjbzd.gjl +254370 gjc +$ cd .. +$ cd zmsbqrqf +$ ls +193665 tjwclf.nzs +$ cd .. +$ cd .. +$ cd wtcttdzg +$ ls +52882 hhcp.jzd +110104 hqwgl.mtb +$ cd .. +$ cd .. +$ cd jdsbt +$ ls +77115 ccpnsjm.cwc +242705 dvlb +12624 lfrctthp +145552 sppmmj +198997 vsbvlr +$ cd .. +$ cd .. +$ cd .. +$ cd vzh +$ ls +dir ccbjg +91733 czdm +89195 dvlb +212167 rvfpbl.rtq +224909 tlhttrgs.djt +72916 vpznzhs.dcd +$ cd ccbjg +$ ls +dir mcvsbd +dir sppmmj +$ cd mcvsbd +$ ls +dir cwjbzd +dir rbsv +$ cd cwjbzd +$ ls +224826 ccpnsjm.cwc +$ cd .. +$ cd rbsv +$ ls +164816 lfrctthp +$ cd .. +$ cd .. +$ cd sppmmj +$ ls +85264 ccpnsjm.cwc +104511 dvlb.qgj +183533 lfrctthp.zdn +98525 wbs.vmh +$ cd .. +$ cd .. +$ cd .. +$ cd zzvnq +$ ls +107390 lfrctthp +dir lznpqbrd +dir pddfg +143496 prnjh.sgb +dir pvdz +dir vnmhs +118674 zhnh.mpl +$ cd lznpqbrd +$ ls +157950 dpvcgj.wlw +dir dvlb +175412 dvlb.qvr +dir lfrctthp +84587 pmsjdj +$ cd dvlb +$ ls +41223 rwr.nbz +$ cd .. +$ cd lfrctthp +$ ls +26056 fqc.fnl +28191 lgjlw.vql +dir sppmmj +262066 wbs.vmh +$ cd sppmmj +$ ls +246742 ccpnsjm.cwc +$ cd .. +$ cd .. +$ cd .. +$ cd pddfg +$ ls +dir cwjbzd +dir jbw +147410 vsbvlr +$ cd cwjbzd +$ ls +197956 jpzb.dcw +$ cd .. +$ cd jbw +$ ls +247206 vsbvlr +$ cd .. +$ cd .. +$ cd pvdz +$ ls +dir jctpqbgw +153177 qwcgjttm.lzm +94686 vsbvlr +$ cd jctpqbgw +$ ls +190424 qvm +$ cd .. +$ cd .. +$ cd vnmhs +$ ls +16118 sdhmzhlg.blf +$ cd .. +$ cd .. +$ cd .. +$ cd ltwmz +$ ls +243152 bdmz +$ cd .. +$ cd nmzntmcf +$ ls +dir jqcms +dir lrtsts +dir lvchpdf +dir qpzqp +dir qrgh +dir scwnmrds +$ cd jqcms +$ ls +105562 ccpnsjm.cwc +257512 chpr.zvl +dir cwjbzd +dir jzqbnpn +dir ssr +117496 tlhttrgs.thg +72550 vsbvlr +$ cd cwjbzd +$ ls +dir mwvlhzdn +dir qrpllg +205638 sppmmj.gcz +$ cd mwvlhzdn +$ ls +272658 dvlb.bbw +$ cd .. +$ cd qrpllg +$ ls +215810 wbs.vmh +$ cd .. +$ cd .. +$ cd jzqbnpn +$ ls +112583 sppmmj +$ cd .. +$ cd ssr +$ ls +66781 hpfpw.pvn +138840 zhwplzd.wrq +$ cd .. +$ cd .. +$ cd lrtsts +$ ls +dir drtrdnsg +41195 dvlb.fgt +dir lfrctthp +$ cd drtrdnsg +$ ls +dir gnc +dir sppmmj +$ cd gnc +$ ls +127922 ccpnsjm.cwc +233097 lfrctthp +24075 qtglzq +$ cd .. +$ cd sppmmj +$ ls +128955 czdm +64809 jtjh.nzq +dir mdmh +dir nbzh +126095 wbs.vmh +dir wwhbgg +$ cd mdmh +$ ls +dir zvtjfz +$ cd zvtjfz +$ ls +142470 ptp.qbf +$ cd .. +$ cd .. +$ cd nbzh +$ ls +7112 ccpnsjm.cwc +215395 chrtbjf.fwr +145865 wld.pdl +$ cd .. +$ cd wwhbgg +$ ls +51752 hhcp.jzd +$ cd .. +$ cd .. +$ cd .. +$ cd lfrctthp +$ ls +198780 hhcp.jzd +$ cd .. +$ cd .. +$ cd lvchpdf +$ ls +108580 hhcp.jzd +105301 jpjjhshl +dir njfmmj +dir nsw +dir sppmmj +dir tlhttrgs +dir tvsvr +$ cd njfmmj +$ ls +dir bjsvdfrf +dir gjgftj +dir sppmmj +25879 twzprtcf.hgl +$ cd bjsvdfrf +$ ls +77668 vsbvlr +$ cd .. +$ cd gjgftj +$ ls +dir mjbw +56593 vsbvlr +$ cd mjbw +$ ls +243595 ccpnsjm.cwc +$ cd .. +$ cd .. +$ cd sppmmj +$ ls +dir qzvwhr +$ cd qzvwhr +$ ls +dir cwjbzd +$ cd cwjbzd +$ ls +262825 wbs.vmh +$ cd .. +$ cd .. +$ cd .. +$ cd .. +$ cd nsw +$ ls +210254 rgqpq +$ cd .. +$ cd sppmmj +$ ls +55463 cwjbzd.dtt +196779 dvlb +125377 hgb.qmj +dir rdd +dir tlhttrgs +222280 tspz +dir zbq +$ cd rdd +$ ls +20045 srmsmr +$ cd .. +$ cd tlhttrgs +$ ls +47256 wbs.vmh +$ cd .. +$ cd zbq +$ ls +223951 cwjbzd.vrm +$ cd .. +$ cd .. +$ cd tlhttrgs +$ ls +56808 jvndrcmd.ftl +dir mjcmhg +220385 prh.wtz +231575 pzbtlg.fzv +11100 sqfr.lzs +dir tlhttrgs +$ cd mjcmhg +$ ls +214188 llsfnv.dmc +$ cd .. +$ cd tlhttrgs +$ ls +dir qtws +dir sbhswjld +$ cd qtws +$ ls +102462 vjlwzbsg.whn +$ cd .. +$ cd sbhswjld +$ ls +159193 dvlb.bqj +17424 hhcp.jzd +28945 pdwrmgs.lzq +38201 rpbllgs.rzn +dir sppmmj +$ cd sppmmj +$ ls +88100 wbs.vmh +$ cd .. +$ cd .. +$ cd .. +$ cd .. +$ cd tvsvr +$ ls +237626 tlhttrgs.mhw +$ cd .. +$ cd .. +$ cd qpzqp +$ ls +dir ddclns +134373 lfrctthp +167788 lstwpqbq.wln +224743 qcplm +14385 vzjj.bzm +108204 wbs.vmh +$ cd ddclns +$ ls +dir vprlq +$ cd vprlq +$ ls +137784 ccpnsjm.cwc +$ cd .. +$ cd .. +$ cd .. +$ cd qrgh +$ ls +29875 ccpnsjm.cwc +225323 hhcp.jzd +135470 tlhttrgs +23724 vsbvlr +$ cd .. +$ cd scwnmrds +$ ls +dir sppmmj +$ cd sppmmj +$ ls +dir sppmmj +$ cd sppmmj +$ ls +73173 blznf.smd +$ cd .. +$ cd .. +$ cd .. +$ cd .. +$ cd vhj +$ ls +221377 cwjbzd.tvv +98748 czdm +108605 hhcp.jzd +dir jnm +dir lfrctthp +11518 lfrctthp.jfl +89038 psnfcwpq.zcd +dir tlhttrgs +$ cd jnm +$ ls +66785 bfwm +196636 dssh.rwn +dir sppmmj +140177 tlhttrgs.jlh +199730 vsbvlr +$ cd sppmmj +$ ls +101586 ccpnsjm.cwc +dir lfrctthp +127582 vsbvlr +71001 zvrzs +$ cd lfrctthp +$ ls +122902 lfrctthp +247157 svmpmrl.tcc +$ cd .. +$ cd .. +$ cd .. +$ cd lfrctthp +$ ls +104555 cwjbzd.hbf +56298 pldmc.hjd +27639 sppmmj.nmr +$ cd .. +$ cd tlhttrgs +$ ls +252680 zsjgqqb \ No newline at end of file diff --git a/adventOfCode/2022/8.go b/adventOfCode/2022/8.go new file mode 100644 index 0000000..8839652 --- /dev/null +++ b/adventOfCode/2022/8.go @@ -0,0 +1,154 @@ +// Day 8 +package main + +import ( + //"fmt" + "strconv" + "errors" +) + +func solve8(input []interface{}) (interface{},interface{}) { + + var day8Inputs [][]int + visibleMat := [][]int{} + + // Customize input + for _, val := range input { + // validate input + line, ok := val.(string) + if !ok { panic(errors.New("type cast failed for input")) } + + // init + row := []int{} + visible_row := []int{} + + // populate the ds + for i, l := range line { + // visible trees + if len(day8Inputs) == 0 || len(day8Inputs) == len(input)-1 { + visible_row = append(visible_row, 1) + } else if i == 0 || i == len(line)-1 { + visible_row = append(visible_row, 1) + } else { + visible_row = append(visible_row, 0) + } + // add heights + charac := string(l) + integer, err := strconv.Atoi(charac) + if err != nil { panic(err) } + row = append(row, integer) + } + + visibleMat = append(visibleMat, visible_row) + day8Inputs = append(day8Inputs, row) + } + + // Solution 1 + sol1 := 0 + + for i:=0;i tallTreeFromLeft { + treeVisible = true + tallTreeFromLeft = day8Inputs[i][j] + } + if visibleMat[i][j] == 1 { + continue + } + if treeVisible { + visibleMat[i][j] = 1 + } + } + // right to left + tallTreeFromRight := 0 + for j:=len(day8Inputs[0])-1;j>=0;j-- { + treeVisible := false + if day8Inputs[i][j] > tallTreeFromRight { + treeVisible = true + tallTreeFromRight = day8Inputs[i][j] + } + if visibleMat[i][j] == 1 { + continue + } + if treeVisible { + visibleMat[i][j] = 1 + } + } + // top to bottom + tallTreeFromUp := 0 + for j:=0;j tallTreeFromUp { + treeVisible = true + tallTreeFromUp = day8Inputs[j][i] + } + if visibleMat[j][i] == 1 { + continue + } + if treeVisible { + visibleMat[j][i] = 1 + } + } + // bottom to top + tallTreeFromDown := 0 + for j:=len(day8Inputs[0])-1;j>=0;j-- { + treeVisible := false + if day8Inputs[j][i] > tallTreeFromDown { + treeVisible = true + tallTreeFromDown = day8Inputs[j][i] + } + if visibleMat[j][i] == 1 { + continue + } + if treeVisible { + visibleMat[j][i] = 1 + } + } + } + for i:=0;i= day8Inputs[i][j] { + view++ + } + //fmt.Println("->",x,y,view) + scenic_score *= view + } + //fmt.Println(i,j,scenic_score) + if scenic_score > sol2 { + sol2 = scenic_score + } + } + } + + return sol1, sol2 +} + +func withinRangeMat(x int, y int, matrix [][]int) bool { + if x < 0 || y < 0 || x >= len(matrix) || y >= len(matrix[0]) { + return false + } + return true +} \ No newline at end of file diff --git a/adventOfCode/2022/8/8-sample.input b/adventOfCode/2022/8/8-sample.input new file mode 100644 index 0000000..6557024 --- /dev/null +++ b/adventOfCode/2022/8/8-sample.input @@ -0,0 +1,5 @@ +30373 +25512 +65332 +33549 +35390 \ No newline at end of file diff --git a/adventOfCode/2022/8/8.input b/adventOfCode/2022/8/8.input new file mode 100644 index 0000000..1e766a0 --- /dev/null +++ b/adventOfCode/2022/8/8.input @@ -0,0 +1,99 @@ +113003322412033102023303501444545044215232525401341546163452453404402234201151432242402140110220101 +332001304022012142421445502213221330453061535265122314201352335233021055055200345412200440033322200 +011113132214324432134325045311145402450516101640412524056254134552334050434552541351100000142223210 +120100233011423423144030334144351644642605521663331053414601341464201040045104150001214204243212330 +032313022420343002352401031112122630544621450306410014210122655033613410314450242104133332033433110 +330133431221024552500405304311611205251454505525065601244143364343441153320511500334525320443331122 +232021314224321045040222145130205324423110304256225426345644345334310200416004113133521143332200422 +312322022143422250013255366221252062135020112327134227764002156152041134323314242255102200014240004 +212411010402324310541162616440606266620317315234166112525535542054554446314636025435501101142314410 +130420010020500305012262532345565125253527765422533261626735742433241362062404452514044512024131310 +241211034142224054050344306633445512263575724527746635663111434536510100261040501431453540340134211 +241313213114241230212646636605641533121654131662127125143714342377771455431346140255405303533314030 +200214302143123545226333105604234323144236661442633717414531213335635263423430225510502553055320124 +432210433113545424321340236152364457166745737761176472274142327714574465315263302246430530531052340 +044321111115013046066155407144655275272121513224325736736453741437462322257332111603344504052313220 +423214232334431334032453034121465736632235428586864276787383246667147623517713521254056250023050122 +341124205512002021001520535463145337475482376656634323542842654415315313467514115356311404235042224 +132001402100660310301501776141144746672773424257875288227677277663442356545463514004411150412531212 +001052001350350313612735275534436625275423778573334245773528222523563225127612470242660400232440014 +000112513501320042013743116251356437388536835723273464367352632733656224242323651012010230151310024 +432343513243516355144362617334462875826626872624526547773732534284688857151541627654520220114445210 +030155000415201011165562424113226826748747748853864385358746645352362468546644524342115335322112153 +521354124325146425431532157187775456325686557739354768338786565328828884835715454276200630310531024 +453541003326165663116714725533384334462564846638857736639973473868246353547315725644665433532024310 +550412430051564655211263423273445384473677893666497965987545884578247877687261326676604334421513240 +413054444206603631433161684337566624388758573363447988796769799695582635658423643315241325425634024 +215150330040102563666211553675525355868889739969438648979533595459347577832874756321426443250541325 +421424650534663421741533522275548697677937396576933765698789956783468276533784535453223333266121254 +422144151564541614312463257866683347483647399747895987469373443743399762878755625665635533442122100 +142126413036631514413457664863683937946499766465555784756389698779343558673226534437441452602242233 +305201320636671251145832252388563746733774564949748445664654449965453936743822654651524764154313443 +011300622102111771164477857675385967936859964787497949987577437799784855267278677674646432241223234 +340321113267666756754785648366853336456946997569954774746449465943647534953257556352535151305025463 +541411012547643576586448655984493857478575997945994447954587596973768677885376565465523461502535643 +444321100654632152854364424757747839747855469574958798776977549543479354379242483435267721134026240 +020626205154575316847673866764644374748789977457499575788744688854499953995222366237635424744520350 +335506510045711628565868794334457797677874456886875779795697459467453749364727248672726163736041204 +500111603536263112863778287468558998649869948858895979757648556554566675849574438477347434571054505 +122000100243546685578334388934875844674864976796788677978555975645687865954363424837536471770452415 +141414215752566148738527647673948945657599775586897776875597686768689334698832463748744764733053124 +100340653262173232623746876388947885855898958859977856795865855466954797947557362275815142426540331 +466303032723142355554844869739456445889568997967558595977567767954454556686589744843263767635404425 +004613266772514623473428884775998765955988667675865595697667595999549844548767382824562175546612214 +223062321176322437826876799485789855749797897795766857786556556466469876653886288833557467773301562 +413332261232125275243773533956777794896856665777776697967896558687464977634963578724434267752313063 +552404621241274462672869963657657685959857786696669988675856559577744587934439473355436162566631240 +435165353647675322378767844955594694568958979668688889986755769858696479453833942343873533447232052 +244432367557727222376845574654778567657966566799677789797957677969848457379553465846862364131450331 +500160365677454526747395979487899988575755756767767688698968968964795455975647975338665645777505164 +102431235675118652565457756594548744578555576979976998997755878856465958937486343448585657465615526 +246165542416756587676444776898888956766578897997878779867867799995588485976853457557557151277215635 +001643325345324464653748985776747945569696578767779897778688898756644945899654857626437342132540232 +012101664761176266736346897839595848575598988867686699987969655574844656549763626542283366457311330 +561504075335422826822483989945889874569866596668697889889787698578564685356683642368537236162426203 +352203514134651772748288733934776699589795768989986896977876655856647995457449532883535245357460413 +033642404423741338448747543456567587875878659898696769778857567974989696766857638532623516361132200 +616444206117715325587799743549596679896878996579778797758659755584898985549986338256726477267555103 +520455143625244274365846334377848464679657799659996799959789655886895549885388585227864441542440633 +301346217675555884462648646383444656479799855995796958569776779656497648598636775768426556776465212 +520404231326621664428744458384498945886755796967559979558788575647874897993564426835362551773515204 +316242511662326327222423774658467889697656957595795766869586965778777639684376585246752671616104436 +415146426112762185773325386754349955694758878879858887885879799994465943455896555866711732413133541 +355625411617227324663526785865944884474696755859788678978799585984575877863878686426651623174052622 +250022125746424524625262754995697689898769757895898887999798967686567449959582647242127737515510342 +525264040416627662865878845844435466984695749789657699584976867495646849545456285287242646554654353 +036123646424431555263267827839763498876769495677697448449595455554764947373454763645727333510646146 +204566364235641316654753765445963394466448895664985649465498769864394998376778764453573662441355520 +220335031661255773663868585338574847865979585777445874888879656858779783486746544464161776603563641 +222513656331342447187422756294679343838685457555849784967456454674489536467765228571211235451313300 +420041535613636672654268683685394696895377789594449696975655499485443388622338663537334646443120355 +525056224212611227113776876877874646779895859895448998785578796984395868862632743546145340000633644 +404314430546135313471247434875543567783736878545548779967377554684776373253726223752325712616213051 +353422360566111142127744587245868774578548754579967945935667489466386244448265471714226610251556141 +240135510612042471674334266253242658953336636546539684393847584358732442564537232411555541300234143 +555204024234655515726125842362866243634643845579964798949797638778425653264527614711662106606433551 +203524350135524444622315434263233285368993457879757738399643368354787234632745135155274525361620440 +340532455653452155645722264385685523579545388464998647475936784423755683487133452753535123313604354 +352152244221611331745526617386458872637865488449639856654753583624523335337272114515341203461045505 +312033003454166053225452625154365544367483828667456379835556776344278883841652574422331646601235245 +354330514213011046317425234714582372762675574834484437275552425744868747672133251365644033361512332 +044021444522010141412515121117476227878457643873272338756238823637528547351444752605411146631314215 +232413442230001100251223172352214643455635846823657522575345326788747411734266577565251164231145220 +131504320306315625216346311325345143883224276853882277427888248757813625336722630560555630113015013 +024451223151264563630623162617513241445834482436236846786748364751551471325535132540104323422105400 +124420553125506323053405346614111134556285246233525828237347884315614217572766434350535521515101401 +130200351112000250166105345316513263244676855323883356633222244252121772667652426014110503513555221 +400241412230012102424516231766252561312255446621244373337355416351623124213640652213520151043110444 +322440423504102454033133351036544434155137522762124773455775324625526553424524313460144053442544330 +324303335402501236440552111053234114555641277255456252443511634243752643304353256666504353255522122 +241434204225354100532033205000145461776516534477176114531271372735543451231303326454043352113013420 +334124213300015522546105345511323376357312632521613774424256342133105114520414061451141133554301031 +211304431150451251125020043053260563634374764226536222654742522421115640025331113215553523303422011 +123324243323523142132445503461621106650437431517676417742653314226115466013230223030345414021112341 +100121244242050431353422620202033056213213561562676642451361622463016135301034322504250003434240420 +202331344430130314251310046312513630614136423111235233115234253411664210435541154434125202004300041 +311142442400021052335032430131001522121243633355511015105456130306054020525345400331240114301233431 +303333210333101445104545232532514231420245342044224564606555504302423403203123103211431303412444103 +322112022033322224210512330414230625446520203533135512231066520423212314402311345154232414213413203 +210220340333424334214524143431005502542403323230305103516410534415015522312221415410344021130000212 \ No newline at end of file diff --git a/adventOfCode/2022/9.go b/adventOfCode/2022/9.go new file mode 100644 index 0000000..9251023 --- /dev/null +++ b/adventOfCode/2022/9.go @@ -0,0 +1,320 @@ +// Day 9 +package main + +import ( + "fmt" + "strconv" + "strings" +) + +func printMat(mat [][]string) { + fmt.Print("\n") + for _, n := range mat { + fmt.Println(n) + } +} + +func genRow(num int) []string { + v := []string{} + for i:=0;i read inputs --> execute the solution --> print result + +import ( + ioutil "io/ioutil" + "strconv" + "strings" + "fmt" +) + +func main() { + dayChallenges := map[int]func(input []interface{})(interface{},interface{}) { + 1: solve1, + 2: solve2, + 3: solve3, + 4: solve4, + 5: solve5, + 6: solve6, + 7: solve7, + 8: solve8, + } + // Iterate day inputs + for day, fun := range dayChallenges { + folderName := strconv.Itoa(day) + inputFiles := []string{folderName+"-sample" + ".input", folderName + ".input"} + for _, f := range inputFiles { + var inputs []interface{} + body, err := ioutil.ReadFile(folderName + "/" + f) + if err != nil { panic(err) } + input_strs := strings.Split(string(body), "\n") + for _, val := range input_strs { + inputs = append(inputs, val) + } + if strings.Contains(f, "sample") { + fmt.Print("[Samples] Day " + folderName + ":") + } else { + fmt.Print("[Problem] Day " + folderName + ":") + } + fmt.Println(fun(inputs)) + } + } +} \ No newline at end of file diff --git a/adventOfCode/2022/go.mod b/adventOfCode/2022/go.mod new file mode 100644 index 0000000..1225d56 --- /dev/null +++ b/adventOfCode/2022/go.mod @@ -0,0 +1,8 @@ +module main + +go 1.18 + +require ( + github.com/deckarep/golang-set v1.8.0 // indirect + github.com/deckarep/golang-set/v2 v2.1.0 // indirect +) diff --git a/adventOfCode/2022/go.sum b/adventOfCode/2022/go.sum new file mode 100644 index 0000000..aca6e4d --- /dev/null +++ b/adventOfCode/2022/go.sum @@ -0,0 +1,4 @@ +github.com/deckarep/golang-set v1.8.0 h1:sk9/l/KqpunDwP7pSjUg0keiOOLEnOBHzykLrsPppp4= +github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo= +github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6dtGktsI= +github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= diff --git a/adventOfCode/2022/template.txt b/adventOfCode/2022/template.txt new file mode 100644 index 0000000..a0f7730 --- /dev/null +++ b/adventOfCode/2022/template.txt @@ -0,0 +1,27 @@ +// Day +package main + +import ( + //"fmt" + "strconv" +) + +func solve(input []interface{}) (interface{},interface{}) { + + var dayInputs []int + + // Customize input + for _, val := range input { + integer, err := strconv.Atoi(val.(string)) + if err != nil { panic(err) } + dayInputs = append(dayInputs, integer) + } + + // Solution 1 + sol1 := 0 + + // Solution 2 + sol2 := 0 + + return sol1, sol2 +} \ No newline at end of file diff --git a/adventOfCode/2023/1.go b/adventOfCode/2023/1.go new file mode 100644 index 0000000..4091dc8 --- /dev/null +++ b/adventOfCode/2023/1.go @@ -0,0 +1,131 @@ +// Day 1 +package main + +import ( + "errors" + "strconv" + "strings" + "unicode" +) + +func reverseWord(word string) string { + r := len(word) - 1 + rev := make([]string, len(word)) + for r >= 0 { + rev = append(rev, string(word[r])) + r-- + } + return strings.Join(rev, "") +} + +func d2GetNum(word string, prefixes map[string][]int, words map[string]int) int { + n := len(word) + if n == 0 { + return -1 + } + lengths, ok := prefixes[string(word[0])] + if !ok { + return -1 + } + for _, l := range lengths { + if l > n { + break + } + num, ok := words[word[:l]] + if ok { + return num + } + } + return -1 +} + +func solve1(input []interface{}) (interface{}, interface{}) { + + var day1Inputs []string + + // Customize input + for _, val := range input { + typeVal, ok := val.(string) + if !ok { + panic(errors.New("typecast failed")) + } + day1Inputs = append(day1Inputs, typeVal) + } + + // Solution 1 + sol1 := 0 + for _, testStr := range day1Inputs { + var first, last string + for _, testChr := range testStr { + if unicode.IsDigit(testChr) { + first = string(testChr) + break + } + } + n := len(testStr) - 1 + for n >= 0 { + testChr := rune(testStr[n]) + if unicode.IsDigit(testChr) { + last = string(testChr) + break + } + n-- + } + totalInt, err := strconv.Atoi(first + last) + if err != nil { + return 0, 0 + } + sol1 += totalInt + } + + // Solution 2 + sol2 := 0 + worded_nums := map[string]int{ + "one": 1, + "two": 2, + "three": 3, + "four": 4, + "five": 5, + "six": 6, + "seven": 7, + "eight": 8, + "nine": 9, + } + prefixes := map[string][]int{ + "o": []int{3}, + "t": []int{3, 5}, + "f": []int{4}, + "s": []int{3, 5}, + "e": []int{5}, + "n": []int{4}, + } + for _, word := range day1Inputs { + var first, last int + for i, testChr := range word { + if unicode.IsDigit(testChr) { + first = int(testChr) - '0' + break + } + first = d2GetNum(word[i:], prefixes, worded_nums) + if first != -1 { + break + } + } + n := len(word) - 1 + for n >= 0 { + testChr := rune(word[n]) + if unicode.IsDigit(testChr) { + last = int(testChr) - '0' + break + } + last = d2GetNum(word[n:], prefixes, worded_nums) + if last != -1 { + break + } + n-- + } + sol2 += (first * 10) + last + } + + return sol1, sol2 +} diff --git a/adventOfCode/2023/1/1-sample.input b/adventOfCode/2023/1/1-sample.input new file mode 100644 index 0000000..db5d9c6 --- /dev/null +++ b/adventOfCode/2023/1/1-sample.input @@ -0,0 +1,7 @@ +two1abc2nine +eightwopqr3stu8vwxthree +a1bone2c3d4e5fourthree +xtwone3four +4nineeightseven2 +zoneight234 +7pqrstsixteen \ No newline at end of file diff --git a/adventOfCode/2023/1/1.input b/adventOfCode/2023/1/1.input new file mode 100644 index 0000000..51cba08 --- /dev/null +++ b/adventOfCode/2023/1/1.input @@ -0,0 +1,1000 @@ +heightseven4two5 +npskfdstpk2knsm +djnrmpxjbsbpgzvtjkhq6pkkfshx +kgsddxsevensevenlcmkdlcgtfbqxmlnkhbnvhshkckppn2 +8blvspztqjnine854fivefour +ninesixthree8six8 +5tnzrrzmcsnfivefeightrjninexrhnnfbcb +dcjcj2 +4fhcmhdtfourlzdphfxvlmvm6 +eighth33twobfr +qnb2sdsfhgxmfqqzkkjmfbxzjeight +seven4zzsmcqtwo +fourthreeone1two +kkncfbsrfdsix9rvfpjrdxbgcssmkztwo +959eight3two +sixpmvlkkdjf3frr91 +five3xhpsdfkg94two3six +bgqqglhqqtwohhqpgqjvqj8 +23seven +kkddrrtskfive75pcmhhxcxzfourthree8 +smtfgqg7foureight +281 +eighttxqtfjrldgxdpgkblzt3three +zjznfive4 +5hpxksxc +dvrkfvgvtwosnlqqcfivesixstglhvgfhlrgczzgvkvfour3 +sixllkhdpdxfvhqcbgz24two +drc79twotwofive +2vccthreefive6sevenrzqprfflnlsjtb +3four3fjqm7lntttphvs +threerzshdfgs4seventwolpb +9threehmbt5 +9plgm +17bjhndv3one2 +jghtqonesix3 +1kzdfjeightonesixtwothree44 +jpzs23gvjvsztbcvthree +v5hmkncqvtqxvtwotwofiveeighttqmbk +oner9kmfrjdbxcffl +bmnpn9n +3dsrcnssfgn +psstwonesevenfvctwo9vnbxflpntcdllpzpkgtwo9one +rkmbh8 +two1twokmkr +sixfour9xsmpzzseightvqn +threemmbrfxlqjtjgx95r9six +seveneightpthree91nine +twoeightfive7rdqqs4 +5threesevenhdjnrseven6five +45nineeightnvoneeight71 +hrprrsg6eightrmthree7xnkmdcdqm +cgfrgmflvthree38grksbjnpfhqpnvctrmtshffivemkzqmlfn +227 +79onethreervsjtpkkr +229twoonedcvz +8ltnnqmtn7threetdfxd3 +3358pvbtbonekpbcvbcrrz +fourrpkmtvvqfgsmxktqhvhb1mnbjj +91xmzmzfbt +vseven9 +6four2 +32q2 +bneightwo6eightsevenxl3 +two8jhbchqncbmsvfhznbvqmpxr931lnt +cvlbktjmsevensix9eightfsixthree +fivethree8sevenone +prqr1krjgkllqrdmjbdjnvvc +six4hspnpbgfivefour9fourxlsf +zhxsncl77321 +dlslthree1sevenkrrlnbzggtwofourtwo +rqtjzv2lqt7dfxcvfshtwo +31oneqrnnzbbjfthreesix9nhnpqmnbnx +sfhlrqt5649eight +sevenjzlxthree6kndrfvtwo8zjzfspgtr +2f +4bmzvbpkfmtwo946 +eight8qkpxm33ljprdctmghfrt +three643sevensixfour82 +vkdcnhhlhltsn6 +2sixsix264oneightm +6rbx9threetwothree +hhvtjlxgjpqbzzdcfpnhvncbqf94 +nine98 +jknmeight9seventhreemhdxddhfive8 +qljrvrprxthree1fiveeightwoj +bjtntqlhk3mhjqmd5twolqrjtsixfour +fdqddhxvone1twogjpqclnpjqxjpk8 +4cffzxeightfmbzfourn5 +56947cthvktgff +ztbhdtmxtrbr1ssxmzbvhfiveeightwox +two1phrvdx +16vvrs1szzk9 +67rhvtzvzvseventx7 +2kjnmseven8 +tonenine9nine +threeeightseven93jttxgtdml2threeflclh +2hxsdksfmdshxcdmxlb +seven9threeqslknninelfgmrsfjjjpklbh +3twosevensevenfourcgsmbn7hr +threevjvldjvstn2sixonevcljlf +17cninepqgjp +rjrnlknfivelscqfhhfv75 +five7hzvvh +31two3seveneighteightfour +78seven +threesixmzsldcxpjnvrkptwothreenine5f +trrxdhp8cqmfivexx7 +tgppgp9 +7five7grcdhsz5seven +31eight +nptmpmghrhsktcjthtonek15 +xgghqkqqqsdxgjzz7 +vsix1sbthreeonesix4eightwox +gqcvhpdvl5onejmlrlljrf +pdgmnmcptwo4 +dnzfgpbjxkkshgrg9qk +fourcrnntcxrhvnlsixbfhvvdncfdeight6 +84krfhzg1onesixhzgpxgmfivedkjqxnf +threembvltrgmgpp795xdtzsixtwo +nlcn8 +76ptqpzkllmvrpthreefour7 +nrfourxjqxkgqj6126gjrplj +tx685 +1fivesixgtlnine29fourmjgjgg +5vzx +86five +qjhgkzmplgql1jppdxmhx2zsbvnxlj9rbxvzsxnj +7pkgpzmfqr +two58eight9 +fcjnpsxthreef1pzgkxqhbfgvjzsix +4s95czbmjsbgvcztqncdk +72zczgsix2twomxpgxfour6 +nine7kfq +nlqcsrdcbkxsrgktbxch5zdjjkkz4fvk +34rhkrpfdpcrqmvrpltrssix +seven6mgdjmk3htqjlqbpbbfftt +3drdclclnsh1srjkshrc8fiveqtssmbdqbvtcbqzxx +4mdzjqnrjdj +gctoneight7fourbqhb3 +sixtjkrxjnj7threethreesixlbvpmf8 +9fourone4qzjzzzlhhljjqtfourhdjkqnt +dpdpxgxndx7eightthree7eightfivexdllmmm +nine6cnvftrddnnineqc1 +8thtdllhzv +qjgoneightgcmltsqcxrninevqxtfgbrp6 +xbxcl3glqgj +one7fivefour4 +fourlsfmgm7jr76 +5vszbtzdzhxmgrgjtt1qrczseven +eight67 +1jk96three5 +54ftvrpgzz3 +four4gnine +fbljngxt8threeqbttzsnnineninethreexdzggvjd +rmsix29fsfbmjjptf32 +x49 +5eightsndntqhhgg +pnlv9svhnskn1npbjxmsixtwo +eightzdvrjf4six9 +1sevennnkcdzcrthree8mz +eightrtgrfrnqninehbhllsdpqthreefourqk6eight +onefxtkztwonineninecfnf4 +threegf3jx +sphgjnpv51twoone +four89rhng +eightsix1threebfprrbzv +9sixfourlmnvgmnmkeightwoc +qrhsnjgndl7 +twoqqglxqbsix1nine1sgstftqjcmzp +9fivemqbjznffxq +lngzjghbbqmrsix5x +89ksqrbdpxfive7 +slbhmrvsstwo1gqcxztgdktqqxzmkpqfqfffgnhzfc +two4sixvtwo6x +oneonefive4 +twofourtfcqzptworq2nine +7pl71three3nclhsjcds +nlptvmgqfourfive7 +nsnzlcktmpcddcpffour3 +dtoneight5gxqbzbbvxc6gpplfzgmkbvmdnlhmg +zdcxqcnfive6gsqqvqfnine58 +fiveblnlvzkgjhbhfgqp6nine5kh +5onegbcdv51fxggdgthreedbbrlkg3 +29twobjpnjddone +seven9nvdndhdfourzhvqzctznqfour +3ztwosixcmbbztbngnsix9ts +8sixpxjcxv7zvf +onedsxmrhflvlqkzjjls8pmtcpteightfoureightvx +8fourfour +dpkhhvkxmttlk33 +three7txlxkdgcxglcb +5xzgxfgkqninecrkbzcfive3 +81fhfhpvxtnine2tfptjkthree +two2twosixgjfour +ncjdrcnptrtwovhzfive9threebmtttcznr +3xgnklgnnhbqgt4fiveghgksglkhlxm1 +five335five +threeninefourlqrgkcdlzfive5 +fiveseven89four8 +seven86spzkbt6mvq +3sevenseven +jm66b +eightqbttxcfzx88cnqjjdrhvcjzvfbdnzmrmvqbvhrlcm +ckmzsdhxqdrdntfivenqt36 +2hjb +twoone5two22mfmf +5rmfznvcjhhtccnkpmtwoone4 +478dckhsmpkmktgznjqfd +5gdqbjvdxv1threefoureighttwo7 +one646sevenmdmzzks +ndc1bxxdnqrnqntbvfxtqm6one +3vcsrrcfknmrgone +onexkxhbjkjn7eightfourqxtsixnine +sevenfive2seven327bdspzbv +fiveseven4xgpbb7four +ztjzhgsrm2seven +1twovslqxxvjxlprtbdjccscdtlngm4bxxhdhj +8rcn +ninelcqrtfbjxlvfourmeight54 +99466bbctwotwo +4twosixhpbhckdsevensix +4qmqrjsznine6 +189jninecxcmtpcx9 +rfbmtwo5gctcrqgthree +mcmpthree3nvmfshmjbtkgqsnine +np2 +four1fourjsghqgmfmrnzfxbh5fourfour7 +kvskplbpgfninesixvzkrv1fqnrjnrhvnpkpkhph27twonemvx +lghhsz175583 +onefive15rvsms4 +22twothreeeight +fkhsfjtqppgrckfiverfsrbggteight48eight +onem1two +nine2fourfour7mfourfourcpnvgcx +1czphscxrfrhqnqgn8 +ghgphgjrfcthreevpjdsevenseven8 +2gzcsdr2four5 +5eight5 +rzgsfive9lgbsqhsbxr +eightone5g +7six5 +63nine +7fivetwo9eighttbvmdb4jskprq7 +6pmgtckvz7 +nine49seven9gzppzm5 +7xqgxgxvqptwo81tlzzrchqxfq +two393 +pznknine67 +onenine514threeeight +mxbkksjfkrsevenc2dtzzfsnqhc1ctjthree +ntgmnhtwofourtwovbgmdnthree2pxv +sixnineonetwoone7rrqfive +vbz95two5zdxgtvnvrtmklt +vhdv7pcn4seven5one +zjqrxmm1ninefiveeight3spghctcttwogcqtrln +1fourthree8ntvlhmxvbbtwozlgjt19 +mg7csnjptsnzsix +4eightthreenineqtwothree13 +782mjrfmdf22sfive +bxfx7six4 +7three2dmmkz691 +sjc8ckjn +dkdfrsgb87cpnkchtgjnkb5q6 +seven2fhtdone9xtpbq7 +four3jmlftfzcdmcrfhjfkcfninefivesix +kdxrl7eightpsmlrkllmjdpslnine +three7nzxl3k2nine6 +7five8two +sv8mj87 +vqjzjjps45hdkcjbsl3eight174 +gfljtv7one2z +dveightwo7zrhmxjvlxftbjrqjcxlfive9 +threefjsvftzqneightfourtbvxqhssgrntdzpx2eighteight +fknxqdhdktmkcdfive1five +gs6168 +8twotlg +fivetwo7one14 +64tjxkdfxbvkthnnc +2onefivenrsgzpdzgjztpzpmeighteightttdfkgtkvltl +nineeight65three +mkbjxsgnineninesevenng2four +3xckzkhh88threepkj4five5 +ndxjxnvxbcfgdfz9fnphqrpvcheightpmxseven +2twodckhmzjvdgthreesix +rttwonecdl4 +qfvsd7kcqjphrqzmlvjffdscbeightfgmdpbfsdpseven3 +five68five +24tpfour17sevenlpkngxps +meightwokqnine1twojmsxxvbbrlqkprmxxlng +skkxpheightseventwosevenbfbcmzrpl3 +jvxhdnldseven58twofiveflsdcrnslqmqfvx +15ninexgmsvtpfnr +five758ssrnh +onezpkfv4vnhhslhgk91pfbtdgqqcmcdqnqxmk +rjphmdlleight5six7 +863xthree +cfghvcv5 +bmbfourfjtnxqppkf882k +dqnrjlvhxdfivenine8xl786 +lqrqspsxtwo6 +oneone9dkvzhsvgtl +9sixf +2nj +hsvrgtmkxcpxtjncmthreethreeone7one +vphqfour4 +qbpxpfmcxbnineeight8eight +26 +bbmspkz22onejeight1 +rljffive89phxltnine +five3dhscqeight3six +nine8msgnltpxf +38jxrfhbnclzzqqkvkgfourcfnxt +9fzlghgp +vjxprkvhpg1sevensdeightshmrfmmrt +95threethreeztmjkvqmgx +sixsfgrkqsc6dsixnineq +fivetwo267lgpttkflb6hcglpldzv +6cnscfjnlhh8x8qjbslh4 +xcxbjg192 +29sixeight +8xkpzfvhdnonemq67 +zxhbcmkbqpqkx1t97phfgdqfour +sixfivefivesix6sixsixjjp +5sevenfour1fourninefourfxsqhcpggone +ldpmdf37six1hfsmjnngmbbsjtf4 +fourtwo3lfzphbl1 +seven8cndkoneznhmtqnpr +9ztwoonegzpfjmgdjhhtglnsmjmqqssn1nine +3jvptqkjhchg9 +qbtwoneeight1nine9txvdpdlhv111pfdnr +3eightmkclrtz51zchkqh +eightpkrvkqgplptwothree5 +88gmb4dffm +fourghmpbfc3 +hcpllninenkcvjx1ghptwo36 +fourone8xdqmfnsdzgninerfbxbfourjshsvdksix +hkljqv5nfkbvveight5 +c9bczrtpqzj2 +xgjskgzkfive3oneighttdt +9one5psix5jcjlhz99 +8gpvvvhpfqb6sevenhjldkhsjskthhmzzgqxsflseven +96xjbsjmkgxgbknqckcrq +cdgjhklphq3chkgtwofour2 +nine9mqfbxdspvn17zkbl +3flbbpjgfh +two9gfn7three1 +zjcksix1dpkdbsxbrseven58 +oner9eight9mtspfsix +1hhdz156qpfmmrb +oneeight9 +crznkknhn716djrhfivetwo7 +thkoneight54nsix +xkkprql688onesixtwonine +791rvbxbcjzfqnine +fiver34 +3onefivenine183four +pkvdxfive6six +6ninesixkstsggvvvsix3two +onetwo6ctkntf +76sixfivefourhspsntf +five6seventkdstwoxdb +9sixzgmrrzfzcfzhrsseight4cprlmkplfzflz6 +fourmmbnpneight516one6q +rpp86sjvzxssbjtfive +three2sblnqxxjntksxjnvonedlbmxrrpzpcjpnn +lqcbbl2rxjhh17zxgjgtkvq2five +svvjsxxlh8t +6bhneight7ljjhjfvsbnsndvrc9six +sevenstgxksfmzd1ktwothree1mfour +527nine7 +295hkjbvf31 +bpzlfour1ninetwo5 +bh5seven3chjvfv +7vggcnckrmgbkx +msqpgd87 +ninekmnjsix9dd1 +three1two +qnrlcck47sixnrdkqnrxmlz5 +1rxseven891 +24b +4fdfrgzjpmltcqg36tpqqcvbznine +ftbtsix3 +njvzhlbthreezml8 +j4nineseven +4dpgmtgrn +97rnhk8rlp +3fivefivefoursevenflxvnbzlxhffgd +ftlbqxslq2 +eightseven3 +6dhcthree171fivecdldskdsgj +54nine +87twovpmn +28mzz +seven7csqxqn +crzrgqk66five5ngdh +xzjlmmtqgrtqrpmchfdbjpdjkqppxhsvfnzrth7 +sixfourjqbgsix3 +5eightnine54 +26gnqghndfcpmcvngqvzmfjpr8 +eightninethreebjjjvsgnonetwogflphxkvmz9seven +6qjqkmpstzc +three97sevenvxone67four +35ninetmdxqngxr7 +2sbrlnqz1 +pnv91 +5four744seven13rp +8bsix +8bcr +3eightljdhfxlnsgxs49sfzhzlsgvbldskr +835m7threefour +x3t52two +onelrzhp1one1seven9lcclzfkn +7rjzxvzdfeightlhzrnqseveneighttwoseven6 +seven13 +zkkknsevenzqsthreenine9four4 +vsszkfqpqtpxhqzpx6rkngzksmeightonesevenvzkd +fourbtkgjrglhxvccbjlnxlbhvsevenfourzjhcgmrr5 +two95 +73four5eightfive1 +8ninembxfprm28 +ninethree2twofive6 +18two +xjtwone7lfdzdvpccjsixp7rvhmh +six872jbhpgznrl8lkdbvfsgv +pnsbvfqtmkjtxseven7hkjhhmncgx +qljf6 +four3five321sixone +xvt15qcqd22six +1ndxz +gxfeightwo1two +22eighthxvrcmx8cqmfsix +3vxxlvgdvd3five3 +6threenine1tscqllqbone8cpzsnrxc +twoseven4snjpkmhnrb +gl3sixgxtttsldsmzhl5jgtwonem +seventtmxdmsjgtonebstmmskzsnsgthree2 +ctgrq17khfmdfbrl12txtsmtfndxmvcshxj +7six9mkkl +five1qxfeighttwo +eightninehckmhftskt7sixgeight2 +fllbppftcshjmtdthree8hpxlf +2one15two +qrzzg8mhqjpcbbfk +nnbnhlmgg3twotwosevenf +9tqqddhpsbdhdnkrjlxnqmjf +dtgfxfivefivefive6 +one5jgbcncmz4fpltcfcdg7 +12czktx +344nine +7zqd6 +sxgftzrr1pkffhkjtcv5mclnzsvdqktvkrgbnctgcnine +slfztfq5nineqcbdpcn5tczz3eightwont +9eight48kblmfc95 +4xmrglzxtsix +qhrgkbnsq5three646qntnvxcvg +vb3fiveseven9n +vgcdgctthree1281onemsxqvgnsix +bcstq5dghsfrcmftwo4lflbbrpztwo +hpjtwoninetwo87four6 +m3kgqggsdjq +26ninejzhmbp1 +nqtpvvsm4kjnkkz9 +5sevenfrqgpvqx +twobqcr9threeone +ninenine2qnnine +fournine629sixfive9 +sevenlsmstsxbpfzmkxsdp6 +1946one3eight7hhlqqkb +tjqmxhkhcsix6nineqdknshfiveflpcbxr +8seven4seven +8zjmndrdpgqsevencghkthree5 +bsrkpbhhsbpggn26 +11threethree89hqpvkqxzq +vjlhmd182hzqmsbdpnz2 +eightsjzfonebdcmlkcp3xdssfckqffsrpjfbb +krvssix8fmpfivezpljfpeightfdkzkgmm +fournrdhfbstx5fivefoureightfive2 +fivedfivejbjdd4eight +sevenfivetdf4one86vv1 +7eight7 +2fivedfsdxfplllfq +qcknrkljqxone75nvg85eight +vvrhxxvpvtsixrvskznine9 +sevengtcdtpgmfivexffgffst1eightjjmskvptrone +86five21zflbtcnlm +pfthree3oneninegzqpgxq2eight +17onekfhpvhppj1hdthrmdggxkgzxhxzdvbf +3sixzkml8eightfive78xv +pseightwosixxqjkfj484three484 +7zdpcvdnllthreefqpcttxbrtqpkpklnxdfszkxsbxx +2threeskpqphjffxnnvk6 +3nine66threeone46k +seventhreezgtlg12gndthree +8sqnqccmseven5 +sevendssdthreeseven2smpgpvdeightwob +hzcrrlkm8three +xtwone56pgzt5two +one4ldxzbjxlmsevenstqlgz +fourcxhqqlxfourtwo5mdjbzn +4eightbrtvsbjgnc +ninemfjghlonenp494jsjjnrhvdkthree +8threekccsevenfive +4bfvscrpfivetwospsvkvhmcptmxqseven +jzcbsgvljn5vtcpgh +8foursixseven8fivenine7 +sljtbrnsrcfourfivesevenzcdsqrseven95 +five8ninethreefive +fivekgcxtkjdvjlr9 +two2onefourkvgnzbfhhqgpdrjxfrrxdmrx +sixvb14sixkfjxrqskbq +three71nzrdggvlsxxxcfzdsrvpvbqsjn +vlrlvrqpvm98qphgsdkkmhdzfh +cmnpnvnine2two +fivexzdqfr4two5ninekgpzqfdgqlz +eight92dd2cgbqone9five +4eightfivevjfffd +57nrnktqrqlv6 +mqlhcpeight9zmsmh485 +hthxcv9l5one +nineeightlptl8fivefourmblrxbtcvlvjftcr5 +7fhgbqs +2v +jnhldbh7dkskeight9 +37fourlcsevenone5 +5jzntdrmfourhxrrfcxthree +four722 +7onenine +8sevenzfzmhkxjnr8four +nine2z +378bcbkrfsnfivesix2 +bdxrq6zsjkdcnfglc +4nqsvxznine271five +2fourthreethree6 +7twovkt6eightkmgzbd +gdsqb12rpqlfourfive +1gczfive4four8five2qbrsddkj +rrkctrmffive99jsgrbg93 +onegxssfourthreeeight2fztpvcvvn +fivesjmzppdlj57 +sixone35fourpj +nkqbbztcc7 +551mhjcn6onesix +49thkftkcsl +jthcqlp7reighthgdjbjpkxeight2 +threecfcmvgmsq534hhmbchteight +kjvdbsrbmxdjpjh7 +fivetfkphxzpkzpvrhfvbd4hfour6zhprttq +ccjcvssevenninensnpxcklbxqlcdgmvddsseven3 +2119six3 +5fourlznsqtvdcz +pfxfknrreight6twonine +bqrscdjrldsix5 +zznkptknm7rqgctxdthreesrhqkrdmsx +hmfjsqk6plqcjxcxmtwoninenine37 +meightthree65 +threenqqz7dhjsgzznhvm44six +86rdjfptxhhv5eightqkfive +91lfzcqshrfxssninejseven5tcqpdx +2xqhs +five6twognddnhfivesixxqkk1 +two85jrxgxcxbr +xfrqjfhpztqfourthreefour3 +tlqzlcckj2xrvvnznrnx +mltpqxbbrprvvlsfone8jbpjkjdqxtzlbnhhhhvshfnl +two9smqghpzpc2 +cqpklmdvnldgsdnlpmdpcql3jmlfvgxbgeight67 +7hhlcbpffour68sevensevenonesix +sixkvtclqcmlpjqvbbrn7ninevjrgxdhqx47 +975two +xdjb57five65sgghqkltxjtwo +8pnjssxdgbdmpbkxbdmhbr +3tgnrsevenrggtxps8rlkck5sixcrdccvcqg +xvvglr4 +fourdqtzrszxdvknq9dvxks +3btdbfourthreexhnjqrtnnxttqcfsevenlvhqxrsbpgqxjfvp +9onefzskrcpmpthreextjnlteighteight4 +hgvch3two +7nrc +5mnhgg +4twonine +7six6six +vjeightwoseven83mjfdpzrnnp +gfrgsixqmcbdjrtwo4tsxghf +7mmvkgmq +8qckbxdkqzsclqfive +3four52eightdhmr66 +ftoneight3bdbqgtfmsrfive3seveneight +scrkzrfive66 +9nb42xdrmbzpz +threetnpkv276one4sshmxpdc +2455zjh1one8 +6nc4seventhree +zjf5rnpnrdffjsix751mqbpgfgfjn +2crtmctwoseven +45fourmxzqzmpsixr3 +91lxbnn1twoxrsjsppjtwoone4 +37four6 +rkqb4eightthreesix93kqkhfsvngljp +ghhhksix38eight1qplkftstdnone +6nlxxncvqv71fbv +9169nine6kvcklgmn +vlddrrvcbd87mctrcj5 +one6fxninesixshdrtvglzlfbzlkvpmtxsix +threemkrzrthree234cnngnflmfdvkt +onefdcdnss8xx1 +oneone8mh8eightzrstvstwo +fivekdmdgdqpcpnineqzmnpsjktzxpvbzrsp1eighttwo +fourxckchnmz2five2hcqrsxgj +38five +onefivethree4cone +fourjrzqcjjvgm6five +9lcjvlsixtfdktbkvv1gsncxfdhhttxlzb64 +7two4one9 +7nineznmdvrpl +threesixthreelkvmhzhtd6 +mxdglbdzqlthreevbjlzmvf9mkbdrtxpsxpgpkdtfh +rjkpvjtdbxsnhrrhseven2eight5six59 +five8sixhblpctxnvtwosevenfour +9rvhtjcb +3ninenjgftq439 +99oneseven61 +54sevenfive8 +foursevenfxsmzxccfnxxc94eight6seven +3p4hnbfcxbzfhrnnhtbmprdhxbfivekqkhzbnkc +fiveeightqpghr9kfdqdlqfour +7five18qkqkzhs75rp +fourtwo3fivetwo +eightsix28klprqxzjfiveone7 +twofourthreethreethree4 +75six648 +rmpndcb797seven1 +five347dcqzmlbdxprzlkkds5ps +mnkmhrlgs7 +tknjqmsfivesevenninefour1jrlrpkl4 +6three62 +eightjrrhxd7csevenvfive +sixh3dvfjlxxkjj +5251fourmtxrpxvvbp4fblrpgtnlgg +948 +76fournine +eightseven4six99threeseven7 +73nine7 +4pknine +6eightmdmmdjone +22nine9kbgfdvjqvnmfqglhpnfhfvzxd +five6srlgmmvs19four9 +4nineone9sixs +four9tgpzrhjzqlhlxgqfz7 +nine5onedxflzhgf9one96 +hpf55 +kreighttwo2 +eight2seven29three7 +three7two1 +dhtkvvtjgzvrrvcjnqlbjsseven6 +93twofourninekznthreeseven +rzvll61 +f47ninexfqsbdrseventwo7twonep +qxcnfoureight6fivetpxbmbtwooneightm +xqkvmbth6onerzgvx +ndmjbvgzkxbttwo5one399twonef +88ncg +twomfiveninetwoltcgqkdch9three +bjgnmpfzninesxbxnlplk45 +jv5tcfkksdmtthreecvsgz6hp1 +78fivehssmgbkzlb +ztchfjrmpgsevenzsjqzmsjj8ninehrsbgknine +tksztsix9kqfbstltqdpdfqjgr1 +413ptmm23two98 +4gkzvsevenfivefive +bxms6rcd +k8two918hrnine +threeone4crkrbm1dmdlqqd +foursix5nine +one4trvninevmqx6four +threethree8five911 +6l4fstcmprm +seventhree91 +onesptwoqknsbrhnine9 +9ninebkmzsixvqnb5 +seventhreepxtcrc3gkfdsfpsfgfzvlfndgb +pcvfrsgthreeftsjvclfournine1kbbkhgrrvblvbkzgbpc +bpjfive9kdlcxbgn9zmcch41 +hcbflhjtsfour7qdjvv5kzjrpl +dbzd6mmsn55fivegkl +5stcpjhscvlsix2qqcbtxnh48 +lxfztjckeight2jsvfs8fivethreetwonel +jf3dbxqmngr +tqzqffdgnstwonnleight4rseven +18threeznntcqpxtlq +fourrmzzjvz18 +9ppbgcnvhhq3ccmsndrc5nlp +3pqlfpfltzh +2qsx4npflpn6seven9 +one2fhhfdzn +fbztdmqfgj91zskxxdcvbeightmbspgqmbggtnpg +24nhzonefourfvjq +7lfvgnpvbvjtworpvcfqqjbthreeone2 +csrcthreeeightsevenx9ninesixsix +43bncszsgmljgndbgnqc6 +13onedrjnonenine7 +six1four +sixeightone2two6four +fds3sdhbonenjlllhqfc9threefour +mbslpskb82four719 +6seven5 +sevenfour9vsixrn3 +755rbnrkmd7sevensevengshmzhmzrpzqhq +eight7khxnvqpjd +clfour5jppbonevgfj9llhfggbz +zcskxrshvbhn4nineeightndhnxs +ltzzbeight4onepnine +fives8fivethree +s5476vcslone +lj9ninekbjzlgqfour +four8gjvhkcvlml +twoone9fivecgcqlqqn74rglfbqbf +vczbllnkxkssmmtrz3ddpzg +threenine9cdqjmsfgspfive +dxtclhmkjxqsgcs938sjr4 +nrqlljlsixjhbfttptcchveightfour4fivesbhgpcnzg +sixthreefourbrtstxbh32 +sixhgdsqj22 +phshjcs7 +fivesix9 +48cjfeight83 +617sevenonesevenqjprssznhmfzrtf +two6three95eightfour +99sixone25jfssmjsmxj +fblfkzkrzqjdbvpmvvf197 +kghllmbfiveplhptxt71vjtcmdrql5 +fivenine6 +six7drddptwo3fivefour7 +57four66jxxjv57 +3blj9twotwofourfive7 +eighteight64nine +nineb9four8 +27cztm +18cgkcnxfgrlsj1chrpxqnnrcone +47sixthreefivefour93xmfndrz +gmhxpninehvfbqdkbbb74drcknctrthcvvbrllvfouroneightbbx +8tccpt1seveneight5hsmxvvdffive +1ninefivecqkchg +seven6six4jjfive2 +twotwozvvkrml3nine4fouroneightxg +482tlvrmdkzfour +fivepeight2 +one3threerfdlnrq +seven3onefivefive3 +tjnxfjrs5dfthkrxklhrnsix +keightwohzzxgnvb2 +kseven7six3five2three +sixvxbccbjmvrbpqxcrzfnsevencdfptrdeightfive2 +24vqldhgtpzpqmsnvcn4onekfvbhzrbrkqvh +mdnl2 +9sevenlfkbtsixvspnnxbvkd +cvhhcvhlgc3eight3 +8sch3one +nine4xhfrppmffone2ninecnrdtrlzzmkrsqkkc6 +three81pfj +frnrxhkhfkncxeight557one +6gcvmmvmlss33 +3zkfmdrc9four23vqvpgd +three71gqdcpzpxkffhpbnbhfjgrhlzckmcrdtrvpnckkvmsp +2phtgvfsevenpcpcvkpqgvkddmzdtbzxjppppptr8 +tzp3ljzslxzldqqsgl99 +eight24five1 +ssfjsnxptwo192threelcdbeight +eightnzdnxpgvzqh7eight76tcj +8598fourhclmkrtzkjgkfr1four +83qfzhmfnsixfourqfpjclprrv64nlxbqdbbst +vdlsvfourcnnninetwokkctqtl2 +lfxoneight8grninesixtwo +82onevhzhthree6 +qzjxbls1 +fivethree1three +qgcqc6two3xcdgfsfournine +6sixdtpdpxrjsixoneightbfm +two4foursix +ts2xkoneightr +gtkhl73onesix1 +7xqmpssix +sixsevenninejjtrh64 +6q2six6 +sixndmphqqpft3one7ninerksljn +eight44c +ppvsjhv32jzctbzceight +ppgeightwoklgkdchccmxxsixbqtkheight56 +ninefourtwo5sixsrrv18 +fivegvhbvkggpcqvksn34fhcxrmhvvt +nineone6eight29jhv +3dvsfpt4two +8257kbvkjjlhmr3 +9ccone +pcmmcblfqfpgxpssnk2 +1twofqfour7two +six96twonvrmnzzeightwoc +kqgsdxjjksdnzjdcd1jqnkz +threenine8698 +seventhreethree1251 +fournnkdvms6fjggsxlljshhmh9sevenfour +2lzxtcvvchmhxhqlxrjspg3 +6jxlz1cqbcjbhfxb9321twoneqq +fivefourfour4 +foureightbjjd7grgvxlm2three +zcdgdslqkkzhmsbdtmvqbmgfqdg2twogd +82onemfffnm +48trdhznd1 +5sixeightsixsixcsjsrnmzbcdjn68 +lvtjmrpfouronethree84dcccm +3sixfsrfour +sixjsvlzzgxrxmnine1kzjrvxmghfour7 +nrqqgsmpkcone3one +lmnzcqrrhvkckzdg5 +29fivebnnh4zv +threefour9dz4mvhh2threesix +six7two +two5zx1threefourseveneight +frb1threefour +xgrrxdmpcc4lvnhpvgcdlone89 +five28qtnxqxshrmspdghsfvoneqzzpjlnvxnrctptlv +eighttwo6eight88seven4 +fmxdtnxfrfivethree2jqqx +cvxktgdvtbfqkvvds2 +vkhmjnlk99 +vvhphh2ttjrscppq +sixjfxxqxxhdhjcthp3three +3gvjntkzcmbninenj +sdlpseven9pdcvonefiveone1 +23pcvcljhtgbthree1eight5one +3kreight7k +mlxvzqjsthreesix98 +6h94sevensevenldthree +six86 +four1four15seven +rvqbkndfqjeightseven84 +one5two672 +two7three87fmqgdmqvcvn8 +qxkkgsixbdrqz7pqsfms +four2v1seven99five +7ndxpm +lrrqxnjtvzfdzplxppzonetwokrmv131 +fourgvjbhpxqcseven1four +thrthbgthree7four +jbnkcqqczzpkq357sixfrgsjhjmxt +rvrjsdnfldcqnplsqfnine6three5 +jgkzn598fhqqxmsqjgpzonefour +qkjl1vptpmsseven41oneone +fiveh94two9five +2lrxjflmvq9 +jtcdnjtcgffourkztkqfrfourtwojpqtq7qjdzkfour +eight3dlkndonethreetwo9one +2bqfprnkz +ninesevenfive63gxgmjvqf3 +tkvoneightsixsevenfour8nine9gzn +sevenninemlzdbttpp3qb31jmmtmbqnr +hdslnxgdz48 +four6prrfbtqrqvdlx81 +2hgqtnbxnqtpfive66dpn +jhkjstxzblfive6vvd +ljxqtqrgm6bgfppeightseven9 +gcmlbqtnm4jqhdhsfour2ninefour +threeeight1hrdqptwo6 +mlxvrhjqz4twolnkqd +npgnsgkmxmeightsix4brmcjjlbl6 +jrtwosixvrtrfvvpnine8hhqcsj2 +5ckctkfour433qd +9zczvzz +one46ninenhjzfhqcbtwo +26mvspqqkxntwomgsfvmfshvmndcbnfxzx +zhponeightbslzggxnpjgt97xjvxqrrsgj6zclqbmsdb +175 +fivetwofiveeight2five +three9sixtwo34 +7foursixhjvpndkjtqzshxdczg3three9 +8six3hqbcnjsdxr922vplmp +tmrbnzlrs822nineeightnine +two36nine6zhvmfss +qdkcfrmb7 +9dcbzzhhgnclcdchgcthree +tmxkqqstzqmp5pf97 +four86fivekbpjggeightnine +mmsvnnxeightjqpdsdmgjzssssjtwofive6none +5bchshczsjdh +39five8cflqglqhbsixmqnfpqhh +8five89threevkvgbtjrhhkqdkllkqtdjrv +ninelldnine4 +fourseven52threebstwo +9zdkqprhfdnthreeddj +threetwo5tzthreetwoslzdkf91 +eightone5twofourdhdjpsbj7 +2nine1ninesixlnine7 +threethree824six +threecbcvvcdgnzthree8nine2ckcvvqvghhthree +nineninefour9ddctwo38 +sixthreeghnblhbsk5 +8threephn +tpvoneight1sixjzkrtjcbpkxgvnccxvxbglhhgsevenkchhvchz +xcdsxxfivethreecdd77 +seven3twomrjfrxninefive2 +82twotwolsm +njljffrkrgnineone5fourtwo34 +9fsrnjjfkeightstjffdpeight +lz77jfdvgq +8skninektrzgsonesbnszbzsbfxgczgt +6lkmpnhjbsjeightvhfqnhtg +jmkrn89onenine4 +84xznbtgmsrg +twonineldsmg59five +z8vgkntnsmntqdhnphjppx8hfvptkrpbmjkg +1sixsixonemzjcbchdkeightsix6 +cnthtftdzhjxc9fivetwo +four99 +tsfhcrqthreecnsf49tnpjtvfjm +3vmrlbdone +fourtwoseven8klx8cjqnlf +5533 +96threesixbb8jcbtlhd +93mjghj +tpq7ninenine58 +twosxzrdncbhr5gnqv +8tgmmjxntmbdrtoneone4five +onehgnthree24 +4ninebrjplcxdthreekmzchvhpkm3zfkvbtp +sixgjrgcvhphv5threekgqtszxllxhdldzbv +krq9nine3fqhdvnrbmncseven6 +six85njxj3mmphzpv6dhqlkmptldvlflckgk +44eightxjtvfbmt +2fp9 +skjxglseven5nxfdgjlclv9 +zbmxptthreechlxvxszszztqqs4threefouroneone +47633nine +8584mrvjdspgmsevenfour8two +five5nzcmgx +4threenine19twonine +kztfivessbtzfjbmjmsnjxkct7 +2onesix +nine6kfpkqhkjzsknrldfcghcgkghnine +9cbhmrchmqjrhqx7zsdxmtlbrzfive7 +87eight16dmgpfcfvbt +three45sfourtwo3 +2xvmdthreeeightthree +zblpmvk2fivefqdjqpdk2eightwods +nvrngd1one642 +twoninesix8tvcm4 +sixjjrjrpjbdlsix5kscvgfour6 +oneninefjmblx25lgstzzkvnqcjl +5fournhphcqqzngvcjphfnhgr +fourninetwo226 +sqszqk8154five8eightnine +5rcqxrbv +3three7three118 +9dlgvvnpsjrhxjpjr +cgttwo97qceight658 +3eight8threefourthree8jvld +sixbctkcmzbtb4ntgtctgtr7three +36three92 +9twonezv +ddrhf7ninefiveonefivefive +4dpc75eighttwonine +27three +837ninethreezdcdbmjtph +two3jgj8pfptxbpjcfournine6 +r8mzqvthlnljthree2 +foursshmxt4qhsnxtwotwo3fpqhpd +ntlfvnxkxxvtktmbqfourqjzjdcdthree76ninetwo +7zfhfmqmbkzrknxcfgxmqh +zfzfcsbkld9eightthree +threethreebxqqsnfzvqfivefmnc71 +one3onesix63mxgmcpqfvnfiveq +9four7twofourtwotjlpcqeight3 +1dcnsvzrstslsqvcvonetwofour7 +cg12five +5twosxfsbmxrtl +seveneightsix3gshhcnjsqb5 +9xkvfhcmrs87 +lpkcnjpsix1fivetwo +9dsninefive6lhjpdkpcr +838mjxsleightnine +seven4ninefivefourhxplgzfvsevenbbdjqc +1drcgshkfthree3nlkztjtrx9five +7three4seveneightfxsz +7onetjjkznvlb +93two4foureight +8fqddclzvlx +tdpcspmg39ddqkdlpjxvkdtjpc21 +fivessmncpxsd3eight +44hjrhqdqf19pxkb +bmcgjkkkhfive5twonekc +twomv4nine +16rrksxjzjlt5plmvjtvhkfnineeight +cmczrnjjsntptjffzrpqthreemjpfhsjbrmnlkzpvvvmj8 +one81six +9jfivefive82rz +one32fourfivelkrczztone +seveneighteightfour1 +58twoxgklhpndxjrpb86 +five2sixfourcjfvnmhrxrtwovhrdrfrssphgtcqthhzxh +lxtbmsevenbms3one8dsbsixnine +sevenhcgr6ninefour +trknlxnv43zxlrqjtwonect \ No newline at end of file diff --git a/adventOfCode/2023/ans.txt b/adventOfCode/2023/ans.txt new file mode 100644 index 0000000..9063443 --- /dev/null +++ b/adventOfCode/2023/ans.txt @@ -0,0 +1,3 @@ + % go run . +[Samples] Day 1:142 0 +[Problem] Day 1:56049 0 diff --git a/adventOfCode/2023/execute.go b/adventOfCode/2023/execute.go new file mode 100644 index 0000000..a1a28a1 --- /dev/null +++ b/adventOfCode/2023/execute.go @@ -0,0 +1,38 @@ +package main + +// Iterate the day problems --> read inputs --> execute the solution --> print result + +import ( + "fmt" + ioutil "io/ioutil" + "strconv" + "strings" +) + +func main() { + dayChallenges := map[int]func(input []interface{}) (interface{}, interface{}){ + 1: solve1, + } + // Iterate day inputs + for day, fun := range dayChallenges { + folderName := strconv.Itoa(day) + inputFiles := []string{folderName + "-sample" + ".input", folderName + ".input"} + for _, f := range inputFiles { + var inputs []interface{} + body, err := ioutil.ReadFile(folderName + "/" + f) + if err != nil { + panic(err) + } + input_strs := strings.Split(string(body), "\n") + for _, val := range input_strs { + inputs = append(inputs, val) + } + if strings.Contains(f, "sample") { + fmt.Print("[Samples] Day " + folderName + ":") + } else { + fmt.Print("[Problem] Day " + folderName + ":") + } + fmt.Println(fun(inputs)) + } + } +} diff --git a/adventOfCode/2023/go.mod b/adventOfCode/2023/go.mod new file mode 100644 index 0000000..df7632e --- /dev/null +++ b/adventOfCode/2023/go.mod @@ -0,0 +1,3 @@ +module github.com/Srinivas11789/AlgorithmNuggets/adventOfCode/2023 + +go 1.19 diff --git a/adventOfCode/2023/run.sh b/adventOfCode/2023/run.sh new file mode 100755 index 0000000..b13dd19 --- /dev/null +++ b/adventOfCode/2023/run.sh @@ -0,0 +1 @@ +go run *.go diff --git a/adventOfCode/2023/template.txt b/adventOfCode/2023/template.txt new file mode 100644 index 0000000..a0f7730 --- /dev/null +++ b/adventOfCode/2023/template.txt @@ -0,0 +1,27 @@ +// Day +package main + +import ( + //"fmt" + "strconv" +) + +func solve(input []interface{}) (interface{},interface{}) { + + var dayInputs []int + + // Customize input + for _, val := range input { + integer, err := strconv.Atoi(val.(string)) + if err != nil { panic(err) } + dayInputs = append(dayInputs, integer) + } + + // Solution 1 + sol1 := 0 + + // Solution 2 + sol2 := 0 + + return sol1, sol2 +} \ No newline at end of file diff --git a/codeWars/goLang/decodeMorse/decode.go b/codeWars/goLang/decodeMorse/decode.go new file mode 100644 index 0000000..8ed2e6c --- /dev/null +++ b/codeWars/goLang/decodeMorse/decode.go @@ -0,0 +1,41 @@ +### Solution + +package kata + +import ( + "strings" +) + +func DecodeMorse(morseCode string) string { + var result string + var temp string + // Three spaces splits words + words := strings.Split(morseCode, " ") + for i:=0; i 0 { + return result + } else { + return nil + } +} + +// Sum of the n numbers +func sumi(value uint64) uint64 { + var result uint64 + var i uint64 + result = 0 + for i=0; i <= value; i++ { + result += i + } + return result +} diff --git a/codeWars/goLang/isThisATriangle/triangle.go b/codeWars/goLang/isThisATriangle/triangle.go new file mode 100644 index 0000000..ad73cc3 --- /dev/null +++ b/codeWars/goLang/isThisATriangle/triangle.go @@ -0,0 +1,13 @@ +package kata + +func IsTriangle(a, b, c int) bool { + // Formula if the given sides form a triangle + // Ref: https://www.wikihow.com/Determine-if-Three-Side-Lengths-Are-a-Triangle + // * sum of any 2 sides is greater than the third side + if a+b > c && a+c > b && b+c > a { + return true + } + return false +} + + diff --git a/codeWars/goLang/isValidIp/ip.go b/codeWars/goLang/isValidIp/ip.go new file mode 100644 index 0000000..30acde1 --- /dev/null +++ b/codeWars/goLang/isValidIp/ip.go @@ -0,0 +1,46 @@ +# Logic 1: Split and check each octets +package kata + +import ( + "strings" + "strconv" +) + +func Is_valid_ip(ip string) bool { + octets := strings.Split(ip, ".") + if len(octets) == 4 { + for i := 0; i<4; i++ { + octet, err := strconv.Atoi(octets[i]) + ztest := strconv.Itoa(octet) + if err != nil { + return false + } + if octets[i] != ztest { + return false + } + if octet < 0 || octet > 255 { + return false + } + } + } else { + return false + } + return true +} + +# Logic 2: Use net library and method ParseIP + +// Add logic for leading zero case +import ( + "net" +) + +func Is_valid_ip(ip string) bool { + result := net.ParseIP(ip) + if result != nil { + return true + } + return false +} + +# Logic 3: Regex compile the string diff --git a/codeWars/goLang/printerErrors/print.go b/codeWars/goLang/printerErrors/print.go new file mode 100644 index 0000000..5b39d3b --- /dev/null +++ b/codeWars/goLang/printerErrors/print.go @@ -0,0 +1,20 @@ +package kata + +import ( + //"fmt" + "strconv" + ) + +func PrinterError(s string) string { + denominator := len(s) + numerator := 0 + //fmt.Println(s) + for i := 0; i < denominator; i ++ { + //fmt.Println(s[i]) // prints in octal value + if s[i] < 97 || s[i] > 109 { + numerator ++ + } + //fmt.Println(numerator) + } + return strconv.Itoa(numerator)+"/"+strconv.Itoa(denominator) +} diff --git a/codeWars/goLang/shortestWord/short.go b/codeWars/goLang/shortestWord/short.go new file mode 100644 index 0000000..9797384 --- /dev/null +++ b/codeWars/goLang/shortestWord/short.go @@ -0,0 +1,48 @@ +package kata + +import ( + "sort" + "strings" + "fmt" +) + +// Logic 1 +// Using sort by function length +// * Create a sort interface and define a function to sort by length of items, then return the first element +// Reference: https://gobyexample.com/sorting-by-functions + +type byLen []string + +func (s byLen) Len() int { + return len(s) +} + +func (s byLen) Swap(i, j int) { + s[i], s[j] = s[j], s[i] +} + +func (s byLen) Less(i, j int) bool { + return len(s[i]) < len(s[j]) +} + +func FindShort(s string) int { + fmt.Println(s) + words := strings.Split(s, " ") + fmt.Println(words) + sort.Sort(byLen(words)) + fmt.Println(words) + return len(words[0]) +} + +// Logic 2 +// * Iterate over each string and obtain the minimum value +func FindShort(s string) int { + words := strings.Split(s, " ") + mini := 9223372036854775807 + for i:=0; i 0 { + stack = stack[:len(stack)-1] + } else { + return false + } + } + } + if len(stack) == 0 { + return true + } else { + return false + } +} diff --git a/codeWars/python/categorizeNewMember/category.py b/codeWars/python/categorizeNewMember/category.py new file mode 100644 index 0000000..0d84857 --- /dev/null +++ b/codeWars/python/categorizeNewMember/category.py @@ -0,0 +1,15 @@ +# Logic 1 +def openOrSenior(data): + result = [] + for person in data: + if person[0] >= 55 and person[1] > 7: + result.append("Senior") + else: + result.append("Open") + return result + +# Logic 2 +def openOrSenior2(data): + return ["Senior" if (age >= 55 and hcap > 7) else "Open" for age, hcap in data] + + diff --git a/codeWars/python/createPhoneNumber/create.py b/codeWars/python/createPhoneNumber/create.py new file mode 100644 index 0000000..92f5be0 --- /dev/null +++ b/codeWars/python/createPhoneNumber/create.py @@ -0,0 +1,10 @@ +def create_phone_number(n): + #your code here + phoneNumber = "(" + for i in range(len(n)): + phoneNumber += str(n[i]) + if i == 2: + phoneNumber += ") " + elif i == 5: + phoneNumber += "-" + return phoneNumber diff --git a/codeWars/python/playingWithDigits/play.py b/codeWars/python/playingWithDigits/play.py new file mode 100644 index 0000000..88714ed --- /dev/null +++ b/codeWars/python/playingWithDigits/play.py @@ -0,0 +1,12 @@ +def dig_pow(n, p): + answer = 0 + temp = list(str(n)) + while temp: + answer += int(temp.pop(0))**p + p += 1 + print(n, p, answer) + if answer % n == 0: + return answer//n + else: + return -1 + diff --git a/codeWars/python/reversedWords/reverse.py b/codeWars/python/reversedWords/reverse.py new file mode 100644 index 0000000..1d595af --- /dev/null +++ b/codeWars/python/reversedWords/reverse.py @@ -0,0 +1,2 @@ +def reverseWords(str): + return " ".join(str.split(" ")[::-1]) diff --git a/codeWars/python/sumOfParts/sum.py b/codeWars/python/sumOfParts/sum.py new file mode 100644 index 0000000..1f0f9f0 --- /dev/null +++ b/codeWars/python/sumOfParts/sum.py @@ -0,0 +1,17 @@ +# Logic 1 +def parts_sums(array): + total = sum(array) + result = [total] + for item in array: + total = total-item + result.append(total) + return result + +# Logic 2 +def parts_sums(ls): + result = [0] + for item in ls[::-1]: + result.append(result[-1]+item) + return result[::-1] + + diff --git a/codeWars/python/yourOrderPlease/your.py b/codeWars/python/yourOrderPlease/your.py new file mode 100644 index 0000000..566c94f --- /dev/null +++ b/codeWars/python/yourOrderPlease/your.py @@ -0,0 +1,26 @@ +# Problem +""" +Your task is to sort a given string. Each word in the string will contain a single number. This number is the position the word should have in the result. + +Note: Numbers can be from 1 to 9. So 1 will be the first word (not 0). + +If the input string is empty, return an empty string. The words in the input String will only contain valid consecutive numbers. + +Examples +"is2 Thi1s T4est 3a" --> "Thi1s is2 3a T4est" +"4of Fo1r pe6ople g3ood th5e the2" --> "Fo1r the2 g3ood 4of th5e pe6ople" +""" + +# Logic1 +def order(sentence): + words = sentence.split(" ") + result = [""]*len(words) + for word in words: + for character in word: + if character.isdigit(): + result[int(character)-1] = word + return " ".join(result) + +# Logic2 +def order(sentence): + return " ".join(sorted(sentence.split(" "), key=lambda x:"".join(filter(str.isdigit, x)))) diff --git a/findTheWinnerOfAnArrayGame/find.py b/findTheWinnerOfAnArrayGame/find.py new file mode 100644 index 0000000..41fe942 --- /dev/null +++ b/findTheWinnerOfAnArrayGame/find.py @@ -0,0 +1,20 @@ +class Solution: + def getWinner(self, arr: List[int], k: int) -> int: + + consec = 0 + max_item = max(arr) + first = arr.pop(0) + if k > len(arr): + return max_item + while consec < k: + oppo = arr.pop(0) + if first >= oppo: + arr.append(oppo) + consec += 1 + else: + consec = 1 + first = oppo + arr.append(first) + #print(first, arr, consec) + return first + diff --git a/removeNthNodeFromEndOfLinkedList/remove.py b/removeNthNodeFromEndOfLinkedList/remove.py new file mode 100644 index 0000000..0648a14 --- /dev/null +++ b/removeNthNodeFromEndOfLinkedList/remove.py @@ -0,0 +1,48 @@ +# Definition for singly-linked list. +# class ListNode(object): +# def __init__(self, x): +# self.val = x +# self.next = None + +class Solution(object): + def removeNthFromEnd(self, head, n): + """ + :type head: ListNode + :type n: int + :rtype: ListNode + """ + + # Logic 1: 2*O(N) Iteration over the linked list - 100 pass 39% faster + # 1. find the length of the linked list + # 2. delete the node + + front = head + length = 0 + + while head: + length += 1 + head = head.next + + head = front + target = length - n + 1 + current = 0 + prev = None + + while head: + current += 1 + if current == target: + if prev: + prev.next = head.next + head = head.next + elif length == 1: + return ListNode("") + else: + prev = head + head = head.next + prev.next = None + front = head + else: + prev = head + head = head.next + + return front diff --git a/theDailyProblem/README.md b/theDailyProblem/README.md new file mode 100644 index 0000000..a019f04 --- /dev/null +++ b/theDailyProblem/README.md @@ -0,0 +1 @@ +# Problems from the daily interview pro series by theTechLead and Joma diff --git a/theDailyProblem/addTwoNumbersAsLinkedList/add.py b/theDailyProblem/addTwoNumbersAsLinkedList/add.py new file mode 100644 index 0000000..1f93c2e --- /dev/null +++ b/theDailyProblem/addTwoNumbersAsLinkedList/add.py @@ -0,0 +1,54 @@ +# The Problem +""" +You are given two linked-lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list. + +Example: +Input: (2 -> 4 -> 3) + (5 -> 6 -> 4) +Output: 7 -> 0 -> 8 +Explanation: 342 + 465 = 807. +""" + +# Definition for singly-linked list. +class ListNode(object): + def __init__(self, x): + self.val = x + self.next = None + +class Solution(object): + def addTwoNumbers(self, l1, l2): + # Fill this in. + carry = 0 + i = 0 + current_sum = 0 + answer = "" + while l1 or l2: + print(current_sum, carry) + current_sum = carry + (l1.val if l1 else 0) + (l2.val if l2 else 0) + current_sum = list(str(current_sum)) + carry = (int("".join(current_sum[:-1])) if current_sum[:-1] else 0) + answer += current_sum[-1] + l1 = l1.next + l2 = l2.next + i += 1 + if not l1 and not l2: + if carry: + answer += str(carry) + return answer[::-1] + +def createLinkedList(array): + linkedList = ListNode(array.pop()) + head = linkedList + while array: + next_node = ListNode(array.pop()) + linkedList.next = next_node + linkedList = next_node + return head + +def main(): + s= Solution() + l1 = createLinkedList([1,8,8]) + l2 = createLinkedList([1,9,9]) + print(s.addTwoNumbers(l1, l2)) + +main() + diff --git a/theDailyProblem/arithmeticBinaryTree.py b/theDailyProblem/arithmeticBinaryTree.py new file mode 100644 index 0000000..d1f4b00 --- /dev/null +++ b/theDailyProblem/arithmeticBinaryTree.py @@ -0,0 +1,52 @@ +""" +This problem was recently asked by Apple: + +You are given a binary tree representation of an arithmetic expression. In this tree, each leaf is an integer value,, and a non-leaf node is one of the four operations: '+', '-', '*', or '/'. + +Write a function that takes this tree and evaluates the expression. + +Example: + + * + / \ + + + + / \ / \ +3 2 4 5 + +This is a representation of the expression (3 + 2) * (4 + 5), and should return 45. +""" + +class Node: + def __init__(self, val, left=None, right=None): + self.val = val + self.left = left + self.right = right + +PLUS = "+" +MINUS = "-" +TIMES = "*" +DIVIDE = "/" + +def traverse_n_create_expression(node): + left_expression = "" + right_expression = "" + if node.left: + left_expression = "("+traverse_n_create_expression(node.left)+")" + if node.right: + right_expression = "("+traverse_n_create_expression(node.right)+")" + return left_expression + str(node.val) + right_expression + +def main(): + # Test setup + tree = Node(TIMES) + tree.left = Node(PLUS) + tree.left.left = Node(3) + tree.left.right = Node(2) + tree.right = Node(PLUS) + tree.right.left = Node(4) + tree.right.right = Node(5) + exp = traverse_n_create_expression(tree) + print(exp) + print(eval(exp)) + +main() diff --git a/theDailyProblem/arrayIntersection.py b/theDailyProblem/arrayIntersection.py new file mode 100644 index 0000000..7406d5e --- /dev/null +++ b/theDailyProblem/arrayIntersection.py @@ -0,0 +1,44 @@ +""" +Given two arrays, write a function to compute their intersection - the intersection means the numbers that are in both arrays. + +Example 1: +Input: nums1 = [1,2,2,1], nums2 = [2,2] +Output: [2] +Example 2: +Input: nums1 = [4,9,5], nums2 = [9,4,9,8,4] +Output: [9,4] +Note: +Each element in the result must be unique. +The result can be in any order. + +Here's a starting point: + +class Solution: + def intersection(self, nums1, nums2): + # Fill this in. + +print Solution().intersection([4, 9, 5], [9, 4, 9, 8, 4]) +# [9, 4] +""" + +class Solution: + def intersection(self, nums1, nums2): + # Logic 1 - dictonary method + import collections + counts = collections.Counter(set(nums1))+collections.Counter(set(nums2)) + result = [k for k,v in counts.items() if v > 1] + return result + + def intersection2(self, nums1, nums2): + # Logic 2 - Set intersection + return list(set(nums1).intersection(set(nums2))) + + def intersection3(self, nums1, nums2): + # Logic 3 - Iteration + result = [] + return result + +print Solution().intersection([4, 9, 5], [9, 4, 9, 8, 4]) +print Solution().intersection2([4, 9, 5], [9, 4, 9, 8, 4]) +print Solution().intersection3([4, 9, 5], [9, 4, 9, 8, 4]) +# [9, 4] diff --git a/theDailyProblem/buyAndSellStockByDayOnce.py b/theDailyProblem/buyAndSellStockByDayOnce.py new file mode 100644 index 0000000..f54a27d --- /dev/null +++ b/theDailyProblem/buyAndSellStockByDayOnce.py @@ -0,0 +1,35 @@ +""" +You are given an array. Each element represents the price of a stock on that particular day. Calculate and return the maximum profit you can make from buying and selling that stock only once. + +For example: [9, 11, 8, 5, 7, 10] + +Here, the optimal trade is to buy when the price is 5, and sell when it is 10, so the return value should be 5 (profit = 10 - 5 = 5). + +Here's your starting point: + +def buy_and_sell(arr): + #Fill this in. + +print buy_and_sell([9, 11, 8, 5, 7, 10]) +# 5 +""" + +# Logic1 +# * Greedy approach - buy at a new low and sell and a any high + +def buy_and_sell(arr): + low = float('inf') + profit = 0 + max_profit = 0 + + # O(N) iteration + for i in range(len(arr)): + if arr[i] < low: + low = arr[i] + else: + profit = arr[i] - low + if profit > max_profit: + max_profit = profit + return max_profit + +print(buy_and_sell([9, 11, 8, 5, 7, 10])) diff --git a/theDailyProblem/characterMap.py b/theDailyProblem/characterMap.py new file mode 100644 index 0000000..94791c3 --- /dev/null +++ b/theDailyProblem/characterMap.py @@ -0,0 +1,41 @@ +""" +Given two strings, find if there is a one-to-one mapping of characters between the two strings. + +Example +Input: abc, def +Output: True # a -> d, b -> e, c -> f + +Input: aab, def +Ouput: False # a can't map to d and e +Here's some starter code: + +def has_character_map(str1, str2): + # Fill this in. + +print(has_character_map('abc', 'def')) +# True +print(has_character_map('aac', 'def')) +# False +""" + +def has_character_map(str1, str2): + # Logic 1: 100 pass --> Using extra space --> a dictionary + """ + result = {} + for i, j in zip(str1, str2): + if i not in result: + result[i] = j + else: + if result[i] == j: + pass + else: + return False + return True + """ + + # Logic 2: Using no extra space and O(N) Iteration + +print(has_character_map('abc', 'def')) +# True +print(has_character_map('aac', 'def')) +# False diff --git a/theDailyProblem/consecutiveOnes.py b/theDailyProblem/consecutiveOnes.py new file mode 100644 index 0000000..026a058 --- /dev/null +++ b/theDailyProblem/consecutiveOnes.py @@ -0,0 +1,41 @@ +""" +Return the longest run of 1s for a given integer n's binary representation. + +Example: +Input: 242 +Output: 4 +242 in binary is 0b11110010, so the longest run of 1 is 4. + +def longest_run(n): + # Fill this in. + +print longest_run(242) +# 4 +""" + +def consec_ones(num): + bina = bin(num)[2:] + """ + left = 0 + right = len(bina)-1 + while left < right: + print(bin[left:right]) + if set(bin[left:right]) == set("1"): + return right-left + if bin[left] == "0": + left += 1 + elif bin[right] == "0": + right -= 1 + else: + """ + maxi = 0 + temp = 0 + for i in range(len(bina)): + if bina[i] == "1": + temp += 1 + else: + temp = 0 + maxi = max(temp, maxi) + return maxi + +print(consec_ones(242)) diff --git a/theDailyProblem/countNumOfUnivalTrees.py b/theDailyProblem/countNumOfUnivalTrees.py new file mode 100644 index 0000000..a3dc38f --- /dev/null +++ b/theDailyProblem/countNumOfUnivalTrees.py @@ -0,0 +1,77 @@ +""" +A unival tree is a tree where all the nodes have the same value. Given a binary tree, return the number of unival subtrees in the tree. + +For example, the following tree should return 5: + + 0 + / \ + 1 0 + / \ + 1 0 + / \ + 1 1 + +The 5 trees are: +- The three single '1' leaf nodes. (+3) +- The single '0' leaf node. (+1) +- The [1, 1, 1] tree at the bottom. (+1) + +Here's a starting point: + +class Node(object): + def __init__(self, val): + self.val = val + self.left = None + self.right = None + +def count_unival_subtrees(root): + # Fill this in. + +a = Node(0) +a.left = Node(1) +a.right = Node(0) +a.right.left = Node(1) +a.right.right = Node(0) +a.right.left.left = Node(1) +a.right.left.right = Node(1) + +print count_unival_subtrees(a) +# 5 +""" + +count = 0 + +class Node(object): + def __init__(self, val): + self.val = val + self.left = None + self.right = None + +def count_unival_subtrees(node): + global count + if not node: + return [] + lsubtree = [] + rsubtree = [] + if node.left: + lsubtree += count_unival_subtrees(node.left) + if node.right: + rsubtree += count_unival_subtrees(node.right) + subtree = [node.val] + lsubtree + rsubtree + if len(set(subtree)) == 1: + count += 1 + return subtree + +def main(): + global count + a = Node(0) + a.left = Node(1) + a.right = Node(0) + a.right.left = Node(1) + a.right.right = Node(0) + a.right.left.left = Node(1) + a.right.left.right = Node(1) + count_unival_subtrees(a) + print(count) + +main() diff --git a/theDailyProblem/coursePrerequisites.py b/theDailyProblem/coursePrerequisites.py new file mode 100644 index 0000000..8608fb3 --- /dev/null +++ b/theDailyProblem/coursePrerequisites.py @@ -0,0 +1,51 @@ +""" +You are given a hash table where the key is a course code, and the value is a list of all the course codes that are prerequisites for the key. Return a valid ordering in which we can complete the courses. If no such ordering exists, return NULL. + +Example: +{ + 'CSC300': ['CSC100', 'CSC200'], + 'CSC200': ['CSC100'], + 'CSC100': [] +} + +This input should return the order that we need to take these courses: + ['CSC100', 'CSC200', 'CSCS300'] + +Here's your starting point: + +def courses_to_take(course_to_prereqs): + # Fill this in. + +courses = { + 'CSC300': ['CSC100', 'CSC200'], + 'CSC200': ['CSC100'], + 'CSC100': [] +} +print courses_to_take(courses) +# ['CSC100', 'CSC200', 'CSC300'] +""" + +courses = { + 'CSC300': ['CSC100', 'CSC200'], + 'CSC200': ['CSC100'], + 'CSC100': [] +} + +# This is a recursive thing +# * Return when the course pre-req is empty +# * Recurse when the course pre-req is not empty +def order_of_courses_to_take(subject, order): + if courses[subject]: + for prereq in courses[subject]: + order_of_courses_to_take(prereq, order) + if subject not in order: + order.append(subject) + return + +order = [] +result = [] +for key in courses: + order_of_courses_to_take(key, order) + if len(order) == len(courses.keys()): + result = order +print(order) diff --git a/theDailyProblem/decodeString.py b/theDailyProblem/decodeString.py new file mode 100644 index 0000000..33e0dbc --- /dev/null +++ b/theDailyProblem/decodeString.py @@ -0,0 +1,33 @@ +""" +Given a string with a certain rule: k[string] should be expanded to string k times. So for example, 3[abc] should be expanded to abcabcabc. Nested expansions can happen, so 2[a2[b]c] should be expanded to abbcabbc. + +Your starting point: + +def decodeString(s): + # Fill this in. + +print decodeString('2[a2[b]c]') +# abbcabbc +""" + +def decodeString(s): + result = "" + stack = [] + i = 0 + while i < len(s): + if s[i] == "]": + temp = "" + while stack and stack[-1] != "[": + temp = stack.pop() + temp + stack.pop() # remote [ + count = "" + while stack and stack[-1].isdigit(): + count = stack.pop() + count + stack.append(int(count)*temp) + else: + stack.append(s[i]) + i += 1 + return "".join(stack) + + +print decodeString('2[a2[b]c]') diff --git a/theDailyProblem/distributeBonus.py b/theDailyProblem/distributeBonus.py new file mode 100644 index 0000000..f710414 --- /dev/null +++ b/theDailyProblem/distributeBonus.py @@ -0,0 +1,34 @@ +""" +You are the manager of a number of employees who all sit in a row. The CEO would like to give bonuses to all of your employees, but since the company did not perform so well this year the CEO would like to keep the bonuses to a minimum. + +The rules of giving bonuses is that: +- Each employee begins with a bonus factor of 1x. +- For each employee, if they perform better than the person sitting next to them, the employee is given +1 higher bonus (and up to +2 if they perform better than both people to their sides). + +Given a list of employee's performance, find the bonuses each employee should get. + +Example: +Input: [1, 2, 3, 2, 3, 5, 1] +Output: [1, 2, 3, 1, 2, 3, 1] +Here's your starting point: + +def getBonuses(performance): + # Fill this in. + +print getBonuses([1, 2, 3, 2, 3, 5, 1]) +# [1, 2, 3, 1, 2, 3, 1] +""" + +def getBonuses(performance): + bonus = [] + for e in range(len(performance)): + current_perf = 1 + if e-1>=0 and performance[e-1] < performance[e]: + current_perf += 1 + if e+1 < len(performance) and performance[e+1] < performance[e]: + current_perf += 1 + bonus.append(current_perf) + return bonus + +print getBonuses([1, 2, 3, 2, 3, 5, 1]) +# [1, 2, 3, 1, 2, 3, 1] diff --git a/theDailyProblem/filterBinaryTreeLeaves.py b/theDailyProblem/filterBinaryTreeLeaves.py new file mode 100644 index 0000000..4ebd030 --- /dev/null +++ b/theDailyProblem/filterBinaryTreeLeaves.py @@ -0,0 +1,87 @@ +""" +Given a binary tree and an integer k, filter the binary tree such that its leaves don't contain the value k. Here are the rules: + +- If a leaf node has a value of k, remove it. +- If a parent node has a value of k, and all of its children are removed, remove it. + +Here's an example and some starter code: + +class Node: + def __init__(self, value, left=None, right=None): + self.value = value + self.left = left + self.right = right + + def __repr__(self): + return f"value: {self.value}, left: ({self.left.__repr__()}), right: ({self.right.__repr__()})" + +def filter(tree, k): + # Fill this in. + +# 1 +# / \ +# 1 1 +# / / +# 2 1 +n5 = Node(2) +n4 = Node(1) +n3 = Node(1, n4) +n2 = Node(1, n5) +n1 = Node(1, n2, n3) + +print(filter(n1, 1)) +# 1 +# / +# 1 +# / +# 2 +# value: 1, left: (value: 1, left: (value: 2, left: (None), right: (None)), right: (None)), right: (None) +""" + +class Node: + def __init__(self, value, left=None, right=None): + self.val = value + self.left = left + self.right = right + + def __repr__(self): + #if self.left: + # self.left.__repr__() + #print(self.val) + #if self.right: + # self.right.__repr__() + return "value: { " + str(self.val) + " }, left: ({" + str(self.left.__repr__()) + "}), right: ({" + str(self.right.__repr__()) + "})" + +def filter(node, k, parent, orient): + + # Recurse for each child -> left and right + if node.left: + filter(node.left, k, node, "left") + if node.right: + filter(node.right, k, node, "right") + + # filter the nodes if value is `k` and no children + if node.val == k and not node.left and not node.right and parent: + if orient == "left": + parent.left = None + if orient == "right": + parent.right = None + + # If root is k and all subtree nodes is k + if not parent and not node.left and not node.right: + return Node("") + else: + return node + +# 1 +# / \ +# 1 1 +# / / +# 2 1 +n5 = Node(2) +n4 = Node(1) +n3 = Node(1, n4) +n2 = Node(1, n5) +n1 = Node(1, n2, n3) + +print(filter(n1, 1, None, None)) diff --git a/theDailyProblem/findElementInBinarySearchTree.py b/theDailyProblem/findElementInBinarySearchTree.py new file mode 100644 index 0000000..b4d9a69 --- /dev/null +++ b/theDailyProblem/findElementInBinarySearchTree.py @@ -0,0 +1,65 @@ +""" +Given a binary tree, return all values given a certain height h. + +Here's a starting point: + +class Node(): + def __init__(self, value, left=None, right=None): + self.value = value + self.left = left + self.right = right + +def valuesAtHeight(root, height): + # Fill this in. + +# 1 +# / \ +# 2 3 +# / \ \ +# 4 5 7 + +a = Node(1) +a.left = Node(2) +a.right = Node(3) +a.left.left = Node(4) +a.left.right = Node(5) +a.right.right = Node(7) +print valuesAtHeight(a, 3) +# [4, 5, 7] +""" + +result = [] + +class Node(): + def __init__(self, value, left=None, right=None): + self.value = value + self.left = left + self.right = right + +def traverse_and_find(node, height, current_height): + global result + #print(current_height, node) + if current_height == height: + result.append(node.value) + if node.left: + traverse_and_find(node.left, height, current_height+1) + if node.right: + traverse_and_find(node.right, height, current_height+1) + + +def valuesAtHeight(root, height): + # Fill this in. + traverse_and_find(root, height-1, 0) + +def main(): + global result + a = Node(1) + a.left = Node(2) + a.right = Node(3) + a.left.left = Node(4) + a.left.right = Node(5) + a.right.right = Node(7) + valuesAtHeight(a, 3) + print result + +main() diff --git a/theDailyProblem/findNonDuplicateNumber.py b/theDailyProblem/findNonDuplicateNumber.py new file mode 100644 index 0000000..be7c003 --- /dev/null +++ b/theDailyProblem/findNonDuplicateNumber.py @@ -0,0 +1,56 @@ +""" +Given a list of numbers, where every number shows up twice except for one number, find that one number. + +Example: +Input: [4, 3, 2, 4, 1, 3, 2] +Output: 1 +Here's the function signature: + +def singleNumber(nums): + # Fill this in. + +print singleNumber([4, 3, 2, 4, 1, 3, 2]) +# 1 + +Challenge: Find a way to do this using O(1) memory. +""" + +def findNonDuplicateNumbers(arr): + # Logic 0: Using dictionary or any extra space would be easy solve but the question asks to not use extra space + + # Logic 1: Sort and look for adjacent elements to be different, the different element is the answer + """ + visited = None # o(1) one variable to store history + arr.sort() # Inplace sorting + for i in arr: + if i != visited: + return i + visited = i + return None + """ + + # Logic 2: Naive double lookup ( increasing the running time ) + """ + for i in range(len(arr)): + if arr[i] not in arr[i+1:] and arr[i] not in arr[:i]: # this takes an extra O(N) iteration + return arr[i] + return None + """ + + # Logic 3: operations (bitwise?) pending + + + # Practice: Set visted elements to a negative value - this logic is a practice to get repeated elements + for i in range(len(arr)): + print(arr) + if arr[abs(arr[i])] >= 0: + arr[abs(arr[i])] = -arr[abs(arr[i])] + else: + print(abs(arr[i]), end=" ") + + +def main(): + input = [4, 3, 2, 4, 1, 3, 2] + print(findNonDuplicateNumbers(input)) + +main() diff --git a/theDailyProblem/findSingleElementInArrayOfDuplicates.py b/theDailyProblem/findSingleElementInArrayOfDuplicates.py new file mode 100644 index 0000000..19498cf --- /dev/null +++ b/theDailyProblem/findSingleElementInArrayOfDuplicates.py @@ -0,0 +1,38 @@ +""" +Given an array of integers, arr, where all numbers occur twice except one number which occurs once, find the number. Your solution should ideally be O(n) time and use constant extra space. +Example: +Input: arr = [7, 3, 5, 5, 4, 3, 4, 8, 8] +Output: 7 +class Solution(object): + def findSingle(self, nums): + # Fill this in. + +nums = [1, 1, 3, 4, 4, 5, 6, 5, 6] +print(Solution().findSingle(nums)) +# 3 +""" + +class Solution(object): + def findSingle1(self, nums): + # Logic 1: Using Data Structure - Hashmap + import collections + counts = collections.Counter(nums) + for ele, count in counts.items(): + if count == 1: + return ele + return -1 + + def findSingle2(self, nums): + # Logic 2: Naive O(n) Iteration + elements = {} + for i in range(len(nums)): + if nums[i] in elements: + del elements[nums[i]] + else: + elements[nums[i]] = 1 + return elements.keys()[0] + +nums = [1, 1, 3, 4, 4, 5, 6, 5, 6] +print(Solution().findSingle1(nums)) +print(Solution().findSingle2(nums)) +# 3 diff --git a/theDailyProblem/firstAndLastIndex.py b/theDailyProblem/firstAndLastIndex.py new file mode 100644 index 0000000..f11ec19 --- /dev/null +++ b/theDailyProblem/firstAndLastIndex.py @@ -0,0 +1,75 @@ +""" +Given a sorted array, A, with possibly duplicated elements, find the indices of the first and last occurrences of a target element, x. Return -1 if the target is not found. + +Example: +Input: A = [1,3,3,5,7,8,9,9,9,15], target = 9 +Output: [6,8] + +Input: A = [100, 150, 150, 153], target = 150 +Output: [1,2] + +Input: A = [1,2,3,4,5,6,10], target = 9 +Output: [-1, -1] +Here is a function signature example: + +class Solution: + def getRange(self, arr, target): + # Fill this in. + +# Test program +arr = [1, 2, 2, 2, 2, 3, 4, 7, 8, 8] +x = 2 +print(Solution().getRange(arr, x)) +# [1, 4] +""" + +class Solution: + def getRange(self, arr, target): + + # Logic 1: 2 pointer method - left and right pointer to converge - worst case O(N2) + """ + left = 0 + right = len(arr)-1 + while left < len(arr) and arr[left] != target: + left += 1 + if left == len(arr): + left = -1 + while right > 0 and arr[right] != target: + right -= 1 + if right == 0: + right = -1 + return [left, right] + """ + + # Logic 2: 2 pointer O(N) Iteration + left = 0 + left_range = -1 + right = len(arr)-1 + right_range = -1 + while left < right and (left_range == -1 or right_range == -1): + if arr[left] == target and left_range == -1: + left_range = left + if arr[right] == target and right_range == -1: + right_range = right + if left_range == -1: + left += 1 + if right_range == -1: + right -= 1 + return [left_range, right_range] + +def main(): + s = Solution() + arr = [1, 2, 2, 2, 2, 3, 4, 7, 8, 8] + x = 2 + print(s.getRange(arr, x) == [1,4]) + arr = [1,2,3,4,5,6,10] + x = 9 + print(s.getRange(arr,x) == [-1, -1]) + A = [1,3,3,5,7,8,9,9,9,15] + target = 9 + print(s.getRange(A, target) == [6, 8]) + A = [100, 150, 150, 153] + target = 150 + print(s.getRange(A, target) == [1, 2]) + +main() diff --git a/theDailyProblem/firstRecurringCharacter.py b/theDailyProblem/firstRecurringCharacter.py new file mode 100644 index 0000000..1747aeb --- /dev/null +++ b/theDailyProblem/firstRecurringCharacter.py @@ -0,0 +1,37 @@ +""" +Given a string, return the first recurring letter that appears. If there are no recurring letters, return None. + +Example: +Input: qwertty +Output: t + +Input: qwerty +Output: None +Here's some starter code: + +def first_recurring_char(s): + # Fill this in. + +print(first_recurring_char('qwertty')) +# t + +print(first_recurring_char('qwerty')) +# None +""" + +def first_recurring_char(s): + + # O(N) Iteration with Extra space + freq = {} + for i in range(len(s)): + if s[i] not in freq: + freq[s[i]] = 1 + else: + return s[i] + return None + +print(first_recurring_char('qwertty')) +# t + +print(first_recurring_char('qwerty')) +# None diff --git a/theDailyProblem/fixedPoint.py b/theDailyProblem/fixedPoint.py new file mode 100644 index 0000000..ccf6afe --- /dev/null +++ b/theDailyProblem/fixedPoint.py @@ -0,0 +1,42 @@ +""" +A fixed point in a list is where the value is equal to its index. So for example the list [-5, 1, 3, 4], 1 is a fixed point in the list since the index and value is the same. Find a fixed point (there can be many, just return 1) in a sorted list of distinct elements, or return None if it doesn't exist. + +Here is a starting point: + +def find_fixed_point(nums): + # Fill this in. + +print find_fixed_point([-5, 1, 3, 4]) +# 1 + +Can you do this in sublinear time? +""" + +# Linear time with O(N) would be a very obvious case - But we want to do sublinear time less than O(N) + +# Logic1 +# Binary search for the help? +# 0, 1, 2, 3, 4, 5 + +def find_fixed_point(nums): + left = 0 + right = len(nums) + fixed_point = None + while left < right: + mid = left+(right-left)//2 + target = nums[mid] + if mid < target: + right = mid + else: + left = mid + if right-left == 1: + if nums[left] == left: + fixed_point = left + elif nums[right] == right: + fixed_point = right + break + #print(left, right, target) + return fixed_point + +print find_fixed_point([-5, 1, 3, 4]) +print find_fixed_point([-5, 0, 2, 4, 5, 8]) diff --git a/theDailyProblem/flattenDictionary.py b/theDailyProblem/flattenDictionary.py new file mode 100644 index 0000000..859aacf --- /dev/null +++ b/theDailyProblem/flattenDictionary.py @@ -0,0 +1,68 @@ +""" +Given a nested dictionary, flatten the dictionary, where nested dictionary keys can be represented through dot notation. + +Example: +Input: { + 'a': 1, + 'b': { + 'c': 2, + 'd': { + 'e': 3 + } + } +} +Output: { + 'a': 1, + 'b.c': 2, + 'b.d.e': 3 +} +You can assume there will be no arrays, and all keys will be strings. + +Here's some starter code: + +def flatten_dictionary(d): + # Fill this in. + +d = { + 'a': 1, + 'b': { + 'c': 2, + 'd': { + 'e': 3 + } + } +} +print(flatten_dictionary(d)) +# {'a': 1, 'b.c': 2, 'b.d.e': 3} +""" + +def flatten_dictionary(d, ancestry, flat): + for key, value in d.items(): + + # Generate the ancestry key + if ancestry: + a = ancestry + "." + key + else: + a = key + + # Recurse or flatten dictionary + if isinstance(d[key], dict): + flatten_dictionary(d[key], a, flat) + else: + if a not in flat: + flat[a] = value + else: + print("array value") + return flat + +d = { + 'a': 1, + 'b': { + 'c': 2, + 'd': { + 'e': 3 + } + } +} +print(flatten_dictionary(d, "", {})) +print({'a': 1, 'b.c': 2, 'b.d.e': 3}) diff --git a/theDailyProblem/fullBinarySearchTree.py b/theDailyProblem/fullBinarySearchTree.py new file mode 100644 index 0000000..95264ea --- /dev/null +++ b/theDailyProblem/fullBinarySearchTree.py @@ -0,0 +1,121 @@ +""" +Given a binary tree, remove the nodes in which there is only 1 child, so that the binary tree is a full binary tree. + +So leaf nodes with no children should be kept, and nodes with 2 children should be kept as well. + +Here's a starting point: + +from collections import deque + +class Node(object): + def __init__(self, value, left=None, right=None): + self.left = left + self.right = right + self.value = value + def __str__(self): + q = deque() + q.append(self) + result = '' + while len(q): + num = len(q) + while num > 0: + n = q.popleft() + result += str(n.value) + if n.left: + q.append(n.left) + if n.right: + q.append(n.right) + num = num - 1 + if len(q): + result += "\n" + + return result + +def fullBinaryTree(node): + # Fill this in. + +# Given this tree: +# 1 +# / \ +# 2 3 +# / / \ +# 0 9 4 + +# We want a tree like: +# 1 +# / \ +# 0 3 +# / \ +# 9 4 + +tree = Node(1) +tree.left = Node(2) +tree.right = Node(3) +tree.right.right = Node(4) +tree.right.left = Node(9) +tree.left.left = Node(0) +print fullBinaryTree(tree) +# 1 +# 03 +# 94 +""" +from collections import deque + +class Node(object): + def __init__(self, value, left=None, right=None): + self.left = left + self.right = right + self.value = value + def __str__(self): + q = deque() + q.append(self) + result = '' + while len(q): + num = len(q) + while num > 0: + n = q.popleft() + result += str(n.value) + if n.left: + q.append(n.left) + if n.right: + q.append(n.right) + num = num - 1 + if len(q): + result += "\n" + + return result + + +# This wont work as we progress some node in a single node subtree might be complete, we need to find that and connect properly +# Add altered function with parent argument to fix this + +# Logic1: With parent argument +def fullBinaryTree(node, parent): + # Remove single nodes prior to avoid traversing them + if node.left and not node.right: + parent.left = node.left + fullBinaryTree(node.left, parent) + elif not node.left and node.right: + parent.right = node.right + fullBinaryTree(node.right, parent) + else: + # Traverse the binary search tree + if node.left: + fullBinaryTree(node.left, node) + if node.right: + fullBinaryTree(node.right, node) + + return node + +# Logic 2: Without parent argument + +def main(): + tree = Node(1) + tree.left = Node(2) + tree.right = Node(3) + tree.right.right = Node(4) + tree.right.left = Node(9) + tree.left.left = Node(0) + print fullBinaryTree(tree, tree) + +main() diff --git a/theDailyProblem/generateAllIpAddress.py b/theDailyProblem/generateAllIpAddress.py new file mode 100644 index 0000000..ad60052 --- /dev/null +++ b/theDailyProblem/generateAllIpAddress.py @@ -0,0 +1,35 @@ +""" +An IP Address is in the format of A.B.C.D, where A, B, C, D are all integers between 0 to 255. + +Given a string of numbers, return the possible IP addresses you can make with that string by splitting into 4 parts of A, B, C, D. + +Keep in mind that integers can't start with a 0! (Except for 0) + +Example: +Input: 1592551013 +Output: ['159.255.101.3', '159.255.10.13'] +def ip_addresses(s, ip_parts=[]): + # Fill this in. + +print ip_addresses('1592551013') +# ['159.255.101.3', '159.255.10.13'] +""" + +# + +def ip_addresses(s, index, path, oct): + if index == len(s)-1: + result.append(path[:-1]) + for i in range(1, 4): + #print(path, i, s[index:index+i]) + octet = path.split(".") + print(path, index, i, octet, s[index:index+i]) + if oct < 4 and s[index:index+i] and s[index:index+i][0] != "0" and int(octet[-1] + s[index:index+i]) <= 255: + ip_addresses(s, index+i, path+s[index:index+i]+"." , oct+1) + +result = [] +ip_addresses('1592551013', 0, "", 0) +print(result) +# ['159.255.101.3', '159.255.10.13'] + + diff --git a/theDailyProblem/generateBinarySearchTrees.py b/theDailyProblem/generateBinarySearchTrees.py new file mode 100644 index 0000000..76b4aa1 --- /dev/null +++ b/theDailyProblem/generateBinarySearchTrees.py @@ -0,0 +1,91 @@ +# One hacky recursive way to work... +""" +Given a number n, generate all binary search trees that can be constructed with nodes 1 to n. + +Here's some code to start with: + +class Node: + def __init__(self, value, left=None, right=None): + self.value = value + self.left = left + self.right = right + + def __str__(self): + result = str(self.value) + if self.left: + result = result + str(self.left) + if self.right: + result = result + str(self.right) + return result + +def generate_bst(n): + # Fill this in. + +for tree in generate_bst(3): + print tree + +# Pre-order traversals of binary trees from 1 to n. +# 123 +# 132 +# 213 +# 312 +# 321 + +# 1 1 2 3 3 +# \ \ / \ / / +# 2 3 1 3 1 2 +# \ / \ / +# 3 2 2 1 +""" +import copy +class Node: + def __init__(self, value, left=None, right=None): + self.value = value + self.left = left + self.right = right + + def __str__(self): + result = str(self.value) + if self.left: + result = result + str(self.left) + if self.right: + result = result + str(self.right) + return result + +def generate_bst(n): + trees = [] + ns = range(1, n+1) + def construct_tree(nodes, parent, ancestor): + if not nodes: + return + for i in range(len(nodes)): + #print("hi", parent) + root = Node(nodes[i]) + if parent == None: + ancestor = root + if parent and root.value < parent.value: + parent.left = root + elif parent: + parent.right = root + left = nodes[:i][::-1] + right = nodes[i+1:] + if left: + construct_tree(left, root, ancestor) + if right: + construct_tree(right, root, ancestor) + if parent == ancestor and len(str(ancestor)) == n: + #print("OOO") + #print(ancestor) + #print(root.value, ancestor.value) + trees.append(copy.deepcopy(ancestor)) + #print(trees) + #ancestor = None + construct_tree(ns, None, None) + #print(trees) + return trees + +for tree in generate_bst(3): + print tree + +for tree in generate_bst(5): + print tree diff --git a/theDailyProblem/heightBalancedBinaryTree.py b/theDailyProblem/heightBalancedBinaryTree.py new file mode 100644 index 0000000..3adeec9 --- /dev/null +++ b/theDailyProblem/heightBalancedBinaryTree.py @@ -0,0 +1,81 @@ +""" +Given a tree, find if the binary tree is height balanced or not. A height balanced binary tree is a tree where every node's 2 subtree do not differ in height by more than 1. + +Here's some starter code: + +class Node: + def __init__(self, value, left=None, right=None): + self.value = value + self.left = left + self.right = right + +def is_height_balanced(tree): + # Fill this in. + +# 1 +# / \ +# 2 3 +# / +# 4 +n4 = Node(4) +n3 = Node(3) +n2 = Node(2, n4) +n1 = Node(1, n2, n3) + +print(is_height_balanced(n1)) +# True + +# 1 +# / +# 2 +# / +# 4 +n1 = Node(1, n2) +print(is_height_balanced(n1)) +# False +""" + +class Node: + def __init__(self, value, left=None, right=None): + self.value = value + self.left = left + self.right = right + +def find_height(node): + if not node: + return -1 + else: + return 1 + max(find_height(node.left), find_height(node.right)) + +def is_height_balanced(tree): + + if tree.left: + is_height_balanced(tree.left) + if tree.right: + is_height_balanced(tree.right) + + if abs(find_height(tree.right)-find_height(tree.left)) <= 1: + return True + else: + return False + +# 1 +# / \ +# 2 3 +# / +# 4 +n4 = Node(4) +n3 = Node(3) +n2 = Node(2, n4) +n1 = Node(1, n2, n3) + +print(is_height_balanced(n1)) +# True + +# 1 +# / +# 2 +# / +# 4 +n1 = Node(1, n2) +print(is_height_balanced(n1)) diff --git a/theDailyProblem/kthLargestElement.py b/theDailyProblem/kthLargestElement.py new file mode 100644 index 0000000..5960c1c --- /dev/null +++ b/theDailyProblem/kthLargestElement.py @@ -0,0 +1,23 @@ +""" +Given a list, find the k-th largest element in the list. +Input: list = [3, 5, 2, 4, 6, 8], k = 3 +Output: 5 +Here is a starting point: + +def findKthLargest(nums, k): + # Fill this in. + +print findKthLargest([3, 5, 2, 4, 6, 8], 3) +# 5 +""" + +def findKthLargest(nums, k): + # Write any sorting algo or use inbuilt to sort + nums.sort() + # return the index from the reverse + return nums[::-1][k-1] + +def heapWay(nums, k): + + +print findKthLargest([3, 5, 2, 4, 6, 8], 4) diff --git a/theDailyProblem/largestProductOf3ElementsInArray.py b/theDailyProblem/largestProductOf3ElementsInArray.py new file mode 100644 index 0000000..fdcf2f2 --- /dev/null +++ b/theDailyProblem/largestProductOf3ElementsInArray.py @@ -0,0 +1,118 @@ +""" +You are given an array of integers. Return the largest product that can be made by multiplying any 3 integers in the array. + +Example: + +[-4, -4, 2, 8] should return 128 as the largest product can be made by multiplying -4 * -4 * 8 = 128. + +Here's a starting point: + +def maximum_product_of_three(lst): + # Fill this in. + +print maximum_product_of_three([-4, -4, 2, 8]) +# 128 +""" + +class Solution(object): + def maximumProduct(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + + # Logic 1: + # * Track 2 sorted array of length 3 for negative and positive numbers + # * Round about logic + # * Perform product and return max + """ + def insert_to_array(num, array): + # descending sorted array arrangement of 3 elements size + if not array: + array.append(num) + else: + if abs(num) >= abs(array[-1]): + array.append(num) + elif abs(num) <= abs(array[0]): + array = [num] + array + elif len(array) == 3 and abs(num) > abs(array[1]): + array = [array[0]] + [num] + [array[-1]] + else: + array = [array[0]] + [num] + [array[-1]] + print(array) + if len(array) > 3: + array = array[1:] + return array + + def product(array): + p = 1 + for n in array: + p *= n + return p + + def maximum_product_of_three(a): + negative_descending = [] + positive_descending = [] + for i in range(len(a)): + # negative number + if a[i] < 0: + negative_descending = insert_to_array(a[i], negative_descending) + else: + positive_descending = insert_to_array(a[i], positive_descending) + if positive_descending: + p_p = product(positive_descending) + else: + p_p = -float('inf') + #if len(negative_descending) >= 2: + # if positive_descending and positive_descending[-1] > abs(negative_descending[-1]): + # n_p = product([positive_descending[-1], negative_descending[-1], negative_descending[-1]]) + # else: + # n_p = product(negative_descending) + #else: + # n_p = 0 + if negative_descending: + n_p = product(negative_descending) + else: + n_p = 0 + if positive_descending and len(negative_descending) >= 2: + np = product([positive_descending[-1], negative_descending[-1], negative_descending[-2]]) + else: + np = -float('inf') + print(positive_descending, negative_descending, n_p, p_p) + return max(p_p, n_p, np) + + return maximum_product_of_three(nums) + """ + + # Logic 2: + # * Use absolute value of the elements to sort + """ + nums = sorted(nums, key=lambda x: abs(x), reverse=True) + print(nums) + + # All negative elements + if nums[0] < 0: + return nums[0]*nums[1]*nums[2] + + max_product = nums[0] + count = 1 + + # Mix of positive and negative elements + i = 1 + while count < 3: + if nums[i] < 0: + if nums[i+1] < 0 and count == 1: + return max_product*nums[i]*nums[i+1] + else: + max_product *= nums[i] + count += 1 + i += 1 + return max_product + """ + + # Logic 3 + nums = sorted(nums, reverse=True) + positive_max = nums[0]*nums[1]*nums[2] + negative_max = nums[0]*nums[-1]*nums[-2] + return max(positive_max, negative_max) + diff --git a/theDailyProblem/longestIncreasingSubSequence.py b/theDailyProblem/longestIncreasingSubSequence.py new file mode 100644 index 0000000..9477913 --- /dev/null +++ b/theDailyProblem/longestIncreasingSubSequence.py @@ -0,0 +1,42 @@ +# Pending... +""" +You are given an array of integers. Return the length of the longest increasing subsequence (not necessarily contiguous) in the array. + +Example: +[0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15] + +The following input should return 6 since the longest increasing subsequence is 0, 2, 6, 9 , 11, 15. +""" + +# Logic 1: Contiguous sub-array of increasing subsequence +def longest_increasing_subsequence(array): + pointer = 0 + maxi = 0 + current = 0 + while pointer < len(array)-1: + if array[pointer+1] < array[pointer]: + maxi = max(maxi, current) + current = 0 + else: + current += 1 + pointer += 1 + return maxi + +# Logic 1: Non Contiguous sub-array of increasing subsequence - worst case +# * Lets do recursive to go over all possible increasing subsequence +# O(N**2) +def longest_increasing_worst_case(index, array): + maxi_length = 1 + for i in range(index, len(array)): + if array[i] > array[index]: + maxi_length = max(maxi_length, 1+longest_increasing_worst_case(i, array)) + return maxi_length + +def main(): + nums = [0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15] + # ANother loop as start can be any index + maxi = 0 + for i in range(len(nums)): + maxi = max(maxi, longest_increasing_worst_case(i, nums)) + print(maxi) +main() diff --git a/theDailyProblem/longestPalindromeSubstring.py b/theDailyProblem/longestPalindromeSubstring.py new file mode 100644 index 0000000..efdd2b3 --- /dev/null +++ b/theDailyProblem/longestPalindromeSubstring.py @@ -0,0 +1,116 @@ +""" +Input: "banana" +Output: "anana" + +Input: "million" +Output: "illi" +class Solution: + def longestPalindrome(self, s): + # Fill this in. + +# Test program +s = "tracecars" +print(str(Solution().longestPalindrome(s))) +# racecar +""" + +class Solution: + def longestPalindrome(self, s): + + # Logic 2: left and right pointer testing all the possible substrings and exiting on the first match + # * Going worst case by iterating the left for each right index + left = 0 + right = len(s) + while right > 0: + left = 0 + while (right-left) > 1: + #print(s[left:right]) + if s[left:right] == s[left:right][::-1]: + return s[left:right] + left += 1 + right -= 1 + return "" + + # Logic 1: 2 pointer logic - use a left and right pointer to traverse all possible substrings + # * maintaining the order of the elements in the array + # * return on the first substring palindrome hit + """ + left = 0 + right = len(s)+1 + while left < right: + if s[left:right] == s[left:right][::-1]: + return s[left:right] + """ + # Will this logic tackle a[1//2:] and a[:1//2] being a palindrome? + + # Logic 0: Thoughts O(N) logic wont work as the palindrome would not be fixed on any index + +class Solution(object): + def longestPalindrome(self, s): + """ + :type s: str + :rtype: str + """ + + # Logic 1: 2 pointer method - Moving from right towards the left or vice versa - Failure + # * Solves some testcases but not everything + """ + left = 0 + right = len(s) + if right == 0: + return "" + elif len(set(s)) == 1: + return s + elif right <= 2: + return s[0] + while right > 0: + left = 0 + while (right-left) > 1: + #print(s[left:right]) + if s[left:right] == s[left:right][::-1]: + return s[left:right] + left += 1 + right -= 1 + return "" + """ + + # Logic 2: 100 pass 87% - Same 2 pointer expanding from an index outward. Gist obtained from the logic at https://leetcode.com/problems/longest-palindromic-substring/discuss/2954/Python-easy-to-understand-solution-with-comments-(from-middle-to-two-ends). + # * Start from the middle and expand for every index + # * Iterate O(N) and at every current index expand for a longest palindrome match + + def expand_window(string, left, right): + # Boundary of palindrome is when the characters at the end are equal + # left equal to 0 while right should be lesser than length of string always + while left >= 0 and right < len(string) and string[left] == string[right]: + left -= 1 + right += 1 + return string[left+1:right] + + # Palindrome can be 2 types + # * Odd length palindrome has a center character different like abcba + # * Even length palindrome is symmetric abba + result= "" + for i in range(len(s)): + # Odd length palindrome - expand from the same index + palindrome_substring = expand_window(s, i, i) + if len(palindrome_substring) > len(result): + result = palindrome_substring + # Even length palindrome - expand from next index so we can find the equal internal elem + palindrome_substring = expand_window(s, i, i+1) + if len(palindrome_substring) > len(result): + result = palindrome_substring + return result + +def main(): + s = Solution() + question = "banana" + print( question, s.longestPalindrome(question)) + assert "anana", s.longestPalindrome(question) + question = "million" + print( question, s.longestPalindrome(question)) + assert "illi", s.longestPalindrome(question) + question = "racecar" + print( question, s.longestPalindrome(question)) + assert "racecar", s.longestPalindrome(question) + +main() diff --git a/theDailyProblem/makeNonDecreasingWithOneChange.py b/theDailyProblem/makeNonDecreasingWithOneChange.py new file mode 100644 index 0000000..c404b3e --- /dev/null +++ b/theDailyProblem/makeNonDecreasingWithOneChange.py @@ -0,0 +1,74 @@ +""" +You are given an array of integers in an arbitrary order. Return whether or not it is possible to make the array non-decreasing by modifying at most 1 element to any value. + +We define an array is non-decreasing if array[i] <= array[i + 1] holds for every i (1 <= i < n). + +Example: + +[13, 4, 7] should return true, since we can modify 13 to any value 4 or less, to make it non-decreasing. + +[13, 4, 1] however, should return false, since there is no way to modify just one element to make the array non-decreasing. + +Here is the function signature: + +def check(lst): + # Fill this in. + +print check([13, 4, 7]) +# True +print check([5,1,3,2,5]) +# False + +Can you find a solution in O(n) time? +""" + +def makeNonDecreasingWithOneChange(a): + """ + :type nums: List[int] + :rtype: bool + """ + + # Logic 1: Check if more than one violation is found + # Doesnt work for 3,4,2,3 + """ + violation = 0 + n = len(a) + for i in range(n-1): + if a[i] > a[i+1]: + violation += 1 + if violation > 1: + return False + if violation > 1: + return False + return True + """ + + # Improv Logic 1: 100 pass 85% faster + # Improvise above logic with popping one element and checking the same condition around it (i-1 and i+2 of the pair) + violation = 0 + n = len(a) + for i in range(n-1): + if a[i] > a[i+1]: + violation += 1 + if violation > 1 or ((i-1>=0 and i+1 < n and a[i-1] > a[i+1]) and (i+2 < n and a[i] > a[i+2])) : + return False + return True + + + # Logic 2 - Match remaining with sorted after the first violation ( check either way i and i+1 ) - 100 pass 25% faster + """ + n = len(a) + for i in range(n-1): + if a[i] > a[i+1]: + if a[:i]+a[i+1:] != sorted(a[:i]+a[i+1:]) and a[:i+1]+a[i+2:] != sorted(a[:i+1]+a[i+2:]): + return False + return True + """ + +def main(): + a = [ 13, 4, 7] + b = [ 5, 1, 3, 2, 5] + print(makeNonDecreasingWithOneChange(a)) + print(makeNonDecreasingWithOneChange(b)) + +main() diff --git a/theDailyProblem/makingAHeightBalancedBinarySearchTree.py b/theDailyProblem/makingAHeightBalancedBinarySearchTree.py new file mode 100644 index 0000000..8ab9dbc --- /dev/null +++ b/theDailyProblem/makingAHeightBalancedBinarySearchTree.py @@ -0,0 +1,64 @@ +""" +class Node: + def __init__(self, value, left=None, right=None): + self.value = value + self.left = left + self.right = right + + def __str__(self): + answer = str(self.value) + if self.left: + answer += str(self.left) + if self.right: + answer += str(self.right) + return answer + +def create_height_balanced_bst(nums): + # Fill this in. + +tree = create_height_balanced_bst([1, 2, 3, 4, 5, 6, 7, 8]) +# 53214768 +# (pre-order traversal) +# 5 +# / \ +# 3 7 +# / \ / \ +# 2 4 6 8 +# / +# 1 +""" + +class Node: + def __init__(self, value, left=None, right=None): + self.value = value + self.left = left + self.right = right + + def __str__(self): + answer = str(self.value) + if self.left: + answer += str(self.left) + if self.right: + answer += str(self.right) + return answer + +def create_height_balanced_bst(nums): + # To make it perfetly balanced with difference at most 1, break in the middle + mid = len(nums)//2 + # Middle would be the current subtree root, set left and right + left, right = None, None + # Create left subtree and get the left subtree root + if nums[:mid]: + left = create_height_balanced_bst(nums[:mid]) + # Create right subtree and get the right subtree root + if nums[mid+1:]: + right = create_height_balanced_bst(nums[mid+1:]) + # Create the current subtree root node and set left and right + n = Node(nums[mid]) + n.left = left + n.right = right + # Return current subtree node to recursively build + return n + +print create_height_balanced_bst([1, 2, 3, 4, 5, 6, 7, 8]) + diff --git a/theDailyProblem/mergeKLinkedList.py b/theDailyProblem/mergeKLinkedList.py new file mode 100644 index 0000000..ba9f920 --- /dev/null +++ b/theDailyProblem/mergeKLinkedList.py @@ -0,0 +1,112 @@ +""" +# You are given an array of k sorted singly linked lists. Merge the linked lists into a single sorted linked list and return it. +class Node(object): + def __init__(self, val, next=None): + self.val = val + self.next = next + + def __str__(self): + c = self + answer = "" + while c: + answer += str(c.val) if c.val else "" + c = c.next + return answer + + def get_list(self): + c = self + answer = [] + while c: + answer.append(str(c.val) if c.val else "") + c = c.next + return answer + +def merge(lists): + # Fill this in. + +a = Node(1, Node(3, Node(5))) +b = Node(2, Node(4, Node(6))) +print merge([a, b]) +# 123456 +""" + +# Structure to create each node and link the next (eventually the full linked list) +class Node(object): + def __init__(self, val, next=None): + self.val = val + self.next = next + + def __str__(self): + c = self + answer = "" + while c: + answer += str(c.val) if c.val else "" + c = c.next + return answer + + def get_list(self): + c = self + answer = [] + while c: + answer.append(str(c.val) if c.val else "") + c = c.next + return answer + +def merge(lists): + # Pointers to store the start of each list ( avoid iterations and have a key to indicate start: say "-1" ) + pointers = [-1]*len(lists) + # Resulting linked list to hold all merged nodes + result = None + ans = None + min_next = None + # Iterate until all the lists have been iterated ( that is None for every linkedlist ) + while set(pointers) != set([None]): + #print(min_next) + if min_next != None: + if result == None: + result = Node(pointers[min_next].val) + if ans == None: + ans = result + else: + result.next = Node(pointers[min_next].val) + result = result.next + if pointers[min_next]: + pointers[min_next] = pointers[min_next].next + #print([p.val if p != -1 and p != None else str(p) for p in pointers], min_next, result.val if result != None else result) + pointer = 0 + min_next = 0 + while pointer < len(pointers): + # Set the head node of each linkedlist when the indicator is hit + if pointers[pointer] != None: + if pointers[pointer] == -1: + pointers[pointer] = lists[pointer] + if pointers[min_next] == None: + min_next = pointer + elif pointers[pointer].val < pointers[min_next].val: + min_next = pointer + print(min_next) + pointer += 1 + return ans + +def merge2(lists): + result = [] + ans = None + head = None + for list in lists: + result.extend(list.get_list()) + result.sort() + for val in result: + current_node = Node(val) + if ans == None: + ans = current_node + head = ans + else: + ans.next = current_node + ans = ans.next + return head + +a = Node(1, Node(3, Node(5))) +b = Node(2, Node(4, Node(6))) +print(merge([a, b])) +print(merge2([a, b])) + diff --git a/theDailyProblem/mostFrequentSubtreeSum.py b/theDailyProblem/mostFrequentSubtreeSum.py new file mode 100644 index 0000000..5e2cbcf --- /dev/null +++ b/theDailyProblem/mostFrequentSubtreeSum.py @@ -0,0 +1,54 @@ +""" +Given a binary tree, find the most frequent subtree sum. + +Example: + + 3 + / \ + 1 -3 + +The above tree has 3 subtrees. The root node with 3, and the 2 leaf nodes, which gives us a total of 3 subtree sums. The root node has a sum of 1 (3 + 1 + -3), the left leaf node has a sum of 1, and the right leaf node has a sum of -3. Therefore the most frequent subtree sum is 1. + +If there is a tie between the most frequent sum, you can return any one of them. + +Here's some starter code for the problem: + +class Node(): + def __init__(self, value, left=None, right=None): + self.val = value + self.left = left + self.right = right + +def most_freq_subtree_sum(root): + # fill this in. + +root = Node(3, Node(1), Node(-3)) +print(most_freq_subtree_sum(root)) +# 1 +""" + +class Node(): + def __init__(self, value, left=None, right=None): + self.val = value + self.left = left + self.right = right + +def traverse(node): + global maxi + if not node: + return 0 + current_sum = node.val + traverse(node.left) + traverse(node.right) + if current_sum not in sums: + sums[current_sum] = 0 + sums[current_sum] += 1 + if sums[current_sum] > maxi: + maxi = sums[current_sum] + return current_sum + +sums = {} +maxi = 0 +root = Node(3, Node(1), Node(-3)) +traverse(root) +print([k for k,v in sums.items() if v == maxi]) +# 1 + diff --git a/theDailyProblem/moveZeros.py b/theDailyProblem/moveZeros.py new file mode 100644 index 0000000..afbcdf5 --- /dev/null +++ b/theDailyProblem/moveZeros.py @@ -0,0 +1,45 @@ +""" +Given an array nums, write a function to move all 0's to the end of it while maintaining the relative order of the non-zero elements. + +Example: +Input: [0,1,0,3,12] +Output: [1,3,12,0,0] +You must do this in-place without making a copy of the array. +Minimize the total number of operations. + +Here is a starting point: + +class Solution: + def moveZeros(self, nums): + # Fill this in. + +nums = [0, 0, 0, 2, 0, 1, 3, 4, 0, 0] +Solution().moveZeros(nums) +print(nums) +# [2, 1, 3, 4, 0, 0, 0, 0, 0, 0] +""" + +class Solution: + + # O(N) and 1 pointer method + def moveZeros2(nums): + zero = None + for i in range(len(nums)): + if nums[i] == 0: + if zero is None: + zero = i + else: + nums[zero], nums[i] = nums[i], nums[zero] + zero += 1 + return nums + +def main(): + nums = [ + [0, 0, 0, 2, 0, 1, 3, 4, 0, 0], + [ 0, 1, 0, 3, 12] + ] + for num in nums: + Solution.moveZeros2(num) + print(num) + +main() diff --git a/theDailyProblem/multiTasking.py b/theDailyProblem/multiTasking.py new file mode 100644 index 0000000..ed44505 --- /dev/null +++ b/theDailyProblem/multiTasking.py @@ -0,0 +1,27 @@ +""" +We have a list of tasks to perform, with a cooldown period. We can do multiple of these at the same time, but we cannot run the same task simultaneously. + +Given a list of tasks, find how long it will take to complete the tasks in the order they are input. +tasks = [1, 1, 2, 1] +cooldown = 2 +output: 7 (order is 1 _ _ 1 2 _ 1) +def findTime(arr, cooldown): + # Fill this in. + +print findTime([1, 1, 2, 1], 2) +# 7 +""" + +def findTime(arr, cooldown): + time = 0 + tasks = set() + while arr: + if arr[0] not in tasks: + tasks.add(arr.pop(0)) + else: + time += len(tasks) + abs(len(tasks)-1-cooldown) + print(tasks, time) + tasks = set() + return time+len(tasks) + +print findTime([1, 1, 2, 1], 2) diff --git a/theDailyProblem/nearestPoints.py b/theDailyProblem/nearestPoints.py new file mode 100644 index 0000000..0f91135 --- /dev/null +++ b/theDailyProblem/nearestPoints.py @@ -0,0 +1,51 @@ +""" +Given a list of points, an interger k, and a point p, find the k closest points to p. + +Here's an example and some starter code: + +class Point: + def __init__(self, x=0, y=0): + self.x = x + self.y = y + + def __repr__(self): + return f"({self.x}, {self.y})" + +def closest_points(points, k, p): + # Fill this in. + +points = [ + Point(0, 0), + Point(1, 1), + Point(2, 2), + Point(3, 3), +] +print(closest_points(points, 2, Point(0, 2))) +# [(0, 0), (1, 1)] +""" + +class Point: + def __init__(self, x=0, y=0): + self.x = x + self.y = y + + def __repr__(self): + return str((self.x, self.y)) + +def distance(p1, p2): + import math + return math.sqrt((p2.x-p1.x)**2+(p2.y-p1.y)**2) + +def closest_points(points, k, p): + points = sorted(points, key=lambda x: distance(x, p)) + return points[:k] + +points = [ + Point(0, 0), + Point(1, 1), + Point(2, 2), + Point(3, 3), +] +print(closest_points(points, 2, Point(0, 2))) +# [(0, 0), (1, 1)] + diff --git a/theDailyProblem/noAdjacentRepeatingCharacters.py b/theDailyProblem/noAdjacentRepeatingCharacters.py new file mode 100644 index 0000000..c23f7ef --- /dev/null +++ b/theDailyProblem/noAdjacentRepeatingCharacters.py @@ -0,0 +1,29 @@ +""" +Given a string, rearrange the string so that no character next to each other are the same. If no such arrangement is possible, then return None. + +Example: +Input: abbccc +Output: cbcbca +def rearrangeString(s): + # Fill this in. + +print rearrangeString('abbccc') +# cbcabc +""" + +def rearrangeString(s): + # Logic 1: O(N) arrangement + s = list(s) + for i in range(len(s)): + if i+1 < len(s) and s[i+1] == s[i]: + j = i+1 + while s[j] == s[i] and s[i-1] == s[i]: + j += 1 + if j == len(s): + s[i], s[0] = s[0], s[i] + else: + s[i], s[j] = s[j], s[i] + return s + +print rearrangeString('abbccc') +# cbcabc diff --git a/theDailyProblem/numberOfCousins.py b/theDailyProblem/numberOfCousins.py new file mode 100644 index 0000000..7299804 --- /dev/null +++ b/theDailyProblem/numberOfCousins.py @@ -0,0 +1,72 @@ +""" +Given a binary tree and a given node value, return all of the node's cousins. Two nodes are considered cousins if they are on the same level of the tree with different parents. You can assume that all nodes will have their own unique value. + +Here's some starter code: + +class Node(object): + def __init__(self, value, left=None, right=None): + self.value = value + self.left = left + self.right = right + +class Solution(object): + def list_cousins(self, tree, val): + # Fill this in. + +# 1 +# / \ +# 2 3 +# / \ \ +# 4 6 5 +root = Node(1) +root.left = Node(2) +root.left.left = Node(4) +root.left.right = Node(6) +root.right = Node(3) +root.right.right = Node(5) + +print Solution().list_cousins(root, 5) +# [4, 6] +""" + +class Node(object): + def __init__(self, value, left=None, right=None): + self.val = value + self.left = left + self.right = right + +class Solution(object): + def list_cousins(self, tree, val): + levels = {} + self.current_node_level = None + def traverse(node, val, level): + if not node: + return + if level not in levels: + levels[level] = [] + #print(node.val == val) + if node.val == val: + self.current_node_level = level + else: + levels[level].append(node.val) + traverse(node.left, val, level+1) + traverse(node.right, val, level+1) + + traverse(tree, val, 0) + #print(levels, self.current_node_level) + return levels[self.current_node_level] + +# 1 +# / \ +# 2 3 +# / \ \ +# 4 6 5 +root = Node(1) +root.left = Node(2) +root.left.left = Node(4) +root.left.right = Node(6) +root.right = Node(3) +root.right.right = Node(5) + +print Solution().list_cousins(root, 5) +# [4, 6] diff --git a/theDailyProblem/numberOfMeetings.py b/theDailyProblem/numberOfMeetings.py new file mode 100644 index 0000000..58dca18 --- /dev/null +++ b/theDailyProblem/numberOfMeetings.py @@ -0,0 +1,64 @@ +""" +Given a list of meetings that will happen during a day, find the minimum number of meeting rooms that can fit all meetings. + +Each meeting will be represented by a tuple of (start_time, end_time), where both start_time and end_time will be represented by an integer to indicate the time. start_time will be inclusive, and end_time will be exclusive, meaning a meeting of (0, 10) and (10, 20) will only require 1 meeting room. + +Here's some examples and some starting code: + +def meeting_rooms(meetings): + # Fill this in. + +# print 1 +print(meeting_rooms([(0, 10), (10, 20)])) +# 1 + +print(meeting_rooms([(20, 30), (10, 21), (0, 50)])) +# 3 (all meetings overlap at time 20) +""" + +# Logic 2: +def meeting_rooms(meetings): + schedule = {} + meetings.sort() + for meet in meetings: + if schedule: + room = 1 + while room in schedule and schedule[room][1] > meet[0]: + room += 1 + schedule[room] = meet + else: + schedule[1] = meet + return len(schedule.keys()) + +""" +# Logic 1: Naive try works for the cases below but fails in leetcode. So new logic above +def meeting_rooms(meetings): + schedule = {} + rooms = 0 + for meet in meetings: + booked = False + if rooms: + for room in range(1, rooms+1): + last_meeting = schedule[room] + if last_meeting[1] > meet[0]: + rooms += 1 + schedule[rooms] = meet + booked = True + else: + schedule[rooms] = meet + booked = True + if booked: + break + else: + rooms += 1 + schedule[rooms] = meet + print(schedule) + return rooms +""" + +# print 1 +print(meeting_rooms([(0, 10), (10, 20)])) +# 1 + +print(meeting_rooms([(20, 30), (10, 21), (0, 50)])) +# 3 (all meetings overlap at time 20) diff --git a/theDailyProblem/productOfArrayExceptSelf.py b/theDailyProblem/productOfArrayExceptSelf.py new file mode 100644 index 0000000..51ffef0 --- /dev/null +++ b/theDailyProblem/productOfArrayExceptSelf.py @@ -0,0 +1,68 @@ +""" +You are given an array of integers. Return an array of the same size where the element at each index is the product of all the elements in the original array except for the element at that index. + +For example, an input of [1, 2, 3, 4, 5] should return [120, 60, 40, 30, 24]. + +You cannot use division in this problem. + +def products(nums): + # Fill this in. + +print products([1, 2, 3, 4, 5]) +# [120, 60, 40, 30, 24] +""" + +# Logic 1 with division, refresher +# O(N) to calculate the product +def nums_division(nums): + product = 1 + for element in nums: + product *= element + for i in range(len(nums)): + nums[i] = product//nums[i] + return nums + +# The most naive method (worst case) +def product(nums): + product = 1 + for element in nums: + product *= element + return product + +def products(nums): + new = [1]*len(nums) + for i in range(len(nums)): + new[i] = product(nums[:i]+nums[i+1:]) + return new + +# O(N) Method +# * Bisect the array --> moving left and right from there gives the products +# [ 1 2 3 4 5 ] +# 2345 1345 1245 1235 1234 +# Left -> Right +# 0 1 1*2 2*3 2*3*4 +# 2*3*4*5 3*4*5 4*5 5 0 +# Right<- Left +# O(N) + O(N) ==> O(2N) ==> O(N) +def o_of_n(nums): + n = len(nums) + results = [1]*n + left = 1 + for i in range(n): + if i > 0: + left *= nums[i-1] + results[i] = left + print(results) + right = 1 + for i in range(n-1, -1, -1): + if i < n-1: + right *= nums[i+1] + results[i] *= right + return results + +def main(): + array = [1, 2, 3, 4, 5] + #print(nums_division(array)) + #print(products(array)) + print(o_of_n(array)) +main() diff --git a/theDailyProblem/removeCharacterToCreatePalindrome.py b/theDailyProblem/removeCharacterToCreatePalindrome.py new file mode 100644 index 0000000..3bea35e --- /dev/null +++ b/theDailyProblem/removeCharacterToCreatePalindrome.py @@ -0,0 +1,79 @@ +""" +Given a string, determine if you can remove any character to create a palindrome. + +Here's some examples and some starter code: + +def create_palindrome(s): + # Fill this in. + +print(create_palindrome("abcdcbea")) +# True +print(create_palindrome("abccba")) +# False +print(create_palindrome("abccaa")) +# False +""" + +def create_palindrome(A): + + # Logic 1: 2 pointer method - 100 pass + left = 0 + right = len(A)-1 + remove = False # to track only one remove + # Iterating until left < right --> + # Even length: the last i vs i+1 are both equal + # Odd length: the last i is unique so we do not care + while left < right: + if A[left] == A[right]: + left += 1 + right -= 1 + elif A[left+1] == A[right] and not remove: + remove = True + left += 1 + elif A[right-1] == A[left] and not remove: + remove = True + right -= 1 + else: + return False + if remove: + return True + else: + return False + +def create_palindrome_2(A): + n = len(A) + for i in range(n): + mid = n//2 + if n%2 != 0 and i != mid: # ODD LENGTH STRING + if A[i] != A[-i-1]: + possible1 = A[:i]+A[i+1:] + j = n-i-1 + possible2 = A[:j]+A[j+1:] + if (possible1 == possible1[::-1]) or (possible2 == possible2[::-1]): + return True + else: + return False + elif n%2 == 0: # EVEN LENGTH STRING + if A[i] != A[-i-1]: + possible1 = A[:i]+A[i+1:] + j = n-i-1 + possible2 = A[:j]+A[j+1:] + if (possible1 == possible1[::-1]) or (possible2 == possible2[::-1]): + return True + else: + return False + return False + +print(create_palindrome("abcdcbea")) +# True +print(create_palindrome("abccba")) +# False +print(create_palindrome("abccaa")) +# False + +print(create_palindrome_2("abcdcbea")) +# True +print(create_palindrome_2("abccba")) +# False +print(create_palindrome_2("abccaa")) +# False diff --git a/theDailyProblem/reverseALinkedList.py b/theDailyProblem/reverseALinkedList.py new file mode 100644 index 0000000..377994d --- /dev/null +++ b/theDailyProblem/reverseALinkedList.py @@ -0,0 +1,129 @@ +# Reverse a Linked List + +""" +Given a singly-linked list, reverse the list. This can be done iteratively or recursively. Can you get both solutions? + +Example: +Input: 4 -> 3 -> 2 -> 1 -> 0 -> NULL +Output: 0 -> 1 -> 2 -> 3 -> 4 -> NULL +class ListNode(object): + def __init__(self, x): + self.val = x + self.next = None + + # Function to print the list + def printList(self): + node = self + output = '' + while node != None: + output += str(node.val) + output += " " + node = node.next + print(output,) + + # Iterative Solution + def reverseIteratively(self, head): + # Implement this. + + # Recursive Solution + def reverseRecursively(self, head): + # Implement this. + +# Test Program +# Initialize the test list: +testHead = ListNode(4) +node1 = ListNode(3) +testHead.next = node1 +node2 = ListNode(2) +node1.next = node2 +node3 = ListNode(1) +node2.next = node3 +testTail = ListNode(0) +node3.next = testTail + +print("Initial list: ") +testHead.printList() +# 4 3 2 1 0 +testHead.reverseIteratively(testHead) +#testHead.reverseRecursively(testHead) +print("List after reversal: ") +testTail.printList() +# 0 1 2 3 4 +""" + +class Node: + def __init__(self, value): + self.val = value + self.next = None + +class Solution: + def reverse_linked_list_iterative(self, node): + # Logic 1: using extra space to keep track of visited nodes + """ + stack = [] + head = node + while node: + stack.append(node) + node = node.next + while stack: + print(stack) + first, last = None, None + if stack: + last = stack.pop() + if stack: + first = stack.pop(0) + if last and first: + print(last.val, first.val) + last.val, first.val = first.val, last.val + return head + """ + + # Logic 2: inverting next pointers as we visit and go to the next node + reverse_pointer = None + head = None + while node: + if node.next is None: + head = node + current_node = node # Store the current node reference + node = node.next # Move node to the next node to not loose pointer + current_node.next = reverse_pointer + reverse_pointer = current_node + return head + + def reverse_linked_list_recursive(self, current, previous): + if current: + next = current.next + current.next = previous + #if current.next is not None: + # print(current.val, current.next.val) + if next == None: + return current + else: + return self.reverse_linked_list_recursive(next, current) + else: + return + +def construct_linked_list(input): + # Construct linkedlist from the array + root = Node(input[0]) + head = root + for i in range(1, len(input)): + head.next = Node(input[i]) + head = head.next + return root + +def print_linked_list(node): + while node: + print(node.val,) + node = node.next + +def main(): + s = Solution() + input = [4, 3, 2, 1, 0] + + head = construct_linked_list(input) + #head = s.reverse_linked_list_iterative(head) + head = s.reverse_linked_list_recursive(head, None) + print_linked_list(head) + +main() diff --git a/theDailyProblem/reverseInteger.py b/theDailyProblem/reverseInteger.py new file mode 100644 index 0000000..b7455e6 --- /dev/null +++ b/theDailyProblem/reverseInteger.py @@ -0,0 +1,46 @@ +""" +Write a function that reverses the digits a 32-bit signed integer, x. Assume that the environment can only store integers within the 32-bit signed integer range, [-2^31, 2^31 - 1]. The function returns 0 when the reversed integer overflows. + +Example: +Input: 123 +Output: 321 +class Solution: + def reverse(self, x): + # Fill this in. + +print(Solution().reverse(123)) +# 321 +print(Solution().reverse(2**31)) +# 0 +""" +import sys +class Solution: + def reverse_hack(self, x): + if x > (-2**31) and x < (2**31)-1: + return int(str(x)[::-1]) + else: + return 0 + + # New Logic - learn more ways + def reverse(self, x): + rev = 0 + #print(x) + #i = 0 + while x: + if x >= (2**31) or x <= (-2**31)-1: + return 0 + #print("=============> "+str(i)) + pop = x%10 + #print(pop) + x /= 10 + #print(x) + rev = rev*10 + pop + #print(rev) + #i += 1 + return rev + +print(Solution().reverse(123)) +# 321 +print(Solution().reverse(2**31)) +# 0 + diff --git a/theDailyProblem/reversePolishNotationCalculator.py b/theDailyProblem/reversePolishNotationCalculator.py new file mode 100644 index 0000000..16c7d7c --- /dev/null +++ b/theDailyProblem/reversePolishNotationCalculator.py @@ -0,0 +1,104 @@ +""" +Given an expression (as a list) in reverse polish notation, evaluate the expression. Reverse polish notation is where the numbers come before the operand. Note that there can be the 4 operands '+', '-', '*', '/'. You can also assume the expression will be well formed. + +Example +Input: [1, 2, 3, '+', 2, '*', '-'] +Output: -9 +The equivalent expression of the above reverse polish notation would be (1 - ((2 + 3) * 2)). + +Here's some starter code: + +def reverse_polish_notation(expr): + # Fill this in. + +# 1 - (2 + 3) * 2 +print(reverse_polish_notation([1, 2, 3, '+', 2, '*', '-'])) +# -9 +""" + +def reverse_polish_notation(expr): + + # Logic 1: Find the inner most operand and evaluate + # * Iterate to find the indexes of all the operands backwards + indexes = [] + #print(expr) + for i in range(len(expr)-1, -1, -1): + if expr[i] in ['+', '-', '*', '/']: + indexes = [i] + indexes + for i in indexes: + o1 = i-1 + while expr[o1] == "": + o1 -= 1 + op1 = str(expr[o1]) + expr[o1] = "" + while expr[o1] == "": + o1 -= 1 + op2 = str(expr[o1]) + expr[o1] = "" + expr[i] = eval(op2+expr[i]+op1) + #print(expr) + #print(expr) + return expr[-1] + +# 1 - (2 + 3) * 2 +print(reverse_polish_notation([1, 2, 3, '+', 2, '*', '-'])) +# -9 + +""" +class Solution(object): + def evalRPN(self, expr): + """ + :type tokens: List[str] + :rtype: int + """ + + # Logic 1: Find the inner most operand and evaluate - 5% Faster Only + # * Iterate to find the indexes of all the operands backwards + + """ + indexes = [] + #print(expr) + for i in range(len(expr)-1, -1, -1): + if expr[i] in ['+', '-', '*', '/']: + indexes = [i] + indexes + for i in indexes: + o1 = i-1 + while expr[o1] == "": + o1 -= 1 + op1 = str(int(expr[o1])) + expr[o1] = "" + while expr[o1] == "": + o1 -= 1 + op2 = str(int(expr[o1])) + expr[o1] = "" + expr[i] = eval(op2+expr[i]+op1) + #print(expr) + #print(expr) + return int(expr[-1]) + """ + + # Logic 2: Single Iteration Logic --> 92% faster + stack = [] + for i in range(len(expr)): + if expr[i] not in ["+","-","/","*"]: + stack.append(expr[i]) + else: + r = int(stack.pop()) + l = int(stack.pop()) + if expr[i] == "+": + stack.append(l+r) + elif expr[i] == "*": + stack.append(l*r) + elif expr[i] == "/": + if l*r < 0 and l%r != 0: + stack.append(l//r+1) + else: + stack.append(l//r) + elif expr[i] == "-": + stack.append(l-r) + else: + print("wrong") + #print(stack) + return stack[-1] + # Ref: https://leetcode.com/problems/evaluate-reverse-polish-notation/discuss/47444/Python-solution-with-comments-(don't-use-eval()-function). +""" diff --git a/theDailyProblem/reverseWordsInAString.py b/theDailyProblem/reverseWordsInAString.py new file mode 100644 index 0000000..06ae9eb --- /dev/null +++ b/theDailyProblem/reverseWordsInAString.py @@ -0,0 +1,24 @@ +""" +Given a string, you need to reverse the order of characters in each word within a sentence while still preserving whitespace and initial word order. + +Example 1: +Input: "The cat in the hat" +Output: "ehT tac ni eht tah" +Note: In the string, each word is separated by single space and there will not be any extra space in the string. + +Here's a starting point: + +class Solution: + def reverseWords(self, str): + # Fill this in. + +print Solution().reverseWords("The cat in the hat") +# ehT tac ni eht tah +""" +class Solution: + def reverseWords(self, str): + return " ".join(map(lambda x: x[::-1], str.split(" "))) + +print Solution().reverseWords("The cat in the hat") +# ehT tac ni eht tah + diff --git a/theDailyProblem/roomScheduling.py b/theDailyProblem/roomScheduling.py new file mode 100644 index 0000000..663d97b --- /dev/null +++ b/theDailyProblem/roomScheduling.py @@ -0,0 +1,54 @@ +""" +You are given an array of tuples (start, end) representing time intervals for lectures. The intervals may be overlapping. Return the number of rooms that are required. + +For example. [(30, 75), (0, 50), (60, 150)] should return 2. +""" + +# Recon +# * When overlap occurs we need another room, else we use the same room + +def rooms(schedule): + + # Logic 1: Naive method + # * Sort the schedule with start times as reference + # * Maintain a rooms dictionary to know what class is going on that room + # * Iterate tuples and see if there is a overlap, if overlap occurs create a room in rooms dictionary and add current class + + # Room dictionary + rooms = {} + + # Sort the schedule with respect to the start time + schedule.sort() + + # First room allocated + rooms[1] = schedule[0] + + # Iterate other rooms + for i in range(1, len(schedule)): + # current Start and End time + start = schedule[i][0] + end = schedule[i][1] + # Sentinel for identifying if room is allocated + got_room = False + # Iterate the rooms dictionary to find free slots + for room in rooms.keys(): + # If there is a conflict move to next room + if start < rooms[room][1]: + pass + else: + # If there is no conflict get the room and leave + rooms[room] = (start, end) + got_room = True + break + # If we dont get any room yet ( conflicts ), create a new room + if not got_room: + rooms[len(rooms.keys())+1] = (start, end) + #print(rooms) + return len(rooms.keys()) + + +def main(): + schedule = [(30, 75), (0, 50), (60, 150)] + print(rooms(schedule)) + +main() \ No newline at end of file diff --git a/theDailyProblem/rotateLinkedList.py b/theDailyProblem/rotateLinkedList.py new file mode 100644 index 0000000..227c8a9 --- /dev/null +++ b/theDailyProblem/rotateLinkedList.py @@ -0,0 +1,74 @@ +""" +Given a linked list and a number k, rotate the linked list by k places. + +Here's some starter code and an example: + +class Node: + def __init__(self, value, next=None): + self.value = value + self.next = next + + def __str__(self): + current = self + ret = '' + while current: + ret += str(current.value) + current = current.next + return ret + +def rotate_list(list, k): + # Fill this in. + +# Order is 1, 2, 3, 4 +llist = Node(1, Node(2, Node(3, Node(4)))) + +# Order should now be 3, 4, 1, 2 +print(rotate_list(llist, 2)) +# 3412 +""" + +class Node: + def __init__(self, value, next=None): + self.value = value + self.next = next + + def __str__(self): + current = self + ret = '' + while current: + ret += str(current.value) + current = current.next + return ret + +def rotate_list(head, k): + # O(2N) ==> O(N) Logic + + # Head is the first node + front = head + length = 1 + + # Tail is the last node, we use O(N) + tail = None + while head and head.next: + length += 1 + head = head.next + tail = head + + # Modulate k for rotation + k = (length-k)%length + + # Rotate until k is zero + while head and tail and k: + tail.next = front + front = front.next + tail = tail.next + tail.next = None + k -= 1 + + return front + +# Order is 1, 2, 3, 4 +llist = Node(1, Node(2, Node(3, Node(4)))) + +# Order should now be 3, 4, 1, 2 +print(rotate_list(llist, 2)) diff --git a/theDailyProblem/searchingAMatrix.py b/theDailyProblem/searchingAMatrix.py new file mode 100644 index 0000000..6da1fff --- /dev/null +++ b/theDailyProblem/searchingAMatrix.py @@ -0,0 +1,65 @@ +""" +Given a matrix that is organized such that the numbers will always be sorted left to right, and the first number of each row will always be greater than the last element of the last row (mat[i][0] > mat[i - 1][-1]), search for a specific value in the matrix and return whether it exists. + +Here's an example and some starter code. + +def searchMatrix(mat, value): + # Fill this in. + +mat = [ + [1, 3, 5, 8], + [10, 11, 15, 16], + [24, 27, 30, 31], +] + +print(searchMatrix(mat, 4)) +# False + +print(searchMatrix(mat, 10)) +# True +""" + +# Logic 1: Search is best with binarySearch --> Doing BinarySearch in 2D is the challenge +# the start and end of each row can be a sorted list to do search? +# first, going naive with iteration plus binary search or flatten the matrix and then perform binary search +def binarySearch(array, value): + print(array) + n = len(array) + left = 0 + right = n-1 + while left < right: + mid = left + (right-left)//2 + print(left, mid, right) + if array[mid] == value: + return mid + elif array[mid] < value: + left = mid + else: + right = mid + + if right-left == 1: + if array[left] == value: + return left + elif array[right] == value: + return right + else: + return -1 + +# Logic 2: Can you optimize and perform binarySearch in 2D in one go? + +def searchMatrix(mat, value): + import itertools + return binarySearch(list(itertools.chain.from_iterable(mat)), value) + + +mat = [ + [1, 3, 5, 8], + [10, 11, 15, 16], + [24, 27, 30, 31], +] + +print(searchMatrix(mat, 4)) +# False + +print(searchMatrix(mat, 10)) +# True diff --git a/theDailyProblem/shiftedString.py b/theDailyProblem/shiftedString.py new file mode 100644 index 0000000..89ca9cd --- /dev/null +++ b/theDailyProblem/shiftedString.py @@ -0,0 +1,22 @@ +""" +You are given two strings, A and B. Return whether A can be shifted some number of times to get B. + +Eg. A = abcde, B = cdeab should return true because A can be shifted 3 times to the right to get B. A = abc and B= acb should return false. + +def is_shifted(a, b): + # Fill this in. + +print is_shifted('abcde', 'cdeab') +# True +""" + +def is_shifted(a, b): + for i in range(len(a)): + shift = a[i:]+a[:i] + #print(shift, i) + if shift == b: + return True + return False + +print is_shifted('abcde', 'cdeab') +# True diff --git a/theDailyProblem/shortestUniquePrefix.py b/theDailyProblem/shortestUniquePrefix.py new file mode 100644 index 0000000..0a12f80 --- /dev/null +++ b/theDailyProblem/shortestUniquePrefix.py @@ -0,0 +1,39 @@ +""" +Given a list of words, for each word find the shortest unique prefix. You can assume a word will not be a substring of another word (ie play and playing won't be in the same words list) + +Example +Input: ['joma', 'john', 'jack', 'techlead'] +Output: ['jom', 'joh', 'ja', 't'] +Here's some starter code: + +def shortest_unique_prefix(words): + + +print(shortest_unique_prefix(['joma', 'john', 'jack', 'techlead'])) +# ['jom', 'joh', 'ja', 't'] +""" + +def shortest_unique_prefix(words): + unique_prefix = {} + visited = set() + n = len(max(words)) + i = 1 + while i < n: + w = 0 + while w < len(words): + if words[w][:i] in visited: + w += 1 + elif words[w][:i] not in unique_prefix: + unique_prefix[words[w][:i]] = words[w] + words.pop(w) + else: + words.append(unique_prefix[words[w][:i]]) + del unique_prefix[words[w][:i]] + visited.add(words[w][:i]) + w += 1 + #print(i, words, unique_prefix) + i += 1 + return unique_prefix.keys() + +print(shortest_unique_prefix(['joma', 'john', 'jack', 'techlead'])) +# ['jom', 'joh', 'ja', 't'] diff --git a/theDailyProblem/sortAPartiallySortedList.py b/theDailyProblem/sortAPartiallySortedList.py new file mode 100644 index 0000000..8694d31 --- /dev/null +++ b/theDailyProblem/sortAPartiallySortedList.py @@ -0,0 +1,37 @@ +""" +You are given a list of n numbers, where every number is at most k indexes away from its properly sorted index. Write a sorting algorithm (that will be given the number k) for this list that can solve this in O(n log k) + +Example: +Input: [3, 2, 6, 5, 4], k=2 +Output: [2, 3, 4, 5, 6] +As seen above, every number is at most 2 indexes away from its proper sorted index. + +Here's a starting point: + +def sort_partially_sorted(nums, k): + # Fill this in. + +print sort_partially_sorted([3, 2, 6, 5, 4], 2) +""" + +def sort_partially_sorted(nums, k): + n = len(nums) + for i in range(len(nums)): + time = k + j = i+1 + mini = float('inf') + min_ = float('inf') + while time > 0 and j < len(nums): + #print(i, j) + if nums[j] < nums[i] and nums[j] < mini: + mini = nums[j] + min_ = j + j += 1 + time -= 1 + if min_ < len(nums): + nums[i], nums[min_] = nums[min_], nums[i] + #print(nums, i, mini) + return nums + +print sort_partially_sorted([3, 2, 6, 5, 4], 2) +print sort_partially_sorted([2, 3, 0, 1], 2) diff --git a/theDailyProblem/sortWith3Elements.py b/theDailyProblem/sortWith3Elements.py new file mode 100644 index 0000000..5f8d6d3 --- /dev/null +++ b/theDailyProblem/sortWith3Elements.py @@ -0,0 +1,52 @@ +""" +Given a list of numbers with only 3 unique numbers (1, 2, 3), sort the list in O(n) time. + +Example 1: +Input: [3, 3, 2, 1, 3, 2, 1] +Output: [1, 1, 2, 2, 3, 3, 3] +def sortNums(nums): + # Fill this in. + +print sortNums([3, 3, 2, 1, 3, 2, 1]) +# [1, 1, 2, 2, 3, 3, 3] + +Challenge: Try sorting the list using constant space. +""" + +def sort_3(a): + # Constant space so add variable with element and num of time it occurs + first = [None, 0] + second = [None, 0] + third = [None, 0] + n = len(a) + for i in range(n): + if first[0] == None: + first[0] = a[i] + elif first[0] != a[i] and second[0] == None: + second[0] = a[i] + if second[0] < first[0]: + first, second = second, first + elif (second[0] != a[i] and first[0] != a[i]) and third[0] == None: + third[0] = a[i] + if third[0] < first[0] and third[0] < second[0]: + first, third = third, first + second, third = third, second + elif third[0] < second[0]: + second, third = third, second + if a[i] == first[0]: + first[1] += 1 + elif a[i] == second[0]: + second[1] += 1 + elif a[i] == third[0]: + third[1] += 1 + print(first, second, third) + return [first[0]]*first[1] + [second[0]]*second[1] + [third[0]]*third[1] +#def inbuild_3_sort(a): +# return list(set(a)) + +def main(): + a = [3,3,2,1,3,2,1] + print(sort_3(a)) + print(inbuild_3_sort(a)) + +main() diff --git a/theDailyProblem/sortWith3UniqueElements.py b/theDailyProblem/sortWith3UniqueElements.py new file mode 100644 index 0000000..4c8205f --- /dev/null +++ b/theDailyProblem/sortWith3UniqueElements.py @@ -0,0 +1,49 @@ +""" +Given a list of numbers with only 3 unique numbers (1, 2, 3), sort the list in O(n) time. + +Example 1: +Input: [3, 3, 2, 1, 3, 2, 1] +Output: [1, 1, 2, 2, 3, 3, 3] +def sortNums(nums): + # Fill this in. + +print sortNums([3, 3, 2, 1, 3, 2, 1]) +# [1, 1, 2, 2, 3, 3, 3] + +Challenge: Try sorting the list using constant space. +""" + +def sort_3(a): + # Constant space so add variable with element and num of time it occurs + first = [None, 0] + second = [None, 0] + third = [None, 0] + n = len(a) + for i in range(n): + if first[0] == None: + first[0] = a[i] + elif first[0] != a[i] and second[0] == None: + second[0] = a[i] + if second[0] < first[0]: + first, second = second, first + elif (second[0] != a[i] and first[0] != a[i]) and third[0] == None: + third[0] = a[i] + if third[0] < first[0] and third[0] < second[0]: + first, third = third, first + second, third = third, second + elif third[0] < second[0]: + second, third = third, second + if a[i] == first[0]: + first[1] += 1 + elif a[i] == second[0]: + second[1] += 1 + elif a[i] == third[0]: + third[1] += 1 + print(first, second, third) + return [first[0]]*first[1] + [second[0]]*second[1] + [third[0]]*third[1] + +def main(): + a = [3,3,2,1,3,2,1] + print(sort_3(a)) + +main() diff --git a/theDailyProblem/sortingWindowRange.py b/theDailyProblem/sortingWindowRange.py new file mode 100644 index 0000000..6d0518f --- /dev/null +++ b/theDailyProblem/sortingWindowRange.py @@ -0,0 +1,35 @@ +""" +Given a list of numbers, find the smallest window to sort such that the whole list will be sorted. If the list is already sorted return (0, 0). You can assume there will be no duplicate numbers. + +Example: +Input: [2, 4, 7, 5, 6, 8, 9] +Output: (2, 4) +Explanation: Sorting the window (2, 4) which is [7, 5, 6] will also means that the whole list is sorted. + +def min_window_to_sort(nums): + # Fill this in. + +print(min_window_to_sort([2, 4, 7, 5, 6, 8, 9])) +# (2, 4) +""" + +def min_window_to_sort(nums): + + # Logic O(N) iterate to record the incorrect sort + left, right = None, None + for i in range(len(nums)-1): + if nums[i] > nums[i+1]: + if not left: + left = i + else: + right = i+1 + nums[i], nums[i+1] = nums[i+1], nums[i] + if left == None: + left = 0 + if right == None: + right = 0 + return (left, right) + +print(min_window_to_sort([2, 4, 7, 5, 6, 8, 9])) +# (2, 4) +print(min_window_to_sort([2, 3, 7, 5, 4, 6, 8, 9])) diff --git a/theDailyProblem/stringCompression.py b/theDailyProblem/stringCompression.py new file mode 100644 index 0000000..b405aa4 --- /dev/null +++ b/theDailyProblem/stringCompression.py @@ -0,0 +1,70 @@ +""" +Given an array of characters with repeats, compress it in place. The length after compression should be less than or equal to the original array. + +Example: +Input: ['a', 'a', 'b', 'c', 'c', 'c'] +Output: ['a', '2', 'b', 'c', '3'] +Here's a starting point: + +class Solution(object): + def compress(self, chars): + # Fill this in. + +print Solution().compress(['a', 'a', 'b', 'c', 'c', 'c']) +# ['a', '2', 'b', 'c', '3'] +""" + +class Solution(object): + def compress(self, chars): + """ + :type chars: List[str] + :rtype: int + """ + + # Logic 1: 2 pointer method - inplace replacement is the only way you could do this... + + select = 0 + i = 1 + n = len(chars) + + length = 1 + + while i < n: + + count = 1 + + while i < n and chars[i] == chars[select]: + count += 1 + i += 1 + + if count > 1: + count = str(count) + for dig in count: + select += 1 + chars[select] = dig + length += 1 + + if i < n: + select += 1 + chars[select] = chars[i] + length += 1 + i += 1 + + return length + + # Below logic uses extra space + """ + result = [] + while chars: + if not result: + result.append(chars.pop(0)) + result.append("1") + else: + if result[-2] == chars[0]: + result[-1] = str(int(result[-1])+1) + else: + result.append(chars[0]) + result.append("1") + chars.pop(0) + return len(result) + """ diff --git a/theDailyProblem/ticTacToe.py b/theDailyProblem/ticTacToe.py new file mode 100644 index 0000000..0cadd95 --- /dev/null +++ b/theDailyProblem/ticTacToe.py @@ -0,0 +1,100 @@ +''' +Design a Tic-Tac-Toe game played between two players on an n x n grid. A move is guaranteed to be valid, and a valid move is one placed on an empty block in the grid. A player who succeeds in placing n of their marks in a horizontal, diagonal, or vertical row wins the game. Once a winning condition is reached, the game ends and no more moves are allowed. Below is an example game which ends in a winning condition: + +Given n = 3, assume that player 1 is "X" and player 2 is "O" +board = TicTacToe(3); + +board.move(0, 0, 1); -> Returns 0 (no one wins) +|X| | | +| | | | // Player 1 makes a move at (0, 0). +| | | | + +board.move(0, 2, 2); -> Returns 0 (no one wins) +|X| |O| +| | | | // Player 2 makes a move at (0, 2). +| | | | + +board.move(2, 2, 1); -> Returns 0 (no one wins) +|X| |O| +| | | | // Player 1 makes a move at (2, 2). +| | |X| + +board.move(1, 1, 2); -> Returns 0 (no one wins) +|X| |O| +| |O| | // Player 2 makes a move at (1, 1). +| | |X| + +board.move(2, 0, 1); -> Returns 0 (no one wins) +|X| |O| +| |O| | // Player 1 makes a move at (2, 0). +|X| |X| + +board.move(1, 0, 2); -> Returns 0 (no one wins) +|X| |O| +|O|O| | // Player 2 makes a move at (1, 0). +|X| |X| + +board.move(2, 1, 1); -> Returns 1 (player 1 wins) +|X| |O| +|O|O| | // Player 1 makes a move at (2, 1). +|X|X|X| + +Here's a starting point: + +class TicTacToe(object): + def __init__(self, n): + # Fill this in. + + def move(self, row, col, player): + # Fill this in. + +board = TicTacToe(3) +board.move(0, 0, 1) +board.move(0, 2, 2) +board.move(2, 2, 1) +board.move(1, 1, 2) +board.move(2, 0, 1) +board.move(1, 0, 2) +print(board.move(2, 1, 1)) +''' + +class TicTacToe(object): + def __init__(self, n): + # Initialize nxn with all 0s + self.n = n + self.grid = [[0 for i in range(n)] for i in range(n)] + + def move(self, row, col, player): + # * Ensuring move is always valid we dont need to check + # * Using player ids instead of X0 + self.grid[row][col] = player + # Check winning row + for rw in range(self.n): + rwCheck = set(self.grid[rw]) + if len(rwCheck) == 1: + return "1" + "(player " + str(rwCheck) + " wins)" + # Check winning col + for col in range(self.n): + colCheck = set(self.grid[col]) + if len(colCheck) == 1: + return "1" + "(player " + str(colCheck) + " wins)" + # Check winning diagnal + diag = set() + for i in range(0, self.n): + diag.add(self.grid[i][i]) + if len(diag) > 1: + break + if len(diag) == 1: + return "1" + "(player " + str(diag) + " wins)" + return "0" + +board = TicTacToe(3) +board.move(0, 0, 1) +board.move(0, 2, 2) +board.move(2, 2, 1) +board.move(1, 1, 2) +board.move(2, 0, 1) +board.move(1, 0, 2) +print(board.move(2, 1, 1)) + + diff --git a/theDailyProblem/validateBalancedParanthesis.py b/theDailyProblem/validateBalancedParanthesis.py new file mode 100644 index 0000000..e26273e --- /dev/null +++ b/theDailyProblem/validateBalancedParanthesis.py @@ -0,0 +1,65 @@ +""" +Imagine you are building a compiler. Before running any code, the compiler must check that the parentheses in the program are balanced. Every opening bracket must have a corresponding closing bracket. We can approximate this using strings. + +Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid. +An input string is valid if: +- Open brackets are closed by the same type of brackets. +- Open brackets are closed in the correct order. +- Note that an empty string is also considered valid. + +Example: +Input: "((()))" +Output: True + +Input: "[()]{}" +Output: True + +Input: "({[)]" +Output: False +class Solution: + def isValid(self, s): + # Fill this in. + +# Test Program +s = "()(){(())" +# should return False +print(Solution().isValid(s)) + +s = "" +# should return True +print(Solution().isValid(s)) + +s = "([{}])()" +# should return True +print(Solution().isValid(s)) +""" + +class Solution(object): + def isValid(self, s): + """ + :type s: str + :rtype: bool + """ + + braces = { + "{":"}", + "[":"]", + "(":")" + } + + stack = [] + + for br in s: + if br in braces.keys(): + stack.append(br) + else: + if stack and braces[stack[-1]] == br: + stack.pop() + else: + return False + if stack: + return False + else: + return True + + diff --git a/theDailyProblem/validateBinarySearchTree.py b/theDailyProblem/validateBinarySearchTree.py new file mode 100644 index 0000000..567e704 --- /dev/null +++ b/theDailyProblem/validateBinarySearchTree.py @@ -0,0 +1,88 @@ +""" +You are given the root of a binary search tree. Return true if it is a valid binary search tree, and false otherwise. Recall that a binary search tree has the property that all values in the left subtree are less than or equal to the root, and all values in the right subtree are greater than or equal to the root. + +Here's a starting point: + +class TreeNode: + def __init__(self, key): + self.left = None + self.right = None + self.key = key + +def is_bst(root): + # Fill this in. + +a = TreeNode(5) +a.left = TreeNode(3) +a.right = TreeNode(7) +a.left.left = TreeNode(1) +a.left.right = TreeNode(4) +a.right.left = TreeNode(6) +print is_bst(a) + +# 5 +# / \ +# 3 7 +# / \ / +#1 4 6 + +""" + +class TreeNode: + def __init__(self, key): + self.left = None + self.right = None + self.key = key + +# Maintain all ancestors and check it supports BST property +# * less than the root if left +# * greater than the root if right +# Summary +# * For each node, it should be greater if right or lesser if left for all nodes in subtree except root + + +# Break down the logic to avoid confusion +# * Logic to get all the left and the right subtree of each node +""" +def is_bst(node): + # Condition to recurse + left_subtree = right_subtree = [] + if node.left: + left_subtree = is_bst(node.left) + if node.right: + right_subtree = is_bst(node.right) + print(left_subtree, right_subtree) + if node: + path = [node.key] + left_subtree + right_subtree + return path +""" + +def is_bst(node): + # Condition to recurse + left_subtree = right_subtree = [] + lresult = rresult = True + if node.left: + left_subtree, lresult = is_bst(node.left) + if node.right: + right_subtree, rresult = is_bst(node.right) + print(left_subtree, right_subtree) + for l in left_subtree: + if l > node.key: + lresult = False + for r in right_subtree: + if r < node.key: + rresult = False + if node: + path = [node.key] + left_subtree + right_subtree + return path, lresult and rresult + +def main(): + a = TreeNode(5) + a.left = TreeNode(3) + a.right = TreeNode(7) + a.left.left = TreeNode(1) + a.left.right = TreeNode(8) + a.right.left = TreeNode(6) + print is_bst(a)[1] + +main() diff --git a/ui_ux/README.md b/ui_ux/README.md new file mode 100644 index 0000000..c577cfa --- /dev/null +++ b/ui_ux/README.md @@ -0,0 +1,5 @@ +## User Interface + +* This folder is a reference to helper scripts or projects to build a better UI + + diff --git a/ui_ux/terminal_in_tk.py b/ui_ux/terminal_in_tk.py new file mode 100644 index 0000000..236de46 --- /dev/null +++ b/ui_ux/terminal_in_tk.py @@ -0,0 +1,13 @@ +# Reference: https://stackoverflow.com/questions/7253448/how-to-embed-a-terminal-in-a-tkinter-application + +from Tkinter import * +import os + +root = Tk() +termf = Frame(root, height=400, width=500) + +termf.pack(fill=BOTH, expand=YES) +wid = termf.winfo_id() +os.system('xterm -into %d -geometry 40x20 -sb &' % wid) + +root.mainloop()