From 294268ea963842bf951d93956b613c7c51dee221 Mon Sep 17 00:00:00 2001 From: Tarek Tarho Date: Sat, 29 Jul 2023 14:15:20 +0200 Subject: [PATCH 1/2] add more methods --- index.js | 257 ++++++++++++++++++++++++++++++++++++++++++++ random.js | 205 ++++++++++++++++++++++++++++++++++- simpleTextEditor.js | 91 ++++++++++------ 3 files changed, 517 insertions(+), 36 deletions(-) diff --git a/index.js b/index.js index 275c407..f621e01 100644 --- a/index.js +++ b/index.js @@ -594,3 +594,260 @@ function isValid(s) { console.log(isValid("aabbcc")) console.log(isValid("aabbccddeefghi")) + +console.log("-----climbingLeaderboard-----") + +function climbingLeaderboard(ranked, player) { + //init started playerRange as 0 + //remove duplicates + // determine the playerRank by iterating over the number Of players then compare it to the rank list + // iterate over the game array each time increase the player score by the players + + /** + Creates a new array uniqueRanked by removing duplicate scores from the ranked array using a Set data structure. + It ensures that each score in uniqueRanked is unique and maintains the order of the scores from ranked. + */ + const uniqueRanked = [...new Set(ranked)] + //const uniqueRanked = Array.from(new Set(ranked)) + /** + * initializes an empty array results to store the rankings of each player score. + */ + const results = [] + /** + * initializes a variable i to the last index of the uniqueRanked array. + * It will be used to iterate through the scores in uniqueRanked. + */ + let i = uniqueRanked.length - 1 + + /** + * starts a loop that iterates through each score in the player array. + */ + for (const score of player) { + /** + * starts a nested loop. It continues to decrement i as long as i is greater than or equal to 0 + * and the current player score is greater than or equal to the score at index i in the uniqueRanked array. + * This loop helps to find the correct rank for the player's score. + */ + while (i >= 0 && score >= uniqueRanked[i]) { + i-- + } + /* + adds the rank of the player's score to the results array. Since the ranking is 1-indexed, i + 2 is used. + */ + results.push(i + 2) + } + + return results +} + +//big-O O(n+m) time +// space O(n) + +//rankedCurr = [100, 100, 50, 40,40, 20, 10] +//playerCurr = [5, 25, 50, 120] // score per game +console.log(climbingLeaderboard([100, 100, 50, 40, 40, 20, 10], [5, 25, 50, 120])) + +//criteria: +// w > orginal word +// w < word that meets the first condition +// example w = abcd + +function biggerIsGreater(w) { + // Step 1: Find the character to swap + let i = w.length - 2 + console.log(i, w[i]) + while (i >= 0 && w[i] >= w[i + 1]) { + i-- + } + + // Step 2: Check if no character is found + if (i === -1) { + return "no answer" + } + + // Step 3: Find the character to swap with + let j = w.length - 1 + while (j > i && w[j] <= w[i]) { + j-- + } + + // Step 4: Swap characters + let charArray = w.split("") + ;[charArray[i], charArray[j]] = [charArray[j], charArray[i]] + + // Step 5: Sort the remaining characters + const sortedSubstring = charArray.slice(i + 1).sort() + + // Step 6: Return the modified word + return charArray + .slice(0, i + 1) + .concat(sortedSubstring) + .join("") +} + +console.log(biggerIsGreater("hefg"), "-----biggerIsGreater----") + +console.log("----Swap array----") + +let array = [1, 2, 3, 4, 5, 6, 7, 8] +console.log(array) +const n = array.length +const reverse = (array) => { + for (let i = 0; i < Math.floor(n / 2); i++) { + ;[array[i], array[n - 1 - i]] = [array[n - 1 - i], array[i]] + } + return array +} + +console.log(reverse(array), "revers") + +function isIsogram(str) { + return new Set(str.toLowerCase()).size === str.length +} + +console.log(isIsogram("aba"), "isIsogram") + +function timeInWords(h, m) { + const numberWords = [ + "zero", + "one", + "two", + "three", + "four", + "five", + "six", + "seven", + "eight", + "nine", + "ten", + "eleven", + "twelve", + "thirteen", + "fourteen", + "fifteen", + "sixteen", + "seventeen", + "eighteen", + "nineteen", + "twenty", + "twenty one", + "twenty two", + "twenty three", + "twenty four", + "twenty five", + "twenty six", + "twenty seven", + "twenty eight", + "twenty nine", + ] + + if (m === 0) { + return `${numberWords[h]} o' clock` + } else if (m === 15) { + return `quarter past ${numberWords[h]}` + } else if (m === 30) { + return `half past ${numberWords[h]}` + } else if (m === 45) { + return `quarter to ${numberWords[h + 1]}` + } else if (m === 1) { + return `one minute past ${numberWords[h]}` + } else if (m < 30) { + return `${numberWords[m]} minutes past ${numberWords[h]}` + } else { + return `${numberWords[60 - m]} minutes to ${numberWords[h + 1]}` + } +} + +// Example usage: +console.log(timeInWords(5, 0)) // five o' clock +console.log(timeInWords(5, 1)) // one minute past five +console.log(timeInWords(5, 10)) // ten minutes past five +console.log(timeInWords(5, 15)) // quarter past five +console.log(timeInWords(5, 30)) // half past five +console.log(timeInWords(5, 40)) // twenty minutes to six +console.log(timeInWords(5, 45)) // quarter to six +console.log(timeInWords(5, 47)) // thirteen minutes to six +console.log(timeInWords(5, 28)) // twenty eight minutes past five + +console.clear() + +function chocolateFeast(amountOfMoney, cost, numberOfWrappers) { + // 10 2 5 = (10/2 = 5 = wraps so + 1) = 6 + // 12 4 4 = (12 / 4 = 3 < wraps ) 3 + // 6 2 2 = (6/2 = 3 he have 2 + 2 left it cost 2 3 + 2) = 5 + // money. cost. warappers eaten chocolates + // 15 3 2 = ( 15/3 = 5 cost 3 - 2 = 1, 2 - 1 = 1) = 9 + // (amountOfMoney / cost) wraps + // = 6 + // = 3 + // = 3 + // if rest = 2 we can get new coco he need at least 2 wraps to get coco + + // calculate the init number he can eat + let totalChocolates = Math.floor(amountOfMoney / cost) + //set the initial number of wraps + let wrappers = totalChocolates + //whiel loop to keep exchanging for chocolate until Bobby can no longer get a free chocolate + while (wrappers >= numberOfWrappers) { + // Calculate the number of chocolates Bobby can get from exchanging wrappers + const exchangedChocolates = Math.floor(wrappers / numberOfWrappers) + // Add the exchanged chocolates to the total + totalChocolates += exchangedChocolates + // Update the number of remaining wrappers + wrappers = exchangedChocolates + (wrappers % numberOfWrappers) + } + + return totalChocolates +} +//big-o = O(log(n/m)) +console.log(chocolateFeast(15, 3, 2), "chocolateFeast") //9 + +// Intewview qeustion return true if the rectangle overlap else retrun false + +// one main q two follow ups +// looking for most opt +function checkRectangleOverlap(rectangles) { + for (let i = 0; i < rectangles.length; i++) { + const rectangleA = rectangles[i] + for (let j = i + 1; j < rectangles.length; j++) { + const rectangleB = rectangles[j] + + // Calculate the x-coordinate ranges of the rectangles + const rangeAx = [rectangleA.x, rectangleA.x + rectangleA.width] + const rangeBx = [rectangleB.x, rectangleB.x + rectangleB.width] + + // Check if the x-coordinate ranges overlap + if (rangeAx[0] < rangeBx[1] && rangeBx[0] < rangeAx[1]) { + return true // Rectangles overlap + } + } + } + + return false // Rectangles do not overlap +} + +//Optimized solutions +function checkRectangleOverlapOpt(rectangles) { + //storing rectagnles length in const outside the for loop so, we don't have to get length at every iteration + const rectangleLength = rectangles.length + for (let i = 0; i < rectangleLength; i++) { + const rectangleA = rectangles[i] + const rectangleB = rectangles[i + 1] + // Check if rectangles overlap + let leftCorner = rectangleA.x + rectangleA.width > rectangleB.x + let rightCorner = rectangleB.x + rectangleB.width > rectangleA.x + if (leftCorner && rightCorner) { + return true // Rectangles overlap + } + } + + return false // Rectangles do not overlap +} + +const rectangles = [ + { x: 0, width: 15, height: 5 }, + { x: 10, width: 5, height: 5 }, + { x: 20, width: 5, height: 5 }, +] + +console.log(checkRectangleOverlapOpt(rectangles), "rectangles") // true diff --git a/random.js b/random.js index eab7931..3167871 100644 --- a/random.js +++ b/random.js @@ -218,7 +218,7 @@ function stringToArray(string) { return result } -log(stringToArray("hello, world")) +log(stringToArray("hello, world"), "stringToArray") //Simple convert string to array @@ -522,7 +522,10 @@ console.log(beautifulSubarraysOPT(array, oddNum)) console.clear() /** - To solve this problem, you can iterate through the array and count the number of positive, negative, and zero elements. Then, you can calculate the ratios by dividing the respective counts by the total number of elements in the array. Finally, you can print the ratios with the specified decimal places. + To solve this problem, you can iterate through the array and count the number of positive, + negative, and zero elements. Then, you can calculate the ratios by dividing the respective + counts by the total number of elements in the array. Finally, + you can print the ratios with the specified decimal places. */ function plusMinus(arr) { @@ -1156,3 +1159,201 @@ function encryption(s) { } console.log(encryption("haveaniceday")) + +function arrayManipulation(n, queries) { + // Create an array of zeros with length n+1 + const arr = Array(n + 1).fill(0) + + // Perform the operations + for (let i = 0; i < queries.length; i++) { + const [a, b, k] = queries[i] + arr[a - 1] += k // Add k to the starting index of the operation + arr[b] -= k // Subtract k from the next index after the operation range + } + + // Calculate the maximum value by accumulating the array elements + let max = 0 + let sum = 0 + for (let i = 0; i < n; i++) { + sum += arr[i] + max = Math.max(max, sum) + } + + return max +} + +//time complexity is O(q + n), which simplifies to O(max(q, n)) +//space complexity of the method is O(n) +//big-O O(n+m) + +console.log("-----buyTofu---") + +/** + * sudo code +1 - initalize varibles to keep track of the counts of mon and monme coins, the sum of all coin values, and the minimum number of coins needed for Tofu + - Initialize variables: monCount = 0, monmeCount = 0, totalValue = 0. +2 - Split the box string into an array of items using space as the delimiter. +3 -Iterate through each item in the box array. + - If the item is 'mon', increment monCount by 1. + - If the item is 'monme', increment monmeCount by 1. + - If the item is neither 'mon' nor 'monme', skip it.. +4 - Calculate the minimum number of coins needed for Tofu: + - Divide the cost by the value of the monme coin. Let's call this quotient as monmeNeeded. + - Subtract monmeNeeded from monmeCount and assign the result to monmeCount. + - Subtract monmeNeeded multiplied by the value of the monme coin from totalValue and assign the result to totalValue. + - Add monmeNeeded multiplied by the value of the mon coin to totalValue. + - Calculate the number of mon coins needed to make the totalValue equal to the cost. Let's call this monNeeded. +5 - Check the conditions to determine the result: + - If monNeeded is negative or monmeCount is negative, return "leaving the market". + - Otherwise, return [monCount, monmeCount, totalValue, monNeeded]. + + */ +function buyTofu(cost, box) { + const countOfMon = box.split(" ").filter((x) => x === "mon").length + const countOfMonme = box.split(" ").filter((x) => x === "monme").length + const sumOfcoin = countOfMon + countOfMonme * 60 + const monmeNeeded = Math.min(Math.floor(cost / 60), countOfMonme) + const monNeeded = cost - monmeNeeded * 60 + + if (monmeNeeded > countOfMonme || monNeeded > countOfMon) { + return "leaving the market" + } + + const minNumberOfCoins = monNeeded + monmeNeeded + + return [countOfMon, countOfMonme, sumOfcoin, minNumberOfCoins] + //[count of mon coins in box, count of monme coins in box,sum of all coins value in box, minimum number of coins needed for Tofu] +} + +console.log(buyTofu(5, "mon monme")) + +function filterList(l) { + return l.filter((val) => typeof val === typeof 1) +} + +console.log(filterList([1, 2, "a", "b"]), "filterList") + +console.log("-------organizingContainers-----") +function organizingContainers(containers) { + // [ [ 1, 1 ], [ 1, 1 ] ] + const n = containers.length + const containerCounts = new Array(n).fill(0) + const ballTypes = new Array(n).fill(0) + + console.log(ballTypes, containerCounts) + + for (let i = 0; i < n; i++) { + // O(n^2) + const container = containers[i] + for (let j = 0; j < n; j++) { + const ballCount = container[j] + containerCounts[i] += ballCount + ballTypes[j] += ballCount + } + } + + //sort to make com + containerCounts.sort() + ballTypes.sort() // 2 * o(nlogn) + console.log(ballTypes, containerCounts) + + for (let i = 0; i < n; i++) { + // O(n) + if (containerCounts[i] !== ballTypes[i]) return "Impossible" + } + + return "Possible" +} + +console.log( + organizingContainers([ + [0, 2], + [1, 1], + ]) +) + +console.log("-----equalStacks-----") +function equalStacks(h1, h2, h3) { + let mainArr = [h1, h2, h3] + console.log("mainArr: ", mainArr) + + let sumArr = mainArr.map((el) => el.reduce((acc, value) => acc + value)) + console.log("sumArr: ", sumArr) + + for (var i = 0; i < Infinity; i++) { + if (sumArr.every((el) => el === sumArr[0])) { + console.log("all are equal") + break + } + + console.log("sumArr: ", sumArr) + console.log("mainArr: ", mainArr) + + let findMax = Math.max(...sumArr) + console.log("findMax: ", findMax) + + let maxIndex = sumArr.indexOf(findMax) + console.log("maxIndex: ", maxIndex) + + let a = sumArr[maxIndex] + console.log(a, "a") + + sumArr[maxIndex] = sumArr[maxIndex] - mainArr[maxIndex].shift() + + let b = sumArr[maxIndex] + console.log(b) + + // end of FOR LOOP i + } + + return sumArr[0] + + // ! end of the function +} + +let h1a = [3, 2, 1, 1, 1] +let h2a = [4, 3, 2] +let h3a = [1, 1, 4, 1] // should be 5 + +let h1b = [1, 2, 1, 1] +let h2b = [1, 1, 2] +let h3b = [1, 1] // should be 2 + +console.log(equalStacks(h1b, h2b, h3b), "equalStacks") +function mario() { + const height = 5 + let ex = "" + for (var i = 0; i < height; i++) { + // revers the printing of loop + for (var k = height - i; k > 1; k--) { + ex += " " + //console.log(" ") + } + for (var j = 0; j <= i; j++) { + ex += "#" + //console.log("#") + } + ex += "\n" + //console.log("\n") + } + + console.log(ex) +} + +mario() + +function scoreWord(word, titles) { + const number = new mapNumbers([23, 22]) + console.log(typeof number) + + console.log(number) +} + +scoreWord() + +function mapNumbers(numbers) { + for (const number of numbers) { + this[number] ??= 0 + this[number]++ + } +} diff --git a/simpleTextEditor.js b/simpleTextEditor.js index 8068aef..f4c3eaa 100644 --- a/simpleTextEditor.js +++ b/simpleTextEditor.js @@ -6,40 +6,35 @@ /** * - * @param {*} operations array of operations + * @param {*} input array of operations */ -function processData(operations) { - //split a array to sub array with new line - //var lines = operations.split("\n") - //skipping splitting the array since we have it splited in already - var lines = operations - var str = "" - //keep track of last - var last = [] - - for (var i = 1; i <= parseInt(lines[0]); i++) { - var command = parseInt(lines[i].split(" ")[0]) - let args = lines[i].split(" ")[1] - - switch (command) { - case 1: - //append op - last.push(str) - str = str + args - break - case 2: - //delete op - last.push(str) - str = str.substring(0, str.length - parseInt(args)) - break - case 3: - //print op - //charAt(the index of char in str) - console.log(str.charAt(parseInt(args) - 1)) - break - case 4: - str = last.pop() - break +function processData(input) { + //input = input.split("\n") + input.splice(0, 1) + + let final = "" + let finalBuffer = [final] + + for (var i = 0; i < input.length; i++) { + let el = input[i] + if (el.length > 1) { + let elSplit = el.split(" ") + let ops = elSplit[0] + let item = elSplit[1] + if (ops === "1") { + finalBuffer.push(final) + final = final + item + } + if (ops === "2") { + finalBuffer.push(final) + final = final.substring(0, final.length - item) + } + + if (ops === "3") { + console.log(final.substring(item - 1, item)) + } + } else { + final = finalBuffer.pop() } } } @@ -52,9 +47,37 @@ let ops = ["1 fg", "3 6", "2 5", "4", "3 7", "4", "3 4"] let ops2 = ["8", "1 abc", "3 3", "2 3", "1 xy", "3 2", "4", "4", "3 1"] // output c y a //input is not correct -log(processData(ops2)) +console.log(processData(ops2)) //result // f // g // d +const randArr = [5, 2, 6, 1, 2, 3, 5, 11] +const str = "hello how are you" +console.log([...new Set(randArr)].sort()) + +console.log([...new Set(randArr)].sort().reduce((total, val) => total + val, 0)) + +//slice retrun shallow copy of portaion of an array +const newArray = randArr.slice(0, randArr.length - 1) + +console.log(newArray) + +//pop will remove the last item and return it +console.log(newArray.pop()) + +//add el to the begining <-> push it add it to the end +console.log(newArray.unshift(1)) +console.log(newArray) +//remove first el and return in <-> pop +console.log(newArray.shift()) + +//every check if it's postive +console.log(randArr.every((item) => item > 0)) + +//indexOf return the frist el of each that can found in array + +console.log(newArray.indexOf(5)) + +console.log(str.split(" ")) From d69424a807f7996024015c5e516decf192b0505a Mon Sep 17 00:00:00 2001 From: Tarek Tarho Date: Sat, 29 Jul 2023 14:16:13 +0200 Subject: [PATCH 2/2] add more methods --- random.js | 29 +++++++++++++++++++++++++++++ simpleTextEditor.js | 28 ---------------------------- 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/random.js b/random.js index 3167871..fed36f8 100644 --- a/random.js +++ b/random.js @@ -1357,3 +1357,32 @@ function mapNumbers(numbers) { this[number]++ } } + +const randArr = [5, 2, 6, 1, 2, 3, 5, 11] +const str1 = "hello how are you" +console.log([...new Set(randArr)].sort()) + +console.log([...new Set(randArr)].sort().reduce((total, val) => total + val, 0)) + +//slice retrun shallow copy of portaion of an array +const newArray = randArr.slice(0, randArr.length - 1) + +console.log(newArray) + +//pop will remove the last item and return it +console.log(newArray.pop()) + +//add el to the begining <-> push it add it to the end +console.log(newArray.unshift(1)) +console.log(newArray) +//remove first el and return in <-> pop +console.log(newArray.shift()) + +//every check if it's postive +console.log(randArr.every((item) => item > 0)) + +//indexOf return the frist el of each that can found in array + +console.log(newArray.indexOf(5)) + +console.log(str1.split(" ")) diff --git a/simpleTextEditor.js b/simpleTextEditor.js index f4c3eaa..9f3f42c 100644 --- a/simpleTextEditor.js +++ b/simpleTextEditor.js @@ -53,31 +53,3 @@ console.log(processData(ops2)) // f // g // d -const randArr = [5, 2, 6, 1, 2, 3, 5, 11] -const str = "hello how are you" -console.log([...new Set(randArr)].sort()) - -console.log([...new Set(randArr)].sort().reduce((total, val) => total + val, 0)) - -//slice retrun shallow copy of portaion of an array -const newArray = randArr.slice(0, randArr.length - 1) - -console.log(newArray) - -//pop will remove the last item and return it -console.log(newArray.pop()) - -//add el to the begining <-> push it add it to the end -console.log(newArray.unshift(1)) -console.log(newArray) -//remove first el and return in <-> pop -console.log(newArray.shift()) - -//every check if it's postive -console.log(randArr.every((item) => item > 0)) - -//indexOf return the frist el of each that can found in array - -console.log(newArray.indexOf(5)) - -console.log(str.split(" "))