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 way. | |
| // The earlier one is ~88% slower: https://jsbench.me/54keiiwuvy/1 | |
| 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) | |
| 65.61 | |
| iex> RWC_394.calculate_price("2025-04-01", "2025-03-15", 50) | |
| 40.5 | |
| iex> RWC_394.calculate_price("2025-04-01", "2025-04-15", 75) | |
| 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 | |
| # => rotate matrix | |
| |> Enum.zip_with(&Function.identity/1) | |
| |> 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 |
| defmodule RWC_423 do | |
| @moduledoc """ | |
| Write a function that determines if a number is abundant, deficient, perfect, | |
| or amicable. | |
| iex> RWC_423.what_kind_of_number(6) | |
| "perfect" | |
| iex> RWC_423.what_kind_of_number(12) | |
| "abundant" | |
| iex> RWC_423.what_kind_of_number(4) | |
| "deficient" | |
| iex> RWC_423.what_kind_of_number(220) | |
| "amicable" | |
| """ | |
| def what_kind_of_number(num) do | |
| sum = divisor_sum(num) | |
| cond do | |
| sum == num -> "perfect" | |
| sum != num && divisor_sum(sum) == num -> "amicable" | |
| sum > num -> "abundant" | |
| true -> "deficient" | |
| end | |
| end | |
| defp divisor_sum(1), do: 0 | |
| defp divisor_sum(num) do | |
| 1..(num - 1) | |
| |> Enum.filter(&(rem(num, &1) == 0)) | |
| |> Enum.sum() | |
| end | |
| end |
| defmodule RWC_424 do | |
| @moduledoc """ | |
| Given the non-negative integer n, output the value of its hyperfactorial. | |
| iex> RWC_424.hyperfactorial(0) | |
| 1 | |
| iex> RWC_424.hyperfactorial(2) | |
| 4 | |
| iex> RWC_424.hyperfactorial(3) | |
| 108 | |
| iex> RWC_424.hyperfactorial(7) | |
| 3319766398771200000 | |
| """ | |
| def hyperfactorial(0), do: 1 | |
| def hyperfactorial(num) do | |
| 1..num | |
| |> Enum.map(&Integer.pow(&1, &1)) | |
| |> Enum.product() | |
| end | |
| end |
| defmodule RWC_425 do | |
| @moduledoc """ | |
| You're building a tool that tracks component edits and groups them into a | |
| changelog. Given an array of edit actions, each with a timestamp and a | |
| component name, return an array of grouped changelog entries. Edits to the | |
| same component within a 10-minute window should be merged into one changelog | |
| entry, showing the component name and the range of timestamps affected. | |
| iex> edits = [ | |
| ...> %{timestamp: "2025-10-06T08:00:00Z", component: "Header"}, | |
| ...> %{timestamp: "2025-10-06T08:05:00Z", component: "Header"}, | |
| ...> %{timestamp: "2025-10-06T08:20:00Z", component: "Header"}, | |
| ...> %{timestamp: "2025-10-06T08:07:00Z", component: "Footer"}, | |
| ...> %{timestamp: "2025-10-06T08:15:00Z", component: "Footer"} | |
| ...> ] | |
| ...> RWC_425.group_changelog_edits(edits) | |
| [ | |
| %{component: "Footer", start: "2025-10-06T08:07:00Z", end: | |
| "2025-10-06T08:15:00Z"}, %{component: "Header", start: | |
| "2025-10-06T08:00:00Z", end: "2025-10-06T08:05:00Z"}, %{component: "Header", | |
| start: "2025-10-06T08:20:00Z", end: "2025-10-06T08:20:00Z"} | |
| ] | |
| """ | |
| def group_changelog_edits(edits) do | |
| edits | |
| |> Enum.group_by(& &1.component) | |
| |> Enum.sort_by(fn {component, _} -> component end) | |
| |> Enum.flat_map(fn {component, edits} -> | |
| edits | |
| |> Enum.sort_by(& &1.timestamp) | |
| |> Enum.map(& &1.timestamp) | |
| |> Enum.reduce([], &merge_edit/2) | |
| |> Enum.reverse() | |
| |> Enum.map(fn {start, finish} -> | |
| %{component: component, start: start, end: finish} | |
| end) | |
| end) | |
| end | |
| defp merge_edit(timestamp, []), do: [{timestamp, timestamp}] | |
| defp merge_edit(timestamp, [{start, finish} | rest]) do | |
| if minutes_between(finish, timestamp) <= 10 do | |
| [{start, timestamp} | rest] | |
| else | |
| [{timestamp, timestamp}, {start, finish} | rest] | |
| end | |
| end | |
| defp minutes_between(start, finish) do | |
| {:ok, start, _} = DateTime.from_iso8601(start) | |
| {:ok, finish, _} = DateTime.from_iso8601(finish) | |
| DateTime.diff(finish, start, :minute) | |
| end | |
| end |
| defmodule RWC_426 do | |
| @moduledoc """ | |
| Given a CSV string where each row contains a name, age, and city (and values | |
| may be quoted, have embedded commas or escaped quotes), write a function that | |
| parses the CSV and outputs a formatted list of strings in the form: "Name, age | |
| Age, from City". Handle quoted fields containing commas and escaped quotes. | |
| iex> csv = [ | |
| ...> "name,age,city", | |
| ...> ~s("Ryu, Mi-yeong",30,"Seoul"), | |
| ...> ~s(Zoey,24,"Burbank") | |
| ...> ] |> Enum.join(<<10>>) | |
| ...> RWC_426.csv_to_list(csv) |> String.split(<<10>>) | |
| ["- Ryu, Mi-yeong, age 30, from Seoul", "- Zoey, age 24, from Burbank"] | |
| """ | |
| def csv_to_list(csv) do | |
| csv | |
| |> String.split("\n", trim: true) | |
| |> tl() | |
| |> Enum.map(&format_row/1) | |
| |> Enum.join("\n") | |
| end | |
| defp format_row(row) do | |
| [name, age, city] = parse_row(row) | |
| "- #{name}, age #{age}, from #{city}" | |
| end | |
| defp parse_row(row), do: parse_row(String.graphemes(row), "", [], false) | |
| defp parse_row([], field, fields, _quoted), do: Enum.reverse([field | fields]) | |
| defp parse_row(["\"", "\"" | rest], field, fields, true), | |
| do: parse_row(rest, field <> "\"", fields, true) | |
| defp parse_row(["\"" | rest], field, fields, quoted), | |
| do: parse_row(rest, field, fields, !quoted) | |
| defp parse_row(["," | rest], field, fields, false), | |
| do: parse_row(rest, "", [field | fields], false) | |
| defp parse_row([char | rest], field, fields, quoted), | |
| do: parse_row(rest, field <> char, fields, quoted) | |
| end |
| defmodule RWC_427 do | |
| @moduledoc """ | |
| Given a string str and an array of positive integers widths, write a function | |
| that splits the string into lines, each with the exact number of characters as | |
| specified by the corresponding width. Return an array of the substrings. Use | |
| the last width for any remaining characters if the array is shorter than | |
| needed. | |
| iex> RWC_427.split_by_widths("Supercalifragilisticexpialidocious", [5, 9, 4]) | |
| ["Super", "califragi", "list", "icex", "pial", "idoc", "ious"] | |
| """ | |
| def split_by_widths(str, widths) do | |
| split_by_widths(str, widths, List.last(widths), []) | |
| end | |
| defp split_by_widths("", _widths, _last, result), do: Enum.reverse(result) | |
| defp split_by_widths(str, [], last, result), | |
| do: split_by_widths(str, [last], last, result) | |
| defp split_by_widths(str, [width | rest], last, result) do | |
| <<chunk::binary-size(^width), rest_of_string::binary>> = | |
| String.pad_trailing(str, width) | |
| split_by_widths(String.trim_trailing(rest_of_string), rest, last, [ | |
| String.trim_trailing(chunk) | result | |
| ]) | |
| end | |
| end |
| defmodule RWC_428 do | |
| @moduledoc """ | |
| Given a field represented as an array of 0s and 1s, where 1 means that | |
| position needs protection, you can place a scarecrow at any index, and each | |
| scarecrow protects up to k consecutive positions centered around itself. | |
| Return the minimum set of indices where scarecrows should be placed so that | |
| all the positions with 1 are protected. | |
| iex> RWC_428.place_scarecrows([1, 1, 0, 1, 1, 0, 1], 3) | |
| [1, 4, 6] | |
| iex> RWC_428.place_scarecrows([1, 0, 1, 1, 0, 1], 3) | |
| [1, 4] | |
| iex> RWC_428.place_scarecrows([1, 1, 1, 1, 1], 1) | |
| [0, 1, 2, 3, 4] | |
| """ | |
| def place_scarecrows(field, width) do | |
| protect(field, width, 0, [], -1) | |
| end | |
| defp protect(field, _width, index, scarecrows, _protected_until) | |
| when index >= length(field) do | |
| Enum.reverse(scarecrows) | |
| end | |
| defp protect(field, width, index, scarecrows, protected_until) do | |
| if Enum.at(field, index) == 1 && index > protected_until do | |
| radius = div(width, 2) | |
| scarecrow = min(index + radius, length(field) - 1) | |
| protect( | |
| field, | |
| width, | |
| scarecrow + radius + 1, | |
| [scarecrow | scarecrows], | |
| scarecrow + radius | |
| ) | |
| else | |
| protect(field, width, index + 1, scarecrows, protected_until) | |
| end | |
| end | |
| end |
| defmodule RWC_429 do | |
| @moduledoc """ | |
| Given the current position of a knight as [row, col] in an 8x8 chess board | |
| represented as a 2D array, write a function to return all valid moves the | |
| knight can make. | |
| iex> RWC_429.knight_moves([4, 4]) | |
| [[2, 3], [2, 5], [3, 2], [3, 6], [5, 2], [5, 6], [6, 3], [6, 5]] | |
| iex> RWC_429.knight_moves([0, 0]) | |
| [[1, 2], [2, 1]] | |
| iex> RWC_429.knight_moves([1, 2]) | |
| [[0, 0], [0, 4], [2, 0], [2, 4], [3, 1], [3, 3]] | |
| """ | |
| def knight_moves([row, col]) do | |
| [[-2, -1], [-2, 1], [-1, -2], [-1, 2], [1, -2], [1, 2], [2, -1], [2, 1]] | |
| |> Enum.map(fn [row_offset, col_offset] -> | |
| [row + row_offset, col + col_offset] | |
| end) | |
| |> Enum.filter(fn [row, col] -> row in 0..7 && col in 0..7 end) | |
| end | |
| end |
| defmodule RWC_430 do | |
| @moduledoc """ | |
| You are given two sorted arrays, a and b, where a has a large enough size | |
| buffer at the end to hold b (which can be spaces, zeroes, or nulls). Write a | |
| function to merge b into a in sorted order. | |
| iex> RWC_430.merge([1, 3, 5, 0, 0, 0], [2, 4, 6]) | |
| [1, 2, 3, 4, 5, 6] | |
| """ | |
| def merge(a, b) do | |
| a | |
| |> Enum.take(length(a) - length(b)) | |
| |> Kernel.++(b) | |
| |> Enum.sort() | |
| end | |
| end |
| defmodule RWC_431 do | |
| @moduledoc """ | |
| Given a positive integer n, write a function that returns an array containing | |
| all integers from 1 to n, where each integer i appears exactly i times in the | |
| result. For example, 3 should appear 3 times, 5 should appear 5 times, and so | |
| on. The order of the integers in the output array does not matter. | |
| iex> RWC_431.repeated_integers(4) | |
| [1, 2, 2, 3, 3, 3, 4, 4, 4, 4] | |
| """ | |
| def repeated_integers(count), | |
| do: Enum.flat_map(1..count, &List.duplicate(&1, &1)) | |
| end |
| defmodule RWC_432 do | |
| @moduledoc """ | |
| Given an array of meal prep tasks for Thanksgiving, where each task is | |
| represented as [taskName, startTime, endTime], return the maximum number of | |
| non-overlapping tasks you can complete, along with the names of the chosen | |
| tasks in the order they were selected. | |
| iex> tasks = [ | |
| ...> ["Make Gravy", 10, 11], | |
| ...> ["Mash Potatoes", 11, 12], | |
| ...> ["Bake Rolls", 11, 13], | |
| ...> ["Prep Salad", 12, 13] | |
| ...> ] | |
| ...> RWC_432.max_meal_prep_tasks(tasks) | |
| %{count: 3, chosen: ["Make Gravy", "Mash Potatoes", "Prep Salad"]} | |
| """ | |
| def max_meal_prep_tasks(tasks) do | |
| chosen = | |
| tasks | |
| |> Enum.sort_by(fn [_task, _start, finish] -> finish end) | |
| |> Enum.reduce([], &choose_task/2) | |
| |> Enum.reverse() | |
| |> Enum.map(fn [task, _start, _finish] -> task end) | |
| %{count: length(chosen), chosen: chosen} | |
| end | |
| defp choose_task([_task, _start, _finish] = task, []), do: [task] | |
| defp choose_task( | |
| [_task, start, _finish] = task, | |
| [[_prev_task, _prev_start, previous_finish] | _rest] = chosen | |
| ) do | |
| if start >= previous_finish, do: [task | chosen], else: chosen | |
| end | |
| end |
| defmodule RWC_433 do | |
| @moduledoc """ | |
| There are 16 basic HTML Colors. Write a program to output them in ascending | |
| order by HEX value. Don't use any built-in sorting methods. | |
| iex> RWC_433.html_colors_by_hex() | |
| [ | |
| "000000", | |
| "000080", | |
| "0000FF", | |
| "008000", | |
| "008080", | |
| "00FF00", "00FFFF", | |
| "800000", | |
| "800080", | |
| "808000", | |
| "808080", | |
| "C0C0C0", "FF0000", "FF00FF", "FFFF00", "FFFFFF" | |
| ] | |
| """ | |
| def html_colors_by_hex do | |
| [ | |
| "000000", | |
| "000080", | |
| "0000FF", | |
| "008000", | |
| "008080", | |
| "00FF00", | |
| "00FFFF", | |
| "800000", | |
| "800080", | |
| "808000", | |
| "808080", | |
| "C0C0C0", | |
| "FF0000", | |
| "FF00FF", | |
| "FFFF00", | |
| "FFFFFF" | |
| ] | |
| end | |
| end |
| defmodule RWC_434 do | |
| @moduledoc """ | |
| Make a data structure for a deck of cards, and implement a shuffle() method, | |
| and a draw(n) method. Calling draw() when the deck is empty returns an empty | |
| array. | |
| iex> deck = RWC_434.new() | |
| ...> {cards, deck} = RWC_434.draw(deck, 5) | |
| ...> {length(cards), length(deck)} | |
| {5, 47} | |
| iex> RWC_434.draw([], 5) | |
| [] | |
| """ | |
| def new do | |
| for suit <- ["♣", "♦", "♥", "♠"], | |
| rank <- [ | |
| "A", | |
| "2", | |
| "3", | |
| "4", | |
| "5", | |
| "6", | |
| "7", | |
| "8", | |
| "9", | |
| "10", | |
| "J", | |
| "Q", | |
| "K" | |
| ] do | |
| rank <> suit | |
| end | |
| end | |
| def shuffle(deck), do: Enum.shuffle(deck) | |
| def draw([], _num), do: [] | |
| def draw(deck, num) do | |
| Enum.split(deck, num) | |
| end | |
| end |
| defmodule RWC_435 do | |
| @moduledoc """ | |
| Write a function to generate a Latin Square given a positive integer n. The | |
| values can be any n distinct values, and don't have to be consistent for | |
| different n. | |
| iex> RWC_435.latin_square(1) | |
| [[1]] | |
| iex> RWC_435.latin_square(2) | |
| [[1, 2], [2, 1]] | |
| iex> RWC_435.latin_square(4) | |
| [ | |
| [1, 2, 3, 4], | |
| [2, 3, 4, 1], | |
| [3, 4, 1, 2], | |
| [4, 1, 2, 3] | |
| ] | |
| """ | |
| def latin_square(num) do | |
| 0..(num - 1) | |
| |> Enum.map(fn row -> | |
| 0..(num - 1) | |
| |> Enum.map(&(rem(row + &1, num) + 1)) | |
| end) | |
| end | |
| end |
| defmodule RWC_436 do | |
| @moduledoc """ | |
| An alternating array is a list of any length in which two values are | |
| alternating (all even-indexed items are equal, and all odd-indexed items are | |
| equal). Given an array, return true if it is alternating. | |
| iex> RWC_436.alternating?([]) | |
| true | |
| iex> RWC_436.alternating?([1]) | |
| true | |
| iex> RWC_436.alternating?([1, 1]) | |
| true | |
| iex> RWC_436.alternating?([1, 2, 1]) | |
| true | |
| iex> RWC_436.alternating?([10, 5, 10, 5, 10]) | |
| true | |
| iex> RWC_436.alternating?([2, 2, 3, 3]) | |
| false | |
| iex> RWC_436.alternating?([5, 4, 3, 5, 4, 3]) | |
| false | |
| """ | |
| def alternating?(list) do | |
| list | |
| |> Enum.with_index() | |
| |> Enum.group_by(fn {_num, index} -> rem(index, 2) end, fn {num, _index} -> | |
| num | |
| end) | |
| |> Map.values() | |
| |> Enum.all?(fn nums -> Enum.uniq(nums) |> length() == 1 end) | |
| end | |
| end |
| defmodule RWC_437 do | |
| @moduledoc """ | |
| Given a string that contains only digits from 0 to 9 and a number n, replace | |
| each consecutive run of n with its length. | |
| iex> RWC_437.replace_repeats("1234500362000440", 0) | |
| "1234523623441" | |
| iex> RWC_437.replace_repeats("000000000000", 0) | |
| "12" | |
| iex> RWC_437.replace_repeats("123456789", 1) | |
| "123456789" | |
| """ | |
| def replace_repeats(str, num) do | |
| digit = Integer.to_string(num) | |
| ~r/#{digit}+/ | |
| |> Regex.replace(str, fn match -> | |
| Integer.to_string(String.length(match)) | |
| end) | |
| end | |
| end |
| defmodule RWC_438 do | |
| @moduledoc """ | |
| Given an integer array nums, sum each element in the array in order. You are | |
| allowed to use at most one reset during the run: when you reset, your current | |
| score becomes 0 and you continue with the next elements. Return the maximum | |
| score you can end with. | |
| iex> RWC_438.max_score_with_one_reset([2, -1, 2, -5, 2, 2]) | |
| 4 | |
| iex> RWC_438.max_score_with_one_reset([4, -10, 3, 2, -1, 6]) | |
| 10 | |
| iex> RWC_438.max_score_with_one_reset([-50, -2, -3]) | |
| 0 | |
| """ | |
| def max_score_with_one_reset(nums) do | |
| nums | |
| |> Enum.reverse() | |
| |> Enum.scan(0, &(&1 + &2)) | |
| |> then(&[0 | &1]) | |
| |> Enum.max() | |
| end | |
| end |
| defmodule RWC_439 do | |
| @moduledoc """ | |
| Given an array of objects representing bears in a forest, each with a name and | |
| hunger level, return the names of all bears whose hunger level is above the | |
| forest average, sorted alphabetically. | |
| iex> bears = [ | |
| ...> %{name: "Baloo", hunger: 6}, | |
| ...> %{name: "Yogi", hunger: 9}, | |
| ...> %{name: "Paddington", hunger: 4}, | |
| ...> %{name: "Winnie", hunger: 10}, | |
| ...> %{name: "Chicago", hunger: 20} | |
| ...> ] | |
| ...> RWC_439.hungry_bears(bears) | |
| ["Chicago", "Winnie"] | |
| """ | |
| def hungry_bears(bears) do | |
| average = | |
| bears | |
| |> Enum.map(& &1.hunger) | |
| |> then(&(Enum.sum(&1) / length(&1))) | |
| bears | |
| |> Enum.filter(&(&1.hunger > average)) | |
| |> Enum.map(& &1.name) | |
| |> Enum.sort() | |
| end | |
| end |
| defmodule RWC_440 do | |
| @moduledoc """ | |
| Given a string `str`, find a contiguous substring of length `10` whose | |
| characters can be bijectively mapped to the moves `{U,D,L,R,B,A}` so that the | |
| substring decodes to the Konami code `"UUDDLRLRBA"`. | |
| iex> RWC_440.konami_mapping("xx2233454590yy11110") | |
| %{"0" => "A", "2" => "U", "3" => "D", "4" => "L", "5" => "R", "9" => "B"} | |
| iex> RWC_440.konami_mapping("sduwahoda22ii0d0dbn") | |
| %{"0" => "L", "2" => "U", "i" => "D", "d" => "R", "b" => "B", "n" => "A"} | |
| """ | |
| @code String.graphemes("UUDDLRLRBA") | |
| def konami_mapping(str) do | |
| str | |
| |> String.graphemes() | |
| |> Enum.chunk_every(length(@code), 1, :discard) | |
| |> Enum.find_value(&mapping_for/1) | |
| end | |
| defp mapping_for(chars) do | |
| Enum.zip(chars, @code) | |
| |> Enum.reduce_while({%{}, %{}}, fn {char, move}, {mapping, reverse} -> | |
| cond do | |
| Map.get(mapping, char, move) != move -> | |
| {:halt, nil} | |
| Map.get(reverse, move, char) != char -> | |
| {:halt, nil} | |
| true -> | |
| {:cont, {Map.put(mapping, char, move), Map.put(reverse, move, char)}} | |
| end | |
| end) | |
| |> case do | |
| {mapping, _reverse} -> mapping | |
| nil -> nil | |
| end | |
| end | |
| end |
| defmodule RWC_441 do | |
| @moduledoc """ | |
| You are given a string consisting of lowercase words, each separated by a | |
| single space. Determine how many vowels appear in the first word. Then, | |
| reverse each following word that has the same vowel count. | |
| iex> RWC_441.flippedy("cat and mice") | |
| "cat dna mice" | |
| iex> RWC_441.flippedy("banana healthy") | |
| "banana healthy" | |
| """ | |
| def flippedy(str) do | |
| [first | rest] = String.split(str) | |
| count = vowel_count(first) | |
| rest | |
| |> Enum.map(fn word -> | |
| if vowel_count(word) == count, do: String.reverse(word), else: word | |
| end) | |
| |> then(&Enum.join([first | &1], " ")) | |
| end | |
| defp vowel_count(word), | |
| do: word |> String.graphemes() |> Enum.count(&(&1 in ~w(a e i o u))) | |
| end |
| defmodule RWC_442 do | |
| @moduledoc """ | |
| February 2026 is a perfect month! Write a function that returns the closest | |
| previous and next perfect month around the given Gregorian year. | |
| iex> RWC_442.nearest_perfect_months(2025) | |
| %{prev: "2021-02", next: "2026-02"} | |
| iex> RWC_442.nearest_perfect_months(2026) | |
| %{prev: "2026-02", next: "2027-02"} | |
| """ | |
| def nearest_perfect_months(year) do | |
| %{prev: perfect_month_before(year), next: perfect_month_after(year + 1)} | |
| end | |
| defp perfect_month_before(year) do | |
| year | |
| |> Stream.iterate(&(&1 - 1)) | |
| |> Enum.find(&perfect_february?/1) | |
| |> then(&"#{&1}-02") | |
| end | |
| defp perfect_month_after(year) do | |
| year | |
| |> Stream.iterate(&(&1 + 1)) | |
| |> Enum.find(&perfect_february?/1) | |
| |> then(&"#{&1}-02") | |
| end | |
| defp perfect_february?(year) do | |
| not Calendar.ISO.leap_year?(year) and | |
| Date.day_of_week(Date.new!(year, 2, 1)) in [1, 7] | |
| end | |
| end |
| defmodule RWC_443 do | |
| @moduledoc """ | |
| Given an integer array and a number `n`, move all of the `n`s to the end of | |
| the array while maintaining the relative order of the non-`n`s. | |
| iex> RWC_443.move_nums([0, 2, 0, 3, 10], 0) | |
| [2, 3, 10, 0, 0] | |
| """ | |
| def move_nums(nums, num) do | |
| Enum.reject(nums, &(&1 == num)) ++ Enum.filter(nums, &(&1 == num)) | |
| end | |
| end |
| defmodule RWC_444 do | |
| @moduledoc """ | |
| You have a 2D grid of numbers. Write a function that zooms in by an integer | |
| factor `k >= 2` by turning each cell into a `k x k` block with the same value, | |
| returning the bigger grid. | |
| iex> RWC_444.zoom([[1, 2], [3, 4]], 2) | |
| [[1, 1, 2, 2], [1, 1, 2, 2], [3, 3, 4, 4], [3, 3, 4, 4]] | |
| iex> RWC_444.zoom([[7, 8, 9]], 3) | |
| [ | |
| [7, 7, 7, 8, 8, 8, 9, 9, 9], | |
| [7, 7, 7, 8, 8, 8, 9, 9, 9], | |
| [7, 7, 7, 8, 8, 8, 9, 9, 9] | |
| ] | |
| iex> RWC_444.zoom([[1], [2]], 3) | |
| [ | |
| [1, 1, 1], | |
| [1, 1, 1], | |
| [1, 1, 1], | |
| [2, 2, 2], | |
| [2, 2, 2], | |
| [2, 2, 2] | |
| ] | |
| """ | |
| def zoom(grid, count) do | |
| grid | |
| |> Enum.flat_map(fn row -> | |
| row = Enum.flat_map(row, &List.duplicate(&1, count)) | |
| List.duplicate(row, count) | |
| end) | |
| end | |
| end |
| defmodule RWC_445 do | |
| @moduledoc """ | |
| Given an array of integers, find the contiguous subarray that has the largest | |
| sum and return that sum. | |
| iex> RWC_445.max_subarray_sum([-2, 1, -3, 4, -1, 2, 1, -5, 4]) | |
| 6 | |
| iex> RWC_445.max_subarray_sum([5]) | |
| 5 | |
| iex> RWC_445.max_subarray_sum([-1, -2, -3, -4]) | |
| -1 | |
| iex> RWC_445.max_subarray_sum([5, 4, -1, 7, 8]) | |
| 23 | |
| """ | |
| def max_subarray_sum([first | rest]) do | |
| rest | |
| |> Enum.reduce({first, first}, fn num, {best, current} -> | |
| current = max(num, current + num) | |
| {max(best, current), current} | |
| end) | |
| |> elem(0) | |
| end | |
| end |
| defmodule RWC_446 do | |
| @moduledoc """ | |
| Find the majority element in an array (one that appears more than n/2 times) | |
| in `O(n)` time and `O(1)` space without hashmaps. | |
| iex> RWC_446.majority_element([2, 2, 1, 1, 2, 2, 1, 2, 2]) | |
| 2 | |
| iex> RWC_446.majority_element([3, 3, 4, 2, 3, 3, 1]) | |
| 3 | |
| """ | |
| def majority_element(nums) do | |
| nums | |
| |> Enum.reduce({nil, 0}, fn | |
| num, {_, 0} -> {num, 1} | |
| num, {num, count} -> {num, count + 1} | |
| _num, {candidate, count} -> {candidate, count - 1} | |
| end) | |
| |> elem(0) | |
| end | |
| end |
| defmodule RWC_447 do | |
| @moduledoc """ | |
| Given a string `s` consisting only of `a` and `b`, return the minimum number | |
| of adjacent swaps needed to transform it into an alternating string, or `-1` | |
| if impossible. | |
| iex> RWC_447.min_swaps_to_alternate("aabb") | |
| 1 | |
| iex> RWC_447.min_swaps_to_alternate("aaab") | |
| -1 | |
| iex> RWC_447.min_swaps_to_alternate("aaaabbbb") | |
| 6 | |
| """ | |
| def min_swaps_to_alternate(str) do | |
| chars = String.graphemes(str) | |
| a_count = Enum.count(chars, &(&1 == "a")) | |
| b_count = length(chars) - a_count | |
| cond do | |
| abs(a_count - b_count) > 1 -> | |
| -1 | |
| a_count > b_count -> | |
| swaps_to(chars, "a") | |
| b_count > a_count -> | |
| swaps_to(chars, "b") | |
| true -> | |
| min(swaps_to(chars, "a"), swaps_to(chars, "b")) | |
| end | |
| end | |
| defp swaps_to(chars, first) do | |
| chars | |
| |> Enum.with_index() | |
| |> Enum.filter(fn {char, _index} -> char == first end) | |
| |> Enum.map(&elem(&1, 1)) | |
| |> Enum.zip(Stream.iterate(0, &(&1 + 2))) | |
| |> Enum.map(fn {actual, expected} -> abs(actual - expected) end) | |
| |> Enum.sum() | |
| end | |
| end |
| defmodule RWC_448 do | |
| @moduledoc """ | |
| You're given a 2D grid representing a city where each cell is either empty | |
| (`0`), a fire station (`1`), or a building (`2`). Return a 2D grid where each | |
| cell shows the minimum distance to the nearest fire station. | |
| iex> RWC_448.fire_station_coverage([[2, 0, 1], [0, 2, 0], [1, 0, 2]]) | |
| [[2, 1, 0], [1, 2, 1], [0, 1, 2]] | |
| iex> RWC_448.fire_station_coverage([ | |
| ...> [1, 0, 0, 1], | |
| ...> [0, 0, 0, 0], | |
| ...> [0, 0, 0, 0], | |
| ...> [1, 0, 0, 1] | |
| ...> ]) | |
| [ | |
| [0, 1, 1, 0], | |
| [1, 2, 2, 1], | |
| [1, 2, 2, 1], | |
| [0, 1, 1, 0] | |
| ] | |
| """ | |
| def fire_station_coverage(grid) do | |
| rows = length(grid) | |
| cols = grid |> hd() |> length() | |
| stations = | |
| for {row, r} <- Enum.with_index(grid), | |
| {1, c} <- Enum.with_index(row), | |
| do: {r, c} | |
| distances = | |
| bfs(:queue.from_list(stations), Map.new(stations, &{&1, 0}), rows, cols) | |
| for r <- 0..(rows - 1), do: for(c <- 0..(cols - 1), do: distances[{r, c}]) | |
| end | |
| defp bfs(queue, distances, rows, cols) do | |
| case :queue.out(queue) do | |
| {{:value, point}, queue} -> | |
| point | |
| |> neighbors(rows, cols) | |
| |> Enum.reject(&Map.has_key?(distances, &1)) | |
| |> Enum.reduce({queue, distances}, fn next, {queue, distances} -> | |
| {:queue.in(next, queue), | |
| Map.put(distances, next, distances[point] + 1)} | |
| end) | |
| |> then(fn {queue, distances} -> bfs(queue, distances, rows, cols) end) | |
| {:empty, _queue} -> | |
| distances | |
| end | |
| end | |
| defp neighbors({r, c}, rows, cols) do | |
| [{r - 1, c}, {r + 1, c}, {r, c - 1}, {r, c + 1}] | |
| |> Enum.filter(fn {r, c} -> r in 0..(rows - 1) and c in 0..(cols - 1) end) | |
| end | |
| end |
| defmodule RWC_449 do | |
| @moduledoc """ | |
| Given a text string and a pattern, implement a fuzzy string search that finds | |
| all positions in the text where the pattern matches with at most `k` errors. | |
| iex> RWC_449.fuzzy_search("the cat sat on the mat", "cat", 0) | |
| [%{position: 4, errors: 0}] | |
| iex> RWC_449.fuzzy_search("cassidoo", "cool", 1) | |
| [] | |
| """ | |
| def fuzzy_search(text, pattern, max_errors) do | |
| text = String.graphemes(text) | |
| pattern = String.graphemes(pattern) | |
| text_length = length(text) | |
| pattern_length = length(pattern) | |
| 0..(text_length - 1)//1 | |
| |> Enum.flat_map(fn index -> | |
| max(1, pattern_length - max_errors)..min( | |
| text_length - index, | |
| pattern_length + max_errors | |
| )//1 | |
| |> Enum.map(fn length -> {index, Enum.slice(text, index, length)} end) | |
| end) | |
| |> Enum.map(fn {index, piece} -> {index, edit_distance(piece, pattern)} end) | |
| |> Enum.filter(fn {_index, errors} -> errors <= max_errors end) | |
| |> Enum.group_by(&elem(&1, 0), &elem(&1, 1)) | |
| |> Enum.map(fn {index, errors} -> | |
| %{position: index, errors: Enum.min(errors)} | |
| end) | |
| |> Enum.sort_by(& &1.position) | |
| end | |
| defp edit_distance(left, right) do | |
| initial = Enum.to_list(0..length(right)) | |
| left | |
| |> Enum.with_index(1) | |
| |> Enum.reduce(initial, fn {char, row}, previous -> | |
| right | |
| |> Enum.with_index(1) | |
| |> Enum.reduce([row], fn {other, column}, current -> | |
| insert = hd(current) + 1 | |
| delete = Enum.at(previous, column) + 1 | |
| replace = | |
| Enum.at(previous, column - 1) + if(char == other, do: 0, else: 1) | |
| [min(insert, min(delete, replace)) | current] | |
| end) | |
| |> Enum.reverse() | |
| end) | |
| |> List.last() | |
| end | |
| end |
| defmodule RWC_450 do | |
| @moduledoc """ | |
| You are given a file system represented as a map where keys are absolute paths | |
| and values are either `nil` (real file/directory) or a string (a symlink | |
| pointing to another path). Resolve a given path to its real destination, | |
| following symlinks along the way. | |
| iex> fs = %{ | |
| ...> "/a" => "/b", | |
| ...> "/b" => "/c", | |
| ...> "/c" => nil, | |
| ...> "/loop1" => "/loop2", | |
| ...> "/loop2" => "/loop1", | |
| ...> "/real" => nil, | |
| ...> "/alias" => "/real" | |
| ...> } | |
| ...> RWC_450.resolve_path(fs, "/a") | |
| "/c" | |
| iex> fs = %{ | |
| ...> "/a" => "/b", | |
| ...> "/b" => "/c", | |
| ...> "/c" => nil, | |
| ...> "/loop1" => "/loop2", | |
| ...> "/loop2" => "/loop1", | |
| ...> "/real" => nil, | |
| ...> "/alias" => "/real" | |
| ...> } | |
| ...> RWC_450.resolve_path(fs, "/alias") | |
| "/real" | |
| iex> fs = %{ | |
| ...> "/a" => "/b", | |
| ...> "/b" => "/c", | |
| ...> "/c" => nil, | |
| ...> "/loop1" => "/loop2", | |
| ...> "/loop2" => "/loop1", | |
| ...> "/real" => nil, | |
| ...> "/alias" => "/real" | |
| ...> } | |
| ...> RWC_450.resolve_path(fs, "/loop1") | |
| nil | |
| iex> fs = %{ | |
| ...> "/a" => "/b", | |
| ...> "/b" => "/c", | |
| ...> "/c" => nil, | |
| ...> "/loop1" => "/loop2", | |
| ...> "/loop2" => "/loop1", | |
| ...> "/real" => nil, | |
| ...> "/alias" => "/real" | |
| ...> } | |
| ...> RWC_450.resolve_path(fs, "/real") | |
| "/real" | |
| """ | |
| def resolve_path(fs, path), do: resolve_path(fs, path, MapSet.new()) | |
| defp resolve_path(fs, path, seen) do | |
| cond do | |
| MapSet.member?(seen, path) -> nil | |
| Map.get(fs, path) == nil and Map.has_key?(fs, path) -> path | |
| is_binary(fs[path]) -> resolve_path(fs, fs[path], MapSet.put(seen, path)) | |
| true -> nil | |
| end | |
| end | |
| end |
| defmodule RWC_451 do | |
| @moduledoc """ | |
| Given an integer `n`, return all unique combinations of Perrin numbers (up to | |
| and including the `n`th Perrin number) that sum to a target value `k`, where | |
| each Perrin number can be used at most once. | |
| iex> RWC_451.perrin_combinations(7, 12) | |
| [[0, 2, 3, 7], [0, 5, 7], [2, 3, 7], [5, 7]] | |
| iex> RWC_451.perrin_combinations(6, 5) | |
| [[0, 2, 3], [0, 5], [2, 3], [5]] | |
| """ | |
| def perrin_combinations(n, target) do | |
| 0..n | |
| |> Enum.map(&perrin/1) | |
| |> Enum.uniq() | |
| |> Enum.sort() | |
| |> combinations(target) | |
| end | |
| defp combinations(nums, target), do: combinations(nums, target, []) | |
| defp combinations(_nums, 0, combo), do: [Enum.reverse(combo)] | |
| defp combinations([], _target, _combo), do: [] | |
| defp combinations([num | rest], target, combo) when num <= target do | |
| combinations(rest, target - num, [num | combo]) ++ | |
| combinations(rest, target, combo) | |
| end | |
| defp combinations([_num | rest], target, combo), | |
| do: combinations(rest, target, combo) | |
| defp perrin(0), do: 3 | |
| defp perrin(1), do: 0 | |
| defp perrin(2), do: 2 | |
| defp perrin(n), do: perrin(n - 2) + perrin(n - 3) | |
| end |
| defmodule RWC_452 do | |
| @moduledoc """ | |
| You're building a pizza ordering system that enforces strict ingredient | |
| layering rules. Given pizza layers (bottom to top) and rules where ingredient | |
| A must appear below ingredient B, return the first violated pair or `true`. | |
| iex> layers = ["dough", "sauce", "cheese", "pepperoni", "basil"] | |
| ...> rules = [ | |
| ...> ["sauce", "cheese"], | |
| ...> ["cheese", "pepperoni"], | |
| ...> ["dough", "basil"] | |
| ...> ] | |
| ...> RWC_452.validate_pizza(layers, rules) | |
| true | |
| iex> layers = ["dough", "sauce", "cheese", "pepperoni", "basil"] | |
| ...> rules = [["cheese", "pepperoni"], ["cheese", "sauce"]] | |
| ...> RWC_452.validate_pizza(layers, rules) | |
| ["cheese", "sauce"] | |
| """ | |
| def validate_pizza(layers, rules) do | |
| positions = layers |> Enum.with_index() |> Map.new() | |
| Enum.find_value(rules, true, fn [below, above] -> | |
| if positions[below] < positions[above], do: false, else: [below, above] | |
| end) | |
| end | |
| end |
| defmodule RWC_453 do | |
| @moduledoc """ | |
| Given a string containing letters and `?` wildcards, and a target pattern | |
| string, rearrange the entire string however you like. Return the maximum | |
| number of non-overlapping copies of `pattern` that can appear in the | |
| rearranged result. | |
| iex> RWC_453.max_pattern_copies("abcabc???", "ac") | |
| 3 | |
| iex> RWC_453.max_pattern_copies("aab??", "aab") | |
| 1 | |
| iex> RWC_453.max_pattern_copies("??????", "abc") | |
| 2 | |
| """ | |
| def max_pattern_copies(str, pattern) do | |
| chars = frequencies(str) | |
| pattern = pattern |> String.graphemes() |> Enum.frequencies() | |
| 0..String.length(str) | |
| |> Enum.take_while(&possible?(&1, chars, pattern)) | |
| |> List.last() | |
| end | |
| defp possible?(count, chars, pattern) do | |
| missing = | |
| pattern | |
| |> Enum.map(fn {char, needed} -> | |
| max(0, needed * count - Map.get(chars, char, 0)) | |
| end) | |
| |> Enum.sum() | |
| missing <= Map.get(chars, "?", 0) | |
| end | |
| defp frequencies(str), do: str |> String.graphemes() |> Enum.frequencies() | |
| end |
| defmodule RWC_454 do | |
| @moduledoc """ | |
| You are given a 2D grid where `1` represents an intact tile and `0` represents | |
| a broken tile. Find the minimum number of tiles you need to repair to ensure | |
| no broken region has an area larger than `k`. | |
| iex> grid = [[1, 0, 0, 1], [1, 0, 0, 1], [1, 1, 0, 1], [0, 1, 1, 1]] | |
| ...> RWC_454.min_repairs(grid, 2) | |
| 2 | |
| iex> grid = [[1, 0, 0, 1], [1, 0, 0, 1], [1, 1, 0, 1], [0, 0, 1, 1]] | |
| ...> RWC_454.min_repairs(grid, 1) | |
| 3 | |
| """ | |
| def min_repairs(grid, max_size) do | |
| grid | |
| |> regions() | |
| |> Enum.map(&repairs_for(&1, max_size)) | |
| |> Enum.sum() | |
| end | |
| defp repairs_for(region, max_size) when length(region) <= max_size, do: 0 | |
| defp repairs_for(region, max_size) do | |
| 1..length(region) | |
| |> Enum.find(fn count -> | |
| region | |
| |> combinations(count) | |
| |> Enum.any?(&valid_repair?(region, &1, max_size)) | |
| end) | |
| end | |
| defp valid_repair?(region, repaired, max_size) do | |
| remaining = MapSet.difference(MapSet.new(region), MapSet.new(repaired)) | |
| remaining | |
| |> connected_sizes() | |
| |> Enum.all?(&(&1 <= max_size)) | |
| end | |
| defp regions(grid) do | |
| zeros = | |
| for {row, r} <- Enum.with_index(grid), | |
| {0, c} <- Enum.with_index(row), | |
| into: MapSet.new() do | |
| {r, c} | |
| end | |
| find_regions(zeros, []) | |
| end | |
| defp find_regions(zeros, regions) do | |
| case Enum.at(zeros, 0) do | |
| nil -> | |
| regions | |
| point -> | |
| region = connected(zeros, [point], MapSet.new()) | |
| find_regions(MapSet.difference(zeros, region), [ | |
| MapSet.to_list(region) | regions | |
| ]) | |
| end | |
| end | |
| defp connected_sizes(points), | |
| do: points |> find_regions([]) |> Enum.map(&length/1) | |
| defp connected(_points, [], seen), do: seen | |
| defp connected(points, [point | queue], seen) do | |
| point | |
| |> neighbors() | |
| |> Enum.filter( | |
| &(MapSet.member?(points, &1) and not MapSet.member?(seen, &1)) | |
| ) | |
| |> then(&connected(points, queue ++ &1, MapSet.put(seen, point))) | |
| end | |
| defp neighbors({r, c}), do: [{r - 1, c}, {r + 1, c}, {r, c - 1}, {r, c + 1}] | |
| defp combinations(_items, 0), do: [[]] | |
| defp combinations([], _count), do: [] | |
| defp combinations([item | rest], count) do | |
| Enum.map(combinations(rest, count - 1), &[item | &1]) ++ | |
| combinations(rest, count) | |
| end | |
| end |
| defmodule RWC_455 do | |
| @moduledoc """ | |
| Given an array of positive integers, find the length of the longest | |
| subsequence where every adjacent pair of elements in the subsequence is | |
| coprime. | |
| iex> RWC_455.longest_coprime_subsequence([6, 12, 4, 8]) | |
| 1 | |
| iex> RWC_455.longest_coprime_subsequence([4, 3, 6, 9, 7, 2]) | |
| 4 | |
| """ | |
| def longest_coprime_subsequence(nums) do | |
| nums | |
| |> Enum.with_index() | |
| |> Enum.reduce([], fn {num, index}, lengths -> | |
| best = | |
| nums | |
| |> Enum.take(index) | |
| |> Enum.with_index() | |
| |> Enum.filter(fn {prev, _prev_index} -> | |
| Integer.gcd(prev, num) == 1 | |
| end) | |
| |> Enum.map(fn {_prev, prev_index} -> | |
| Enum.at(lengths, prev_index) + 1 | |
| end) | |
| |> Enum.max(fn -> 1 end) | |
| lengths ++ [best] | |
| end) | |
| |> Enum.max() | |
| end | |
| end |
| defmodule RWC_456 do | |
| @moduledoc """ | |
| You are given a 2D grid size, a starting position for a bouncing object, a | |
| target position, and an initial direction. On each step, the object moves one | |
| cell diagonally, and if its next move would leave the grid, it bounces by | |
| reversing the corresponding direction. | |
| iex> RWC_456.count_bounces_to_target([8, 8], [0, 0], [3, 4], [1, 4]) | |
| 2 | |
| iex> RWC_456.count_bounces_to_target([3, 3], [0, 1], [2, 1], [1, 1]) | |
| 1 | |
| iex> RWC_456.count_bounces_to_target([4, 5], [0, 0], [3, 3], [1, 1]) | |
| 0 | |
| """ | |
| def count_bounces_to_target(size, start, target, velocity) do | |
| move( | |
| List.to_tuple(size), | |
| List.to_tuple(start), | |
| List.to_tuple(target), | |
| List.to_tuple(velocity), | |
| 0 | |
| ) | |
| end | |
| defp move(_size, point, point, _velocity, bounces), do: bounces | |
| defp move({rows, cols} = size, {r, c}, target, {dr, dc}, bounces) do | |
| {dr, row_bounce} = bounce(r + dr, dr, rows) | |
| {dc, col_bounce} = bounce(c + dc, dc, cols) | |
| move( | |
| size, | |
| {r + dr, c + dc}, | |
| target, | |
| {dr, dc}, | |
| bounces + row_bounce + col_bounce | |
| ) | |
| end | |
| defp bounce(next, delta, limit) when next < 0 or next >= limit, | |
| do: {-delta, 1} | |
| defp bounce(_next, delta, _limit), do: {delta, 0} | |
| end |
| defmodule RWC_457 do | |
| @moduledoc """ | |
| Given a string consisting of letters, convert each character to its opposite | |
| case. When the alternating option is true, alternate character case instead. | |
| iex> RWC_457.toggle_char("Hello, world!") | |
| "hELLO, WORLD!" | |
| iex> RWC_457.toggle_char("HeheHeheHEheheHeH") | |
| "hEHEhEHEheHEHEhEh" | |
| iex> RWC_457.toggle_char("This will be alternated", true) | |
| "ThIs WiLl Be AlTeRnAtEd" | |
| """ | |
| def toggle_char(str, alternating \\ false) | |
| def toggle_char(str, false) do | |
| str | |
| |> String.graphemes() | |
| |> Enum.map(&swap_case/1) | |
| |> Enum.join() | |
| end | |
| def toggle_char(str, true) do | |
| str | |
| |> String.graphemes() | |
| |> Enum.reduce({[], 0}, fn char, {chars, index} -> | |
| cond do | |
| not letter?(char) -> {[char | chars], index} | |
| rem(index, 2) == 0 -> {[String.upcase(char) | chars], index + 1} | |
| true -> {[String.downcase(char) | chars], index + 1} | |
| end | |
| end) | |
| |> elem(0) | |
| |> Enum.reverse() | |
| |> Enum.join() | |
| end | |
| defp swap_case(char) do | |
| cond do | |
| char =~ ~r/[a-z]/ -> String.upcase(char) | |
| char =~ ~r/[A-Z]/ -> String.downcase(char) | |
| true -> char | |
| end | |
| end | |
| defp letter?(char), do: char =~ ~r/[A-Za-z]/ | |
| end |
| defmodule RWC_458 do | |
| @moduledoc """ | |
| Given a queue of customer names and an integer `n`, move every `n`th customer | |
| to the end of the line while preserving relative order otherwise. | |
| iex> RWC_458.shuffle_line(["Ada", "Ben", "Cam", "Diya", "Eli", "Fay"], 3) | |
| ["Ada", "Ben", "Diya", "Eli", "Cam", "Fay"] | |
| iex> RWC_458.shuffle_line(["A", "B", "C", "D", "E"], 2) | |
| ["A", "C", "E", "B", "D"] | |
| iex> RWC_458.shuffle_line(["Mo", "Noah", "Oli"], 1) | |
| ["Mo", "Noah", "Oli"] | |
| """ | |
| def shuffle_line(customers, count) do | |
| customers | |
| |> Enum.with_index(1) | |
| |> Enum.split_with(fn {_customer, index} -> rem(index, count) != 0 end) | |
| |> then(fn {kept, moved} -> Enum.map(kept ++ moved, &elem(&1, 0)) end) | |
| end | |
| end |
| defmodule RWC_459 do | |
| @moduledoc """ | |
| Given an array of object weights and an array of suitcase capacities, | |
| determine the minimum number of suitcases needed to pack all objects. Return | |
| `-1` if it is impossible. | |
| iex> RWC_459.pack_suitcases([4, 8, 1, 4, 2], [10, 6, 8]) | |
| 3 | |
| iex> RWC_459.pack_suitcases([9, 7, 6], [10, 6]) | |
| -1 | |
| """ | |
| def pack_suitcases(weights, capacities) do | |
| weights = Enum.sort(weights, :desc) | |
| capacities = Enum.sort(capacities, :desc) | |
| 1..length(capacities) | |
| |> Enum.find(fn count -> | |
| capacities | |
| |> combinations(count) | |
| |> Enum.any?(&packable?(weights, &1)) | |
| end) | |
| |> then(&(&1 || -1)) | |
| end | |
| defp packable?(weights, capacities), | |
| do: packable?(weights, capacities, MapSet.new()) | |
| defp packable?([], _capacities, _seen), do: true | |
| defp packable?([weight | rest], capacities, seen) do | |
| key = {weights_key([weight | rest]), capacities} | |
| cond do | |
| MapSet.member?(seen, key) -> | |
| false | |
| true -> | |
| capacities | |
| |> Enum.with_index() | |
| |> Enum.filter(fn {capacity, _index} -> capacity >= weight end) | |
| |> Enum.any?(fn {capacity, index} -> | |
| next_capacities = | |
| List.replace_at(capacities, index, capacity - weight) | |
| |> Enum.sort(:desc) | |
| packable?(rest, next_capacities, MapSet.put(seen, key)) | |
| end) | |
| end | |
| end | |
| defp weights_key(weights), do: Enum.join(weights, ",") | |
| defp combinations(_items, 0), do: [[]] | |
| defp combinations([], _count), do: [] | |
| defp combinations([item | rest], count) do | |
| Enum.map(combinations(rest, count - 1), &[item | &1]) ++ | |
| combinations(rest, count) | |
| end | |
| end |