Solutions to the interview question of the week from the rendezvous with cassidoo newsletter
Solutions in the following languages:
- TypeScript
- Elixir
Inspired and forked from jda0
Solutions to the interview question of the week from the rendezvous with cassidoo newsletter
Solutions in the following languages:
Inspired and forked from jda0
| /** | |
| * Sort an array of strings based on the number of distinct | |
| * characters that occur in the word (followed by the | |
| * length of the word). | |
| * | |
| * $ charNumSort([“Bananas”, “do”, “not”, “grow”, “in”, “Mississippi”]) | |
| * $ do in not Mississippi Bananas grow | |
| * | |
| */ | |
| const charNumSort = (input: Array<string>) => | |
| input | |
| .sort((first, second) => { | |
| // use Set() to find unique char count | |
| const compare = [...new Set(first)].length - [...new Set(second)].length; | |
| return compare ? compare : second.length - first.length; | |
| }) | |
| .join(" "); | |
| console.log(charNumSort(["Bananas", "do", "not", "grow", "in", "Mississippi"])); | |
| // https://codesandbox.io/s/modest-sanderson-wxs33?file=/src/index.ts |
| /** | |
| * Given an array of random integers, move all the zeros in the array to the end of the array. | |
| * Try to keep this in O(n) time (or better)! | |
| * Example: | |
| * $ moveZeros([1, 2, 0, 1, 0, 0, 3, 6]) | |
| * $ [1, 2, 1, 3, 6, 0, 0, 0] | |
| */ | |
| const moveZeros = (arr: Array<number>) => { | |
| let numberOfZeroes = 0; | |
| const result = arr.reduce((agg, curr) => { | |
| curr ? agg.push(curr) : numberOfZeroes++; | |
| return agg; | |
| }, [] as number[]); | |
| return [...result, ...Array(numberOfZeroes).fill(0)]; | |
| }; | |
| console.log(moveZeros([1, 2, 0, 1, 0, 0, 3, 6])); | |
| // https://codesandbox.io/s/misty-forest-pxdog?file=/src/index.ts |
| /** | |
| * Given a string s and a character c, return the number of occurrences of c in s. | |
| * Example: | |
| * | |
| * $ numChars(‘oh heavens’, ‘h’) | |
| * $ 2 | |
| */ | |
| const numChars = (input: string, char: string) => | |
| /** | |
| * yay regular expressions! global flag since we wanna count *all* instances | |
| * return 0 in case of no matches | |
| */ | |
| (input.match(RegExp(char, "g")) || []).length; | |
| console.log(numChars("oh heavens", "h")); | |
| // https://codesandbox.io/s/mystifying-swirles-8h5it?file=/src/index.ts |
| /** | |
| * Given an array of numbers that represent stock prices (where each number is the price for | |
| * a certain day), find 2 days when you should buy and sell your stock for the highest profit. | |
| * Example: | |
| * | |
| * $ stockBuySell([110, 180, 260, 40, 310, 535, 695]) | |
| * $ “buy on day 4, sell on day 7” | |
| */ | |
| const stockBuySell = (prices: Array<number>) => | |
| `buy on day ${prices.indexOf(Math.min(...prices)) + 1}\ | |
| , sell on day ${prices.indexOf(Math.max(...prices)) + 1}`; | |
| // A much faster (the earlier one is ~88% slower, https://jsbench.me/54keiiwuvy/1) way | |
| const stockBuySellReduce = (prices: Array<number>) => { | |
| const minMax = prices.reduce( | |
| (agg, curr, index, arr) => { | |
| if (curr < arr[agg.min]) agg.min = index; | |
| else if (curr > arr[agg.max]) agg.max = index; | |
| return agg; | |
| }, | |
| { min: 0, max: 0 } | |
| ); | |
| return `buy on day ${minMax.min + 1}, sell on day ${minMax.max + 1}`; | |
| }; | |
| console.log(stockBuySell([110, 180, 260, 40, 310, 535, 695])); | |
| console.log(stockBuySellReduce([110, 180, 260, 40, 310, 535, 695])); | |
| // https://codesandbox.io/s/sharp-jepsen-8npl1?file=/src/index.ts |
| /** | |
| * Given an array of people objects (where each person has a name | |
| * and a number of pizza slices they’re hungry for) and a number | |
| * for the number of slices that the pizza can be sliced into, return | |
| * the number of pizzas you need to buy. | |
| * | |
| * $ arr = [{ name: Joe, num: 9 }, { name: Cami, num: 3 }, { name: Cassidy, num: 4 }] | |
| * $ gimmePizza(arr, 8) | |
| * $ 2 // 16 slices needed, pizzas can be sliced into 8 pieces, so 2 pizzas should be ordered | |
| */ | |
| type TPeopleSlicesMap = { | |
| name: string; | |
| num: number; | |
| }; | |
| const gimmePizza = (arr: Array<TPeopleSlicesMap>, maxSlices: number) => { | |
| const totalSlices = arr.reduce((total, { num }) => { | |
| return (total += num); | |
| }, 0); | |
| return Math.ceil(totalSlices / maxSlices); | |
| }; | |
| const inputMap = [ | |
| { name: "Joe", num: 9 }, | |
| { name: "Cami", num: 3 }, | |
| { name: "Cassidy", num: 4 } | |
| ]; | |
| console.log(gimmePizza(inputMap, 8)); | |
| // https://codesandbox.io/s/young-darkness-61nq3?file=/src/index.ts |
| /** | |
| * Given a positive integer n, write a function that returns | |
| * true if it is a perfect square and false otherwise. | |
| * Don’t use any built-in math functions like sqrt. | |
| * Hint: Use binary search! | |
| * | |
| * Examples: | |
| * $ perfectSquare(25) | |
| * $ true | |
| * | |
| * $ perfectSquare(10) | |
| * $ false | |
| */ | |
| const isPerfectSquare = (input: number) => { | |
| const binarySearchPerfectSquare = ( | |
| input: number, | |
| start: number, | |
| end: number | |
| ): number | boolean => { | |
| if (start > end) return false; | |
| // mid value, parsed to an int using bitwise operator | |
| const mid = ((start + end) / 2) >> 0; | |
| if (mid * mid < input) | |
| return binarySearchPerfectSquare(input, mid + 1, end); | |
| if (mid * mid > input) | |
| return binarySearchPerfectSquare(input, start, mid - 1); | |
| // mid*mid === input, perfect square! | |
| return true; | |
| }; | |
| return binarySearchPerfectSquare(input, 1, input); | |
| }; | |
| console.log(isPerfectSquare(25)); | |
| console.log(isPerfectSquare(10)); | |
| // https://codesandbox.io/s/relaxed-pine-yofdz?file=/src/index.ts |
| /** | |
| * Given an array of integers and a target value, return the number of | |
| * pairs of array elements that have a difference equal to a target value. | |
| * | |
| * Example: | |
| * $ arrayDiff([1, 2, 3, 4], 1) | |
| * $ 3 // 2 - 1 = 1, 3 - 2 = 1, and 4 - 3 = 1 | |
| */ | |
| const arrayDiff = (arr: Array<number>, target: number) => { | |
| let count = 0, | |
| flag = false; | |
| arr.sort() | |
| .reverse() | |
| .forEach((baseNum, i, reverseSortedArr) => { | |
| if (i === arr.length) return; | |
| flag = false; | |
| reverseSortedArr.slice(i + 1).forEach((num, j) => { | |
| // arr is sorted, so we won't get the target diff again | |
| if (flag) return; | |
| if (j === reverseSortedArr.length) return; | |
| if (baseNum - num === target) { | |
| count += 1; | |
| flag = true; | |
| } | |
| }); | |
| }); | |
| return count; | |
| }; | |
| console.log(arrayDiff([1, 2, 3, 4], 1)); | |
| // https://codesandbox.io/s/cool-satoshi-84ku4?file=/src/index.ts |
| /** | |
| * You’re given a string of characters that are only 2s and 0s. Return the | |
| * index of the first occurrence of “2020” without using the indexOf (or | |
| * similar) function, and -1 if it’s not found in the string. | |
| * | |
| * Example: | |
| * $ find2020(‘2220000202220020200’) | |
| * $ 14 | |
| */ | |
| const find2020 = (input: string) => { | |
| let index = -1; | |
| input.split("").reduce((_shouldBe2020, _curr, i) => { | |
| const next4 = input.slice(i, i + 4); | |
| if (next4 === "2020") index = i; | |
| return next4; | |
| }, input.slice(0, 4)); | |
| return index; | |
| }; | |
| // https://codesandbox.io/s/sharp-mountain-wddiy?file=/src/index.ts |
| /** | |
| * Given a rowIndex, return an array of the values in that | |
| * row of Pascal’s Triangle. | |
| */ | |
| const getCurrentRow = (previousRow: Array<number>): Array<number> => { | |
| return Array.from(Array(previousRow.length + 1)).map((_, i) => { | |
| if (i === 0) return 1; | |
| else if (i === previousRow.length) return 1; | |
| else return previousRow[i - 1] + previousRow[i]; | |
| }); | |
| }; | |
| const getPascalRow = (index: number): Array<number> => { | |
| if (index === 0) return [1]; | |
| return getCurrentRow(getPascalRow(index - 1)); | |
| }; | |
| console.log(getPascalRow(0)); // [1] | |
| console.log(getPascalRow(1)); // [1, 1] | |
| console.log(getPascalRow(2)); // [1, 2, 1] | |
| console.log(getPascalRow(3)); // [1, 3, 3, 1] | |
| console.log(getPascalRow(4)); // [1, 4, 6, 4, 1] | |
| // https://codesandbox.io/s/heuristic-wood-qzzbd?file=/src/index.ts |
| /** | |
| * Given an integer n, return true if n^3 and n have the same set of digits. | |
| * Example: | |
| * | |
| * $ sameDigits(1) // true | |
| * $ sameDigits(10) // true | |
| * $ sameDigits(251894) // true | |
| * $ sameDigits(251895) // false | |
| */ | |
| const INPUTS = [1, 10, 251894, 251895]; | |
| const getUniqueDigitsAsString = (input: number) => | |
| [...new Set(input.toString().split("").sort())].join(); | |
| const sameDigits = (input: number) => { | |
| const inputDigits = getUniqueDigitsAsString(input); | |
| const cubeDigits = getUniqueDigitsAsString(Math.pow(input, 3)); | |
| return inputDigits === cubeDigits; | |
| }; | |
| INPUTS.forEach(input => console.log(sameDigits(input))) | |
| // true, true, true, false | |
| // https://codesandbox.io/s/cold-cdn-85qcb?file=/src/index.ts |
| /** | |
| * Given a list, return a list of all its prefixes in ascending order of their | |
| * length. You’re essentially implementing the inits function in Haskell! | |
| * | |
| * Example: | |
| * $ inits([4, 3, 2, 1]) | |
| * $ [[], [4], [4,3], [4,3,2], [4,3,2,1]] | |
| * | |
| * $ inits([144]) | |
| * $ [[], [144]] | |
| */ | |
| const INPUT = [4, 3, 2, 1]; | |
| const inits = (input: Array<number>) => | |
| input.reduce( | |
| (arr, curr, index) => { | |
| arr.push([...arr[index], curr]); | |
| return arr; | |
| }, | |
| [[]] as number[][] | |
| ); | |
| console.log(inits(INPUT)); | |
| // https://codesandbox.io/s/determined-swanson-qn27b?file=/src/index.ts |
| /** | |
| * Given a direction and a number of columns, write a function that outputs an | |
| * arrow of asterisks (see the pattern in the examples below)! | |
| * | |
| * Example: | |
| * | |
| * $ printArrow('right', 3) | |
| * Output: | |
| * | |
| * | |
| * | |
| * | |
| * | |
| * $ printArrow('left', 5) | |
| * Output: | |
| * | |
| * | |
| * | |
| * | |
| * | |
| * | |
| * | |
| * | |
| * | |
| */ | |
| const printArrow = (direction: "right" | "left", len: number) => { | |
| Array.from(Array(2 * (len - 1) + 1)).forEach((_, index) => { | |
| let numSpaces; | |
| if (direction === "right") { | |
| numSpaces = index > len - 1 ? 2 * len - 2 - index : index; | |
| } else { | |
| numSpaces = len - (index > len - 1 ? 2 * len - 1 - index : index + 1); | |
| } | |
| console.log(`${" ".repeat(numSpaces)}*`); | |
| }); | |
| }; | |
| // https://codesandbox.io/s/gifted-perlman-0yvo0?file=/src/index.ts |
| const LINE = "█".repeat(10); | |
| const PRIDE_COLORS = [ | |
| "#e40303", | |
| "#ff8c00", | |
| "#ffed00", | |
| "#008026", | |
| "#004dff", | |
| "#750787" | |
| ]; | |
| const PrideFlag = () => { | |
| PRIDE_COLORS.forEach((color) => { | |
| console.log(`%c${LINE}`, `color: ${color}`); | |
| }); | |
| }; | |
| PrideFlag(); | |
| // https://codesandbox.io/s/blissful-leavitt-86k1s?file=/src/index.ts |
| /** | |
| * Write a function to find the longest common prefix string in an array of | |
| * strings. | |
| * | |
| * Example: | |
| * | |
| * $ longestPrefix(["cranberry","crawfish","crap"]) | |
| * $ "cra" | |
| * | |
| * $ longestPrefix(["parrot", "poodle", "fish"]) | |
| * $ "" | |
| */ | |
| function longestPrefix(input: Array<string>) { | |
| let result = ""; | |
| input[0].split("").reduce((prefix, currentLetter) => { | |
| const isPrefixValid = input.every((word) => word.startsWith(prefix)); | |
| if (isPrefixValid) { | |
| result = prefix; | |
| return `${prefix}${currentLetter}`; | |
| } | |
| return result; | |
| }, ""); | |
| return result; | |
| } | |
| // https://codesandbox.io/s/heuristic-dan-pl0nn?file=/src/index.ts |
| /** | |
| * An “odious number” is a non-negative number that has an | |
| * odd number of 1s in its binary expansion. Write a | |
| * function that returns true if a given number is odious. | |
| * | |
| * Example: | |
| * | |
| * $ isOdious(14) | |
| * $ true | |
| * | |
| * $ isOdious(5) | |
| * $ false | |
| */ | |
| const isOdious = (input: number) => | |
| (input.toString(2).match(/1/g) ?? []).length % 2 === 1; | |
| // https://codesandbox.io/s/admiring-poitras-8l6sd?file=/src/index.ts |
| /** | |
| * Given an array of objects A, and an array of indexes B, | |
| * reorder the objects in array A with the given indexes | |
| * in array B. | |
| * | |
| * Example: | |
| * | |
| * let a = [C, D, E, F, G, H]; | |
| * let b = [3, 0, 4, 1, 2, 5]; | |
| * | |
| * $ reorder(a, b) // a is now [D, F, G, C, E, H] | |
| */ | |
| const reorder = ( | |
| a: Array<Record<string, unknown> | string>, | |
| b: Array<number> | |
| ) => | |
| [...Array(a.length)].reduce((res, _, index) => { | |
| res[b[index]] = a[index]; | |
| return res; | |
| }, []); | |
| // https://codesandbox.io/s/agitated-bash-tmu25?file=/src/index.ts |
| defmodule RWC_259 do | |
| @doc """ | |
| Given an integer n, count the total number of 1 digits appearing in all | |
| non-negative integers less than or equal to n. | |
| Example: | |
| > numberOfOnes(14) | |
| > 7 // 1, 10, 11, 12, 13, 14 | |
| """ | |
| defp count_one_recursively(input, count) when input == 1, do: count + 1 | |
| defp count_one_recursively(input, count) do | |
| input | |
| |> Integer.to_string() | |
| |> String.split("") | |
| |> Enum.count(&(&1 == "1")) | |
| |> then(fn x -> | |
| case x > 0 do | |
| true -> | |
| count_one_recursively(input - 1, count + x) | |
| _ -> | |
| count_one_recursively(input - 1, count) | |
| end | |
| end) | |
| end | |
| def number_of_ones(input) do | |
| input | |
| |> count_one_recursively(0) | |
| |> IO.puts() | |
| end | |
| end | |
| RWC_259.number_of_ones(14) |
| defmodule RWC_270 do | |
| @doc """ | |
| Let’s say you have n doors that start out as closed. With the first pass | |
| across the doors, you toggle every door open. With the second pass, you | |
| toggle every second door. With the third, every third door, and so on. | |
| Write a function that takes in an integer numberOfPasses, and returns how | |
| many doors are open after the number of passes. | |
| Example: | |
| let n = 7 | |
| let numberOfPasses = 3 | |
| > passDoors(n, numberOfPasses) | |
| > 4 | |
| // Explanation: | |
| // 0 means open, 1 means closed | |
| // Initial: 1 1 1 1 1 1 1 | |
| // Pass 1: 0 0 0 0 0 0 0 | |
| // Pass 2: 0 1 0 1 0 1 0 | |
| // Pass 3: 0 1 1 1 0 0 0 | |
| """ | |
| @spec pass_doors(n :: non_neg_integer, number_of_passes :: non_neg_integer) :: non_neg_integer | |
| def pass_doors(n, number_of_passes) do | |
| 1..number_of_passes | |
| # duplicate with n+1 because map_every/3 starts from first elem indexed 0 | |
| # open => true, closed => false | |
| |> Enum.reduce(List.duplicate(false, n + 1), fn nth, doors -> | |
| Enum.map_every(doors, nth, &(not &1)) | |
| end) | |
| # ignore the extra door we added at the start | |
| |> Enum.drop(1) | |
| |> Enum.count(& &1) | |
| end | |
| end | |
| RWC_270.pass_doors(7, 3) |
| defmodule RWC_281 do | |
| @doc """ | |
| Given an array of integers arr and an integer n, return a subarray | |
| of arr of length n where the sum is the largest. | |
| Make sure you maintain the order of the original array, and if n | |
| is greater than arr.length, you can choose what you want to return. | |
| > maxSubarray([-4,2,-5,1,2,3,6,-5,1], 4) | |
| > [1,2,3,6] | |
| > maxSubarray([1,2,0,5], 2) | |
| > [0,5] | |
| """ | |
| def maxSubarray(input, size) do | |
| input | |
| |> Enum.chunk_every(size, 1, :discard) | |
| |> Enum.max_by(&Enum.sum(&1)) | |
| end | |
| end | |
| IO.inspect(RWC_281.maxSubarray([-4, 2, -5, 1, 2, 3, 6, -5, 1], 4)) | |
| IO.inspect(RWC_281.maxSubarray([1, 2, 0, 5], 2)) |
| defmodule RWC_282 do | |
| @doc """ | |
| Given a number, sum every second digit in that number. | |
| Example: | |
| > sumEveryOther(548915381) | |
| > 26 // 4+9+5+8 | |
| > sumEveryOther(10) | |
| > 0 | |
| > sumEveryOther(1010.11) | |
| > 1 // 0+0+1 | |
| """ | |
| def sumEveryOther(input) do | |
| input | |
| |> to_string() | |
| |> String.graphemes() | |
| |> List.delete_at(0) | |
| |> Enum.filter(&(&1 !== ".")) | |
| |> Enum.take_every(2) | |
| |> Enum.map(&String.to_integer/1) | |
| |> Enum.sum() | |
| end | |
| end |
| defmodule RWC_284 do | |
| @doc """ | |
| You are given a list of positive integers which represents some | |
| range of integers which has been truncated. Find the missing bits, | |
| insert ellipses to show that that part has been truncated, and | |
| print it. If the consecutive values differ by exactly two, | |
| then insert the missing value. | |
| Examples: | |
| > missingBits([1,2,3,4,20,21,22,23]) | |
| > "[1,2,3,4,...,20,21,22,23]" | |
| > missingBits([1,2,3,5,6]) | |
| > "[1,2,3,4,5,6]" | |
| > missingBits([1,3,20,27]) | |
| > "[1,2,3,...,20,...,27]" | |
| """ | |
| def missingBits(input) do | |
| input | |
| |> Enum.with_index() | |
| |> then(fn input_with_index -> | |
| input_with_index | |
| |> Enum.reduce([], fn {num, index}, acc -> | |
| {next_num, _} = Enum.at(input_with_index, index + 1, {num, nil}) | |
| case next_num - num do | |
| # Last index | |
| 0 -> [num | acc] | |
| 1 -> [num | acc] | |
| # When step is exactly two | |
| 2 -> [num + 1, num | acc] | |
| _ -> ["...", num | acc] | |
| end | |
| end) | |
| |> Enum.reverse() | |
| |> Enum.join(",") | |
| |> then(&"[#{&1}]") | |
| end) | |
| end | |
| end |
| defmodule RWC_285 do | |
| @doc """ | |
| Given a positive integer, generate an array in which every | |
| element is an array that goes from 1 to the index of that array. | |
| Example: | |
| > generateArrays(4) | |
| > [[1], [1, 2], [1, 2, 3], [1, 2, 3, 4]] | |
| > generateArrays(1) | |
| > [[1]] | |
| """ | |
| def generateArrays(input) do | |
| 1..input | |
| |> Enum.to_list() | |
| |> Enum.map(&Enum.to_list(1..&1)) | |
| end | |
| end |
| defmodule RWC_286 do | |
| @doc """ | |
| Spreadsheet programs often use the A1 Reference Style to refer to columns. | |
| Given a column name in this style, return its column number. | |
| Examples of column names to their numbers: | |
| A -> 1 | |
| B -> 2 | |
| C -> 3 | |
| // etc | |
| Z -> 26 | |
| AA -> 27 | |
| AB -> 28 | |
| // etc | |
| AAA -> 703 | |
| """ | |
| def get_weight(char, power) do | |
| char | |
| |> String.to_charlist() | |
| |> hd() | |
| # A => 65, B => 66, so on... | |
| |> then(&(&1 - 64)) | |
| |> then(&(&1 * 26 ** power)) | |
| end | |
| def recusively_get_weight([{char, index}]), do: get_weight(char, index) | |
| def recusively_get_weight([left | rest]), | |
| do: recusively_get_weight([left]) + recusively_get_weight(rest) | |
| def get_column_number(input) do | |
| input | |
| |> String.split("", trim: true) | |
| |> Enum.reverse() | |
| |> Enum.with_index() | |
| |> recusively_get_weight() | |
| end | |
| end |
| defmodule RWC_287 do | |
| @doc """ | |
| Print the digits 0 through 100 without using the characters | |
| 1, 2, 3, 4, 5, 6, 7, 8, or 9 in your code. Get creative! | |
| """ | |
| def print_digits() do | |
| hundred = | |
| "d" | |
| |> to_charlist() | |
| |> hd() | |
| zero = | |
| [hundred - hundred] | |
| |> hd() | |
| zero..hundred | |
| |> Enum.join(", ") | |
| end | |
| end |
| defmodule RWC_288 do | |
| @doc """ | |
| Given a string of parenthesis, return the number of parenthesis | |
| you need to add to the string in order for it to be balanced. | |
| Examples: | |
| > numBalanced(`()`) | |
| > 0 | |
| > numBalanced(`(()`) | |
| > 1 | |
| > numBalanced(`))()))))()`) | |
| > 6 | |
| > numBalanced(`)))))`) | |
| > 5 | |
| """ | |
| def num_balanced(input) do | |
| input | |
| |> String.split("", trim: true) | |
| |> Enum.frequencies() | |
| |> Map.values() | |
| |> then( | |
| &case &1 do | |
| [only_one_kind] -> only_one_kind | |
| [one, other] -> abs(one - other) | |
| end | |
| ) | |
| end | |
| end |
| defmodule RWC_289 do | |
| @doc """ | |
| Given a list of numbers, return all groups of repeating consecutive numbers. | |
| Examples: | |
| > repeatedGroups([1, 2, 2, 4, 5]) | |
| [[2, 2]] | |
| > repeatedGroups([1, 1, 0, 0, 8, 4, 4, 4, 3, 2, 1, 9, 9]) | |
| [[1, 1], [0, 0], [4, 4, 4], [9, 9]] | |
| """ | |
| def chunk_repeats([head | rest]), do: chunk_repeats(rest, [[head]]) | |
| def chunk_repeats([], done), do: done | |
| def chunk_repeats([head | rest], [[head | head_repeated] | previously_repeated]), | |
| do: chunk_repeats(rest, [[head | [head | head_repeated]] | previously_repeated]) | |
| def chunk_repeats([head | rest], previously_repeated), | |
| do: chunk_repeats(rest, [[head] | previously_repeated]) | |
| def repeated_groups(input) do | |
| input | |
| |> chunk_repeats() | |
| |> Enum.reverse() | |
| |> Enum.filter(&(length(&1) > 1)) | |
| end | |
| end |
| defmodule RWC_300 do | |
| @doc """ | |
| Write a function to find out whether the binary representation of | |
| a number is palindrome or not. | |
| Example: | |
| > binaryPal(5) | |
| > true | |
| > binaryPal(10) | |
| > false | |
| """ | |
| def binary_pal(input) do | |
| input | |
| |> Integer.to_charlist(2) | |
| |> List.to_string() | |
| |> then(fn digits -> | |
| digits | |
| |> String.reverse() | |
| |> then( | |
| &case &1 do | |
| ^digits -> true | |
| _ -> false | |
| end | |
| ) | |
| end) | |
| end | |
| end |
| defmodule RWC_301 do | |
| @doc """ | |
| Given a string, calculate the score that it would get in a game of Scrabble. | |
| For extra credit, try verifying if the string is a valid word, or take into | |
| account premium squares! | |
| Scoring and example: | |
| 1 point: E, A, I, O, N, R, T, L, S, U | |
| 2 points: D, G | |
| 3 points: B, C, M, P | |
| 4 points: F, H, V, W, Y | |
| 5 points: K | |
| 8 points: J, X | |
| 10 points: Q, Z | |
| > scrabbleScore('FIZZBUZZ') | |
| > 49 | |
| """ | |
| @score_map %{ | |
| "EAIONRTLSU" => 1, | |
| "DG" => 2, | |
| "BCMP" => 3, | |
| "FHVWY" => 4, | |
| "K" => 5, | |
| "JX" => 8, | |
| "QZ" => 10 | |
| } | |
| def scrabble_score(input) do | |
| input | |
| |> String.split("", trim: true) | |
| |> Enum.reduce(0, fn letter, score -> | |
| @score_map | |
| |> Map.keys() | |
| |> Enum.find(&String.contains?(&1, letter)) | |
| |> then(&Map.get(@score_map, &1)) | |
| |> Kernel.+(score) | |
| end) | |
| end | |
| end |
| defmodule RWC_303 do | |
| @doc """ | |
| Given an array of people objects (where each person has a name and a number of | |
| pie pieces they’re hungry for) and a number for the number of pieces that the | |
| pie can be cut into, return the number of pies you need to buy. | |
| Example: | |
| iex> | |
| ...> arr = [ | |
| ...> %{ name: Joe, num: 9 }, | |
| ...> %{ name: Cami, num: 3 }, | |
| ...> %{ name: Cassidy, num: 4 } | |
| ...> ] | |
| iex> RWC_303.num_pie(arr, 8) | |
| 2 # 16 pieces needed, pies can be cut into 8 pieces, so 2 pies should be bought | |
| """ | |
| def num_pie(input, count) do | |
| input | |
| |> Enum.reduce(0, &(&2 + &1[:num])) | |
| |> div(count) | |
| end | |
| end |
| defmodule RWC_304 do | |
| @doc """ | |
| Given an array arr and integers n and m, remove n elements | |
| from the front of the array, and m elements from the back. | |
| Assume that n + m <= arr.length. | |
| Example: | |
| iex> RWC_304.trim_array([1, 2, 3, 4, 5, 6], 2, 1) | |
| [3, 4, 5] | |
| iex> RWC_304.trim_array([6, 2, 4, 3, 7, 1, 3], 5, 0) | |
| [1, 3] | |
| iex> RWC_304.trim_array([1, 7], 0, 0) | |
| [1, 7] | |
| """ | |
| def trim_array(input, n, m) do | |
| input | |
| |> Enum.slice(n, length(input) - n - m) | |
| end | |
| end |
| defmodule RWC_305 do | |
| @doc """ | |
| Given some JSON data, calculate the maximum depth reached. Both arrays | |
| and dictionaries increase the depth! If the input is invalid data, the | |
| response should be undefined (you decide how you want that to return). | |
| iex> RWC_305.depth_json([]) | |
| 1 | |
| iex> RWC_305.depth_json([1, 2, 3, 4, 5]) | |
| 1 | |
| iex> RWC_305.depth_json([%{a: []}, ["abc"]]) | |
| 3 | |
| """ | |
| def depth_json(input), do: compute_depth(input) | |
| defp compute_depth(input) when is_list(input) or is_map(input) do | |
| cond do | |
| is_list(input) and input == [] -> | |
| 1 | |
| true -> | |
| input | |
| |> flatten_if_map() | |
| |> Enum.map(&compute_depth/1) | |
| |> Enum.max() | |
| |> Kernel.+(1) | |
| end | |
| end | |
| defp compute_depth(_), do: 0 | |
| defp flatten_if_map(input) when is_map(input), do: Map.values(input) | |
| defp flatten_if_map(input), do: input | |
| end |
| defmodule RWC_306 do | |
| @doc """ | |
| Write a function that takes an array of consecutive, increasing letters as input, | |
| and returns any missing letters in the array between the first and last letter. | |
| Example: | |
| iex> RWC_306.missing_letters(["a","b","c","d","f"]) | |
| ["e"] | |
| iex> RWC_306.missing_letters(["a","b","c","d","e","h","i","j","k","l","m","n","o", | |
| ...> "p","q","r","s","t","u","w","x","y","z"]) | |
| ["f","g","v"] | |
| """ | |
| def missing_letters(input) do | |
| input_complete_mapset = | |
| input | |
| |> then(fn list -> | |
| [head | _] = list | |
| tail = List.last(list) | |
| hd(to_charlist(head))..hd(to_charlist(tail)) | |
| |> MapSet.new() | |
| end) | |
| input_mapset = | |
| input | |
| |> MapSet.new(&hd(to_charlist(&1))) | |
| input_complete_mapset | |
| |> MapSet.difference(input_mapset) | |
| |> MapSet.to_list() | |
| |> List.to_string() | |
| |> String.graphemes() | |
| end | |
| end |
| defmodule RWC_307 do | |
| @doc """ | |
| Given an integer n, return true if it's a perfect | |
| square AND when reversed, is still a perfect square. | |
| iex> RWC_307.reversed_squares(9) | |
| true | |
| iex> RWC_307.reversed_squares(441) | |
| true | |
| iex> RWC_307.reversed_squares(25) | |
| false | |
| """ | |
| def reversed_squares(input) do | |
| input | |
| |> Integer.digits() | |
| |> Enum.reverse() | |
| |> Integer.undigits() | |
| |> then( | |
| &cond do | |
| is_perfect_square(&1) and is_perfect_square(input) -> true | |
| true -> false | |
| end | |
| ) | |
| end | |
| defp is_perfect_square(input) do | |
| input | |
| |> :math.sqrt() | |
| |> then(&if Kernel.trunc(&1) == &1, do: true, else: false) | |
| end | |
| end |
| defmodule RWC_308 do | |
| @doc """ | |
| Given an array of strings and a max width, format the text such that each line has exactly | |
| maxWidth characters and is fully justified. You can choose how you want to wrap a word. | |
| Example: | |
| iex> RWC_308.justify_text(["This", "is", "an", "example", "of", "text", "justification."], 16) | |
| [ | |
| "This is an", | |
| "example of text", | |
| "justification. " | |
| ] | |
| """ | |
| def justify_text(input, max_length) do | |
| input | |
| |> Enum.reduce([[]], fn word, phrase_list -> | |
| phrase_list | |
| |> List.last([]) | |
| |> then(fn last_phrase -> | |
| current_phrase_length = last_phrase |> Enum.join(".") |> String.length() | |
| cond do | |
| current_phrase_length + String.length(word) < max_length -> | |
| # update last element | |
| last_list = | |
| phrase_list | |
| |> Enum.at(-1) | |
| |> Enum.concat([word]) | |
| phrase_list | |
| |> Enum.drop(-1) | |
| |> Enum.concat([last_list]) | |
| true -> | |
| # move to new phrase | |
| phrase_list | |
| |> Enum.concat([[word]]) | |
| end | |
| end) | |
| end) | |
| |> Enum.map(&justify_phrase(&1, max_length)) | |
| end | |
| defp justify_phrase(input, max_length) do | |
| number_of_spaces_to_add = max_length - (input |> Enum.join("") |> String.length()) | |
| number_of_breaks = if length(input) == 1, do: 1, else: length(input) - 1 | |
| each_space_block_length = div(number_of_spaces_to_add, number_of_breaks) | |
| remainder = rem(number_of_spaces_to_add, number_of_breaks) | |
| spaces_list = | |
| " " | |
| |> list_from(each_space_block_length) | |
| |> list_from(number_of_breaks) | |
| |> then(fn [first_break_spaces | rest] -> | |
| case remainder do | |
| 0 -> | |
| [first_break_spaces | rest] | |
| _ -> | |
| first_break_spaces | |
| |> Enum.concat(list_from(" ", remainder)) | |
| |> then(&[&1 | rest]) | |
| end | |
| end) | |
| |> then( | |
| &cond do | |
| length(input) == 1 -> &1 | |
| true -> Enum.concat(&1, [[""]]) | |
| end | |
| ) | |
| input | |
| |> Enum.zip(spaces_list) | |
| |> Enum.reduce("", fn {word, spaces}, line -> | |
| "#{line}#{word}#{Enum.join(spaces)}" | |
| end) | |
| end | |
| defp list_from(el, count), do: for(_ <- 1..count, do: el) | |
| end |
| defmodule RWC_309 do | |
| @doc """ | |
| Given a string, separate it into groups of non-space equal characters, sorted. | |
| Example: | |
| iex> RWC_309.explode_string("Ahh, abracadabra!") | |
| ["!",",","A","aaaaa","bb","c","d","hh","rr"] | |
| """ | |
| def explode_string(input) do | |
| input | |
| |> String.replace(" ", "") | |
| |> String.split("", trim: true) | |
| |> Enum.frequencies() | |
| |> Map.to_list() | |
| |> Enum.map(fn {char, count} -> | |
| list_from(char, count) | |
| |> Enum.join() | |
| end) | |
| end | |
| defp list_from(el, count), do: for(_ <- 1..count, do: el) | |
| end |
| defmodule RWC_310 do | |
| @doc """ | |
| Given an array where each element is the price of a given stock on that index's day, | |
| choose a single day to buy a stock and a different day (in the future/later in the array) | |
| to sell the stock to maximize your profit. Return the maximum profit that you can get | |
| from a given input. If you can't profit, return 0. | |
| Example: | |
| iex> RWC_310.maximum_profit([7, 1, 5, 3, 6, 4]) | |
| 5 # Buy on day 2, and sell on day 5, your profit = 6 - 1 = 5. | |
| """ | |
| def maximum_profit(input) do | |
| input | |
| |> Enum.with_index() | |
| |> Enum.reduce(0, fn {price, index}, max_profit -> | |
| input | |
| |> Enum.slice((index + 1)..-1) | |
| |> Enum.max(&>=/2, fn -> 0 end) | |
| |> Kernel.-(price) | |
| |> then( | |
| &cond do | |
| &1 > max_profit -> &1 | |
| true -> max_profit | |
| end | |
| ) | |
| end) | |
| end | |
| end |
| defmodule RWC_311 do | |
| @doc """ | |
| Given two strings s and t, return true if t is an anagram of s, and false otherwise. | |
| Try this in a language you're not comfortable with! | |
| Example: | |
| iex> RWC_311.is_anagram("barbie", "oppenheimer") | |
| false | |
| iex> RWC_311.is_anagram("race", "care") | |
| true | |
| """ | |
| def is_anagram(a, b), do: get_chars(a) === get_chars(b) | |
| defp get_chars(input), do: input |> String.split("", trim: true) |> Enum.frequencies() | |
| end |
| defmodule RWC_312 do | |
| @doc """ | |
| Implement the Luhn algorithm to validate a credit card number. | |
| Bonus points if you can identify what brand of credit card the user inputted! | |
| iex> RWC_312.luhn_check(123456789) | |
| false | |
| iex> RWC_312.luhn_check(5555555555554444) | |
| true | |
| """ | |
| def luhn_check(input) do | |
| input | |
| |> Integer.digits() | |
| |> Enum.with_index(1) | |
| |> Enum.reduce(0, fn {digit, index}, sum -> | |
| cond do | |
| rem(index, 2) == 0 -> digit * 2 | |
| true -> digit | |
| end | |
| |> Integer.digits() | |
| |> Enum.sum() | |
| |> Kernel.+(sum) | |
| end) | |
| |> then(&(rem(&1, 10) == 0)) | |
| end | |
| end |
| defmodule RWC_313 do | |
| @doc """ | |
| You have a faulty keyboard. Whenever you type a vowel on it (a,e,i,o,u,y), | |
| it reverses the string that you have written, instead of typing the character. | |
| Typing other characters works as expected. Given a string, return what will be | |
| on the screen after typing with your faulty keyboard. | |
| Example: | |
| iex> RWC_313.faulty_keeb("string") | |
| "rtsng" | |
| iex> RWC_313.faulty_keeb("hello world!") | |
| "w hllrld!" | |
| """ | |
| @vowels ["a", "e", "i", "o", "u", "y"] | |
| def faulty_keeb(input) do | |
| input | |
| |> String.graphemes() | |
| |> Enum.reduce([], fn char, word -> | |
| cond do | |
| Enum.member?(@vowels, char) -> Enum.reverse(word) | |
| true -> Enum.concat(word, [char]) | |
| end | |
| end) | |
| |> Enum.join() | |
| end | |
| end |
| defmodule RWC_314 do | |
| @doc """ | |
| Make a "guessing game" where there is a target number, and as the user makes | |
| guesses, the output returns higher or lower until the user is correct. | |
| Example usage: | |
| Guess the number! | |
| > 10 | |
| higher | |
| > 20 | |
| higher | |
| > 30 | |
| lower | |
| > 25 | |
| higher | |
| > 27 | |
| Correct! You won in 5 guesses! | |
| """ | |
| def solve(guess) do | |
| IO.puts("Guess the number!") | |
| input() | |
| |> solve(guess) | |
| end | |
| def solve(guess, answer, guess_count \\ 1) | |
| def solve(guess, answer, 1) when guess === answer, | |
| do: IO.puts("Correct! You won in 1 guess!") |> exit() | |
| def solve(guess, answer, guess_count) when guess === answer, | |
| do: IO.puts("Correct! You won in #{guess_count} guesses!") |> exit() | |
| def solve(guess, answer, guess_count) do | |
| cond do | |
| guess > answer -> | |
| IO.puts("lower") | |
| guess < answer -> | |
| IO.puts("higher") | |
| end | |
| input() | |
| |> solve(answer, guess_count + 1) | |
| end | |
| defp input() do | |
| IO.gets("> ") | |
| |> Integer.parse() | |
| |> then(&elem(&1, 0)) | |
| end | |
| end | |
| RWC_314.solve(:rand.uniform(100)) |
| defmodule RWC_315 do | |
| @moduledoc """ | |
| Given a sequence of numbers, generate a "count and say" string. | |
| Example: | |
| iex> RWC_315.count_and_say(112222555) | |
| "two 1s, then four 2s, then three 5s" | |
| iex> RWC_315.count_and_say(3333333333) | |
| "ten 3s" | |
| """ | |
| @number_say_map %{ | |
| 1 => "one", | |
| 2 => "two", | |
| 3 => "three", | |
| 4 => "four", | |
| 5 => "five", | |
| 6 => "six", | |
| 7 => "seven", | |
| 8 => "eight", | |
| 9 => "nine", | |
| 10 => "ten" | |
| } | |
| def count_and_say(input) do | |
| input | |
| |> Integer.digits() | |
| # count | |
| |> Enum.reduce([], fn number, list -> | |
| current_list = List.first(list, [nil]) | |
| current_list | |
| |> List.first() | |
| |> then(fn current_digit -> | |
| case current_digit do | |
| # same digit as current | |
| ^number -> | |
| list | |
| |> List.delete_at(0) | |
| |> then(&[[number | current_list] | &1]) | |
| # new digit | |
| _ -> | |
| [[number] | list] | |
| end | |
| end) | |
| end) | |
| |> Enum.reverse() | |
| # say | |
| |> Enum.map_join(", then ", fn list -> | |
| len = Map.get(@number_say_map, length(list)) | |
| "#{len} #{List.first(list)}s" | |
| end) | |
| end | |
| end |
| defmodule RWC_316 do | |
| @moduledoc """ | |
| Given an array of integers and a number k (where k is guaranteed to be less | |
| than the array's length), return a subarray of length k with the minimum | |
| possible sum. Maintain the order of the original array! | |
| Example: | |
| iex> RWC_316.min_subs([1, 3, 20, 4, 8, 9, 11], 3) | |
| [4, 8, 9] | |
| iex> RWC_316.min_subs([4, 4, 4, 4, 8], 2) | |
| [4, 4] | |
| """ | |
| def min_subs(input, len) do | |
| input | |
| |> Enum.chunk_every(len, 1, :discard) | |
| |> Enum.min_by(&Enum.sum/1) | |
| end | |
| end |
| defmodule RWC_317 do | |
| @moduledoc """ | |
| Given an array of integers, sort them into two separate sorted | |
| arrays of even and odd numbers. If you see a zero, skip it. | |
| Example: | |
| iex> RWC_317.separate_and_sort([4, 3, 2, 1, 5, 7, 8, 9]) | |
| [[2, 4, 8], [1, 3, 5, 7, 9]] | |
| iex> RWC_317.separate_and_sort([1,1,1,1]) | |
| [[], [1,1,1,1]] | |
| """ | |
| def separate_and_sort(input) do | |
| input | |
| |> Enum.sort() | |
| |> Enum.split_with(&(rem(&1, 2) == 0)) | |
| |> Tuple.to_list() | |
| end | |
| end |
| defmodule RWC_318 do | |
| @moduledoc """ | |
| You have n equal-sized blocks and you want to build a staircase | |
| with them. Return the number of steps you can fully build. | |
| iex> RWC_318.build_staircase(6) | |
| 3 | |
| #=> # | |
| #=> ## | |
| #=> ### | |
| iex> RWC_318.build_staircase(9) | |
| 3 #=> it takes 10 blocks to make 4 steps | |
| """ | |
| def build_staircase(input) do | |
| 1..input | |
| |> Enum.reduce_while(0, fn step, total -> | |
| cond do | |
| total + step > input -> {:halt, step - 1} | |
| true -> {:cont, total + step} | |
| end | |
| end) | |
| end | |
| end |
| defmodule RWC_322 do | |
| @moduledoc """ | |
| Given two strings s and t, determine if they are isomorphic. | |
| Two strings are isomorphic if there is a one-to-one mapping | |
| possible for every character of the first string to every | |
| character of the second string. | |
| iex> RWC_322.is_isomorphic("abb", "cdd") | |
| true # "a" maps to "c" and "b" maps to "d" | |
| iex> RWC_322.is_isomorphic("cassidy", "1234567") | |
| false # "s" cannot have a mapping to both "3" and "4" | |
| iex> RWC_322.is_isomorphic("cass", "1233") | |
| true | |
| """ | |
| def is_isomorphic(first, second) do | |
| [first, second] | |
| |> Enum.map(fn string -> | |
| string | |
| |> String.split("", trim: true) | |
| |> Enum.frequencies() | |
| |> Map.values() | |
| end) | |
| |> then(fn [f1, f2] -> f1 == f2 end) | |
| end | |
| end |
| defmodule RWC_323 do | |
| @moduledoc """ | |
| Given a string s, you are allowed to delete at most k characters. | |
| Find if the string can be a palindrome after deleting at most k characters. | |
| iex> RWC_323.k_pal("abcweca", 2) | |
| true | |
| iex> RWC_323.k_pal("abcweca", 1) | |
| false | |
| iex> RWC_323.k_pal("acwca", 2) | |
| true | |
| iex> RWC_323.k_pal("acxcb", 1) | |
| false | |
| """ | |
| def k_pal(string, count) do | |
| string | |
| |> String.graphemes() | |
| |> check_first_and_last_characters(count) | |
| end | |
| defp check_first_and_last_characters([_char], _count), do: true | |
| defp check_first_and_last_characters([char | [char]], _count), do: true | |
| defp check_first_and_last_characters(string, count) do | |
| [first | with_last] = string | |
| [last | remaining_reversed] = Enum.reverse(with_last) | |
| remaining = Enum.reverse(remaining_reversed) | |
| cond do | |
| first == last -> | |
| check_first_and_last_characters(remaining, count) | |
| first != last and count == 0 -> | |
| false | |
| first != last and count > 0 -> | |
| check_first_and_last_characters([first | remaining], count - 1) or | |
| check_first_and_last_characters(with_last, count - 1) | |
| true -> | |
| false | |
| end | |
| end | |
| end |
| defmodule RWC_325 do | |
| @moduledoc """ | |
| Given a list of words and a dictionary of letter scores, find | |
| the word with the highest score according to the rules: | |
| score = word_length * (sum of letter scores in the word) | |
| If there are multiple words with the same highest score, | |
| return the lexicographically smallest one. | |
| iex> word_list = ["apple", "banana", "cherry", "date", "fig"]; | |
| ...> RWC_325.score_word_game(word_list) | |
| "cherry" | |
| """ | |
| def score_word_game(word_list, _letter_scores \\ nil) do | |
| word_list | |
| |> Enum.map(&get_word_score/1) | |
| |> Enum.max_by(fn {_word, score} -> score end) | |
| |> then(&elem(&1, 0)) | |
| end | |
| defp get_word_score(word) do | |
| word | |
| |> String.downcase() | |
| |> String.graphemes() | |
| |> Enum.reduce(0, fn letter, total -> | |
| score = (to_charlist(letter) |> hd()) - 96 | |
| total + score | |
| end) | |
| |> then(&{word, &1}) | |
| end | |
| end |
| defmodule RWC_326 do | |
| @moduledoc """ | |
| Given a list of tasks, where each task has a duration, and a limited amount | |
| of available time to work, write a function to return the tasks that can be | |
| completed within the given time, without re-ordering the original list of tasks. | |
| Try to maximize the number of tasks that can be completed! | |
| Example: | |
| iex> tasks = [ | |
| ...> %{ name: "Task 1", duration: 4 }, | |
| ...> %{ name: "Task 2", duration: 2 }, | |
| ...> %{ name: "Task 3", duration: 7 }, | |
| ...> %{ name: "Task 4", duration: 5 }, | |
| ...> %{ name: "Task 5", duration: 1 }, | |
| ...> %{ name: "Task 6", duration: 3 } | |
| ...> ]; | |
| ...> time_to_work = 6; | |
| ...> RWC_326.do_tasks(tasks, time_to_work) | |
| ["Task 2", "Task 5", "Task 6"] | |
| """ | |
| def do_tasks(task_list, time_to_work) do | |
| task_list | |
| |> Enum.with_index() | |
| |> Enum.sort_by(fn {%{duration: duration}, _index} -> duration end) | |
| |> Enum.reduce_while({0, []}, fn {%{duration: duration}, index}, {time_sum, indices} -> | |
| cond do | |
| time_sum + duration > time_to_work -> {:halt, indices} | |
| true -> {:cont, {time_sum + duration, [index | indices]}} | |
| end | |
| end) | |
| |> Enum.sort() | |
| |> Enum.map( | |
| &(task_list | |
| |> Enum.at(&1) | |
| |> then(fn %{name: name} -> name end)) | |
| ) | |
| end | |
| end |
| defmodule RWC_327 do | |
| @moduledoc """ | |
| Given a start number a, an ending number b, and a string str that can | |
| be "odd", "even", or "prime", return all of the numbers that are odd, even, | |
| or prime between a and b. a will not always necessarily be less than b! | |
| iex> RWC_327.between_nums(3, 11, "even") | |
| [4,6,8,10] | |
| iex> RWC_327.between_nums(15, 1, "prime") | |
| [2,3,5,7,11,13] | |
| """ | |
| defp is_prime(num) do | |
| cond do | |
| num <= 1 -> | |
| false | |
| num == 2 -> | |
| true | |
| rem(num, 2) == 0 -> | |
| false | |
| true -> | |
| 3..(num - 1)//2 | |
| |> Enum.all?(&(rem(num, &1) != 0)) | |
| end | |
| end | |
| def between_nums(start, finish, option) when start > finish, | |
| do: between_nums(finish, start, option) | |
| def between_nums(start, finish, option) do | |
| start..finish | |
| |> Enum.filter(fn num -> | |
| case option do | |
| "prime" -> | |
| is_prime(num) | |
| "even" -> | |
| rem(num, 2) == 0 | |
| _ -> | |
| rem(num, 2) != 0 | |
| end | |
| end) | |
| end | |
| end |
| defmodule RWC_328 do | |
| @moduledoc """ | |
| Given two arrays calories and prices, where calories[i] and prices[i] | |
| represent the calorie content and price of the ith food item, and a | |
| daily calorie goal, find the minimum cost to achieve or exceed the daily | |
| calorie goal. If it's impossible to meet the goal, return -1. | |
| Example: | |
| iex> calories = [200, 400, 600, 800] | |
| ...> prices = [50, 60, 80, 100] | |
| ...> daily_goal = 1200 | |
| ...> RWC_328.min_cost_for_calories(calories, prices, daily_goal) | |
| 160 # the 2nd and 4th items add up to 1200 calories for the minimum cost | |
| """ | |
| def min_cost_for_calories(calories, prices, daily_goal) do | |
| calories | |
| |> Enum.with_index() | |
| |> Enum.flat_map(fn {calorie, index} -> | |
| calories | |
| |> Enum.with_index() | |
| |> Enum.slice(index..-1) | |
| |> Enum.filter(&(elem(&1, 0) != calorie)) | |
| |> Enum.map(&{elem(&1, 0) + calorie, {index, elem(&1, 1)}}) | |
| end) | |
| |> Enum.filter(&(elem(&1, 0) >= daily_goal)) | |
| |> Enum.reduce(:infinity, fn {_calories, {index_a, index_b}}, total_price -> | |
| current_combo_price = Enum.at(prices, index_a) + Enum.at(prices, index_b) | |
| cond do | |
| current_combo_price < total_price -> current_combo_price | |
| true -> total_price | |
| end | |
| end) | |
| end | |
| end |
| defmodule RWC_329 do | |
| @moduledoc """ | |
| There is a sorted integer array that has been rotated an unknown number of times. | |
| Given that rotated array, return how many times it has been rotated. | |
| It may contain duplicate numbers! | |
| iex> RWC_329.rotated_num([4, 0, 1, 2, 3]) | |
| 1 | |
| iex> RWC_329.rotated_num([7, 9, 20]) | |
| 0 | |
| iex> RWC_329.rotated_num([7, 7, 314, 1337, 7]) | |
| 4 | |
| """ | |
| def rotated_num(nums) do | |
| cond do | |
| Enum.sort(nums) == nums -> 0 | |
| true -> 1 + rotated_num(Enum.slide(nums, 0, -1)) | |
| end | |
| end | |
| end |
| defmodule RWC_330 do | |
| @moduledoc """ | |
| Given an array of integers, return the majority element. If there is no | |
| majority element, return if the array is majority even or odd numbers, | |
| and if there is none, say so. | |
| iex> RWC_330.majority([3,1,4,1]) | |
| "1" | |
| iex> RWC_330.majority([33,44,55,66,77]) | |
| "Majority odds" | |
| iex> RWC_330.majority([1,2,3,4]) | |
| "No majority" | |
| """ | |
| def majority(nums) do | |
| nums | |
| |> Enum.frequencies() | |
| |> Map.to_list() | |
| |> Enum.sort_by(fn {_, count} -> count end, :desc) | |
| |> then(fn [{possible_majority, first} | [{_, second} | _]] -> | |
| cond do | |
| first == second -> | |
| nums | |
| |> Enum.group_by(&(rem(&1, 2) == 0)) | |
| |> then(fn %{false: odds, true: evens} -> | |
| cond do | |
| length(odds) > length(evens) -> "Majority odds" | |
| length(odds) > length(evens) -> "Majority evens" | |
| true -> "No majority" | |
| end | |
| end) | |
| true -> | |
| Integer.to_string(possible_majority) | |
| end | |
| end) | |
| end | |
| end |
| defmodule RWC_331 do | |
| @moduledoc """ | |
| Write a function that determines if an array of numbers is a bitonic sequence. | |
| A bitonic sequence is a sequence of numbers in which the numbers are in | |
| increasing order, and after a certain point, they start decreasing. | |
| Extra credit: print the peak number in the sequence! | |
| iex> RWC_331.is_bitonic([1,2,3,2]) | |
| 3 # true, extra credit: 3 | |
| iex> RWC_331.is_bitonic([1,2,3]) | |
| false | |
| iex> RWC_331.is_bitonic([3,4,5,5,5,2,1]) | |
| 5 # true, extra credit: 5 | |
| """ | |
| def is_bitonic(list) do | |
| list | |
| |> Enum.reduce_while({Enum.at(list, 0), :asc}, fn num, {peak, trend} -> | |
| cond do | |
| num >= peak and trend == :asc -> {:cont, {num, :asc}} | |
| num < peak and trend == :asc -> {:cont, {peak, :desc}} | |
| num < peak and trend == :desc -> {:cont, {peak, :desc}} | |
| true -> {:halt, {peak, :err}} | |
| end | |
| end) | |
| |> then(fn | |
| {_, :err} -> false | |
| {_, :asc} -> false | |
| {peak, :desc} -> peak | |
| end) | |
| end | |
| end |
| defmodule RWC_332 do | |
| @moduledoc """ | |
| You have some gifts you want to return. Gifts bought in December have a | |
| 90-day return window, and all other gifts have a 30-day return window. | |
| Given a gift's buy date, write a function that prints the last day you | |
| can return the gift. You can choose how dates should be formatted! | |
| # Given date: "Dec 25, 2023" | |
| iex> RWC_332.return_gift("2023-12-25") | |
| "2024-03-23" # 90 days | |
| iex> RWC_332.return_gift("2023-11-25") | |
| "2023-12-24" # 30 days | |
| """ | |
| def return_gift(date) do | |
| date | |
| |> String.split("-") | |
| |> case do | |
| # December | |
| [_, "12", _] -> 90 - 1 | |
| _ -> 30 - 1 | |
| end | |
| |> then(fn days -> | |
| date | |
| |> Date.from_iso8601!() | |
| |> Date.add(days) | |
| |> Date.to_iso8601() | |
| end) | |
| end | |
| end |
| defmodule RWC_333 do | |
| @moduledoc """ | |
| Write a program that prints Happy new year! without using the | |
| string/character literals for the characters in the string! | |
| iex> RWC_333.wish_happy_new_year() | |
| "Happy New Year" | |
| """ | |
| def wish_happy_new_year() do | |
| # Charlist | |
| [72, 97, 112, 112, 121, 32, 78, 101, 119, 32, 89, 101, 97, 114] | |
| |> to_string() | |
| end | |
| end |
| defmodule RWC_334 do | |
| @moduledoc """ | |
| You have an array of letters. Return the number of possible sequences of | |
| letters you can make using the letters in the array. | |
| Extra credit: print the sequences! | |
| iex> RWC_334.letters(["X"]) | |
| 1 | |
| iex> RWC_334.letters(["A", "A", "B"]) | |
| 8 # "A", "B", "AA", "AB", "BA", "AAB", "ABA", "BAA" | |
| """ | |
| def permutations([]), do: [[]] | |
| def permutations(char_list), | |
| do: for(char <- char_list, rest <- permutations(char_list -- [char]), do: [char | rest]) | |
| def letters(char_list) do | |
| 1..length(char_list) | |
| |> Enum.flat_map(fn chunk_len -> | |
| char_list | |
| |> Enum.chunk_every(chunk_len, 1) | |
| |> Enum.flat_map(fn chunk -> | |
| chunk | |
| |> permutations() | |
| |> Enum.map(&Enum.join/1) | |
| end) | |
| end) | |
| |> Enum.uniq() | |
| |> Enum.count() | |
| end | |
| end |
| defmodule RWC_335 do | |
| @moduledoc """ | |
| Given a 2D array, write a function that flips it vertically or horizontally. | |
| iex> array = [ | |
| ...> [1,2,3], | |
| ...> [4,5,6], | |
| ...> [7,8,9] | |
| ...> ] | |
| iex> RWC_335.flip(array, "horizontal") | |
| [[3,2,1],[6,5,4],[9,8,7]] | |
| iex> RWC_335.flip(array, "vertical") | |
| [[7,8,9],[4,5,6],[1,2,3]] | |
| """ | |
| def flip(lists, "horizontal"), | |
| do: | |
| lists | |
| |> Enum.zip_with(&Function.identity/1) | |
| |> Enum.zip_with(&Enum.reverse/1) | |
| def flip(lists, "vertical"), | |
| do: | |
| lists | |
| |> Enum.zip_with(&Enum.reverse/1) | |
| |> Enum.zip_with(&Function.identity/1) | |
| end |
| defmodule RWC_360 do | |
| @moduledoc """ | |
| Write a function that takes an array of integers representing the number of | |
| flowers planted in a line, and an integer k representing the number of | |
| additional flowers you want to plant. Return whether it's possible to plant | |
| all k flowers without planting any two flowers adjacent to each other. | |
| iex> RWC_360.can_plant_flowers([1, 0, 0, 0, 1], 1) | |
| true # you can plant 1 flower between the others | |
| iex> RWC_360.can_plant_flowers([1, 0, 0, 0, 1], 2) | |
| false | |
| iex> RWC_360.can_plant_flowers([0, 0, 0, 0, 0], 3) | |
| true | |
| iex> RWC_360.can_plant_flowers([1, 0, 1, 0, 1], 1) | |
| false | |
| iex> RWC_360.can_plant_flowers([1, 0, 0, 0, 1, 0, 1], 1) | |
| true | |
| iex> RWC_360.can_plant_flowers([1, 0, 0, 0, 0, 1, 0, 1], 2) | |
| false | |
| iex> RWC_360.can_plant_flowers([1, 0, 0, 0, 0, 0, 1, 0, 1], 2) | |
| true | |
| """ | |
| def can_plant_flowers(flowers, count) do | |
| flowers | |
| |> then(fn flowers -> | |
| flowers | |
| |> pad_ones() | |
| |> Enum.reverse() | |
| |> pad_ones() | |
| |> Enum.reverse() | |
| end) | |
| |> Enum.chunk_by(&(&1 == 1)) | |
| |> Enum.filter(&Enum.all?(&1, fn x -> x == 0 end)) | |
| |> Enum.map(fn zeros_list -> | |
| zeros_list | |
| |> Enum.chunk_every(3, 2, :discard) | |
| |> Enum.count(&(&1 == [0, 0, 0])) | |
| |> then(&(&1 >= count)) | |
| end) | |
| |> Enum.any?(& &1) | |
| end | |
| defp pad_ones(flowers) do | |
| flowers | |
| |> Enum.take(2) | |
| |> case do | |
| [0, 0] -> | |
| [0 | flowers] | |
| _ -> | |
| flowers | |
| end | |
| end | |
| end |
| defmodule RWC_361 do | |
| @moduledoc """ | |
| Given an integer array nums, return the length of the longest | |
| increasing subsequence. | |
| iex> RWC_361.increasing_subsequence([10, 9, 2, 3, 7, 101, 18]) | |
| 4 | |
| iex> RWC_361.increasing_subsequence([4, 4, 4, 4, 3]) | |
| 1 | |
| """ | |
| def increasing_subsequence(input) do | |
| input | |
| |> Enum.chunk_every(2, 1, :discard) | |
| |> Enum.map(fn [a, b] -> a < b end) | |
| |> Enum.chunk_by(& &1) | |
| |> Enum.flat_map(fn | |
| [true | _] = sub -> [length(sub)] | |
| _ -> [] | |
| end) | |
| |> Enum.max(&>=/2, fn -> 0 end) | |
| |> then(&(&1 + 1)) | |
| end | |
| end |
| defmodule RWC_364 do | |
| @moduledoc """ | |
| Create a function that should take one argument n, which is a | |
| positive integer. The function should return the sum of all | |
| squared positive integers between 1 and n, inclusive. | |
| iex> RWC_364.squares(5) | |
| 55 | |
| iex> RWC_364.squares(10) | |
| 385 | |
| iex> RWC_364.squares(25) | |
| 5525 | |
| iex> RWC_364.squares(100) | |
| 338350 | |
| """ | |
| def squares(num, sum \\ 0) | |
| def squares(0, sum), do: sum | |
| def squares(num, sum), do: squares(num - 1, sum + num * num) | |
| end |
| defmodule RWC_386 do | |
| @moduledoc """ | |
| Write a function that generates all possible permutations of a given string. | |
| iex> RWC_386.permute("abc") | |
| ["abc", "acb", "bac", "bca", "cab", "cba"] | |
| """ | |
| def get_permutations([]), do: [[]] | |
| def get_permutations(list), | |
| do: for(el <- list, rest <- get_permutations(list -- [el]), do: [el | rest]) | |
| def permute(input) do | |
| input | |
| |> String.graphemes() | |
| |> get_permutations() | |
| |> Enum.map(&Enum.join/1) | |
| end | |
| end |
| defmodule RWC_389 do | |
| @moduledoc """ | |
| Given two strings, s and p, return an array of all the start indices of p's anagrams in s. | |
| iex> RWC_389.find_anagrams("cbaebabacd", "abc") | |
| [0, 6] | |
| iex> RWC_389.find_anagrams("fish", "cake") | |
| [] | |
| iex> RWC_389.find_anagrams("abab", "ab") | |
| [0, 1, 2] | |
| """ | |
| def find_anagrams(s, p) do | |
| p_sorted = p |> String.graphemes() |> Enum.sort() | |
| s | |
| |> String.graphemes() | |
| |> Enum.chunk_every(String.length(p), 1, :discard) | |
| |> Enum.map(&Enum.sort/1) | |
| |> Enum.with_index() | |
| |> Enum.flat_map(fn | |
| {^p_sorted, i} -> [i] | |
| _ -> [] | |
| end) | |
| end | |
| end |
| defmodule RWC_390 do | |
| @moduledoc """ | |
| Write a function that evaluates a postfix expression (also known as | |
| Reverse Polish Notation) and returns the result. The expression will | |
| contain single-digit integers and the operators +, -, *, and /. | |
| You can assume the input is always a valid expression! | |
| iex> RWC_390.evaluate_postfix("12+") | |
| 3 | |
| iex> RWC_390.evaluate_postfix("56+7*") | |
| 77 | |
| """ | |
| @op %{ | |
| "+" => &Kernel.+/2, | |
| "-" => &Kernel.-/2, | |
| "*" => &Kernel.*/2, | |
| "/" => &div/2 | |
| } | |
| def evaluate_postfix(input) do | |
| input | |
| |> String.graphemes() | |
| |> Enum.reduce({}, fn | |
| el, {} -> | |
| {String.to_integer(el)} | |
| el, {num} when el not in ["+", "-", "/", "*"] -> | |
| {num, String.to_integer(el)} | |
| el, {first, second} -> | |
| {@op[el].(first, second)} | |
| end) | |
| |> elem(0) | |
| end | |
| end |
| defmodule RWC_394 do | |
| @moduledoc """ | |
| A store is going out of business and will reduce the price of all | |
| products by 10% every week leading up to the closing date. Given | |
| the closingDate, visitDate, and the originalPrice of a product, | |
| write a function that returns the price of the product on the visitDate. | |
| You can assume that originalPrice is a positive number. | |
| iex> RWC_394.calculate_price("2025-04-01", "2025-03-03", 100); # 4 weeks of discounts | |
| 65.61 | |
| iex> RWC_394.calculate_price("2025-04-01", "2025-03-15", 50); # 2 weeks of discounts | |
| 40.5 | |
| iex> RWC_394.calculate_price("2025-04-01", "2025-04-15", 75); # No discount (visit after closing) | |
| 75 | |
| """ | |
| def calculate_price(closing, visit, orig) do | |
| Date.diff(Date.from_iso8601!(closing), Date.from_iso8601!(visit)) | |
| |> div(7) | |
| |> then(fn | |
| weeks when weeks < 0 -> | |
| orig | |
| weeks -> | |
| 1..weeks | |
| |> Enum.reduce(orig, fn _, price -> | |
| price * 0.9 | |
| end) | |
| |> Float.round(2) | |
| end) | |
| end | |
| end |
| defmodule RWC_397 do | |
| @moduledoc """ | |
| Write a function that finds the longest streak of consecutive | |
| true values in a boolean array that meets or exceeds a given | |
| streak goal. Return 0 if no such streak exists. | |
| iex> RWC_397.find_longest_streak([true, true, false, true, true, true], 3) | |
| 3 | |
| iex> RWC_397.find_longest_streak([true, true, true, false, true], 4) | |
| 0 | |
| iex> RWC_397.find_longest_streak([true, true, true, true], 2) | |
| 4 | |
| """ | |
| def find_longest_streak(streak, len) do | |
| streak | |
| |> Enum.chunk_by(& &1) | |
| |> Enum.filter(&Enum.all?/1) | |
| |> Enum.max_by(&length/1) | |
| |> length() | |
| |> then(fn | |
| x when x < len -> 0 | |
| x -> x | |
| end) | |
| end | |
| end |
| defmodule RWC_420 do | |
| @moduledoc """ | |
| Imagine a simplified version of the game Battleship played on | |
| a 2D grid. The grid represents the sea, and each cell can either | |
| be empty (.) or contain a part of a ship (X). Ships are placed | |
| horizontally or vertically, and there are no adjacent ships. | |
| Given a grid, count the number of battleships in it. | |
| iex> ships = [ | |
| ...> ["X", "X", ".", "X"], | |
| ...> [".", ".", ".", "X"], | |
| ...> [".", ".", ".", "X"], | |
| ...> [".", ".", ".", "."], | |
| ...> ] | |
| ...> RWC_420.number_of_ships(ships) | |
| 2 | |
| """ | |
| def number_of_ships(ships) do | |
| ships | |
| |> Enum.zip_with(&Function.identity/1) #=> rotate matrix | |
| |> then(&[ships, &1]) | |
| |> Enum.map(&check/1) | |
| |> Enum.sum() | |
| end | |
| defp check(row) do | |
| ~r/[X]{2,}/ | |
| |> Regex.scan(Enum.join(row)) | |
| |> Enum.count() | |
| end | |
| end |
| defmodule RWC_421 do | |
| @moduledoc """ | |
| For an array of numbers, generate an array where for every element, | |
| all neighboring elements are added to itself, and return the sum of that array. | |
| iex> RWC_421.with_neighbours([]) | |
| 0 | |
| iex> RWC_421.with_neighbours([1]) | |
| 1 | |
| iex> RWC_421.with_neighbours([1, 4]) | |
| 10 | |
| iex> RWC_421.with_neighbours([1, 4, 7]) | |
| 28 | |
| iex> RWC_421.with_neighbours([1, 4, 7, 10]) | |
| 55 | |
| iex> RWC_421.with_neighbours([-1, -2, -3]) | |
| -14 | |
| iex> RWC_421.with_neighbours([0.1, 0.2, 0.3]) | |
| 1.4 | |
| iex> RWC_421.with_neighbours([1,-20,300,-4000,50000,-600000,7000000]) | |
| 12338842 | |
| """ | |
| def with_neighbours(nums) do | |
| [0, nums, 0] | |
| |> List.flatten() | |
| |> Enum.chunk_every(3, 1, :discard) | |
| |> Enum.map(&Enum.sum/1) | |
| |> Enum.sum() | |
| end | |
| end |
| defmodule RWC_422 do | |
| @moduledoc """ | |
| You are given an array of arrays, where each inner array represents | |
| the runs scored by each team in an inning of a baseball game: | |
| [[home1, away1], [home2, away2], ...]. Write a function that returns | |
| an object with the total runs for each team, which innings each team led, | |
| and who won the game. | |
| iex> RWC_422.analyze_baseball_game([[1, 0], [2, 2], [0, 3], [4, 1]]) | |
| %{ | |
| home_total: 7, | |
| away_total: 6, | |
| home_led_innings: [1, 2, 4], | |
| away_led_innings: [3], | |
| winner: "home" | |
| } | |
| """ | |
| def analyze_baseball_game(innings) do | |
| analyze_innings(%{}, innings) | |
| end | |
| defp analyze_innings(score, []) do | |
| winner = if score.home_total > score.away_total, do: "home", else: "away" | |
| Map.put(score, :winner, winner) | |
| end | |
| defp analyze_innings(score, [[home, away] | rest]) do | |
| cond do | |
| home >= away -> | |
| Map.update(score, :home_led_innings, [home], &(&1 ++ [home])) | |
| true -> | |
| Map.update(score, :away_led_innings, [away], &(&1 ++ [away])) | |
| end | |
| |> Map.update(:home_total, home, &(&1 + home)) | |
| |> Map.update(:away_total, away, &(&1 + away)) | |
| |> analyze_innings(rest) | |
| end | |
| end |