Skip to content

Commit

Permalink
feat(binarysearch): successful pairs of spells & potions
Browse files Browse the repository at this point in the history
  • Loading branch information
BrianLusina committed Oct 18, 2023
1 parent d645f23 commit dddcc72
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 1 deletion.
2 changes: 1 addition & 1 deletion datastructures/trees/ternary/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Optional, List, Any, Generator, Dict, Iterator
from typing import Optional, List
from datastructures.trees import Tree, TreeNode, T
from datastructures.trees.ternary.node import TernaryTreeNode

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Successful Pairs of Spells and Potions

You are given two positive integer arrays spells and potions, of length n and m respectively, where spells[i] represents
the strength of the ith spell and potions[j] represents the strength of the jth potion.

You are also given an integer success. A spell and potion pair is considered successful if the product of their
strengths is at least success.

Return an integer array pairs of length n where pairs[i] is the number of potions that will form a successful pair with
the ith spell.

``` plain
Example 1:
Input: spells = [5,1,3], potions = [1,2,3,4,5], success = 7
Output: [4,0,3]
Explanation:
- 0th spell: 5 * [1,2,3,4,5] = [5,10,15,20,25]. 4 pairs are successful.
- 1st spell: 1 * [1,2,3,4,5] = [1,2,3,4,5]. 0 pairs are successful.
- 2nd spell: 3 * [1,2,3,4,5] = [3,6,9,12,15]. 3 pairs are successful.
Thus, [4,0,3] is returned.
Example 2:
Input: spells = [3,1,2], potions = [8,5,8], success = 16
Output: [2,0,2]
Explanation:
- 0th spell: 3 * [8,5,8] = [24,15,24]. 2 pairs are successful.
- 1st spell: 1 * [8,5,8] = [8,5,8]. 0 pairs are successful.
- 2nd spell: 2 * [8,5,8] = [16,10,16]. 2 pairs are successful.
Thus, [2,0,2] is returned.
```

## Topics

- Array
- Two Pointers
- Binary Search
- Sorting
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
from bisect import bisect_left
from typing import List


def successful_pairs(spells: List[int], potions: List[int], success: int) -> List[int]:
pairs = []

sorted_potions = sorted(potions)

for spell in spells:
middle = (success + spell - 1) // spell
count = len(sorted_potions) - bisect_left(sorted_potions, middle)
pairs.append(count)

return pairs


def successful_pairs_2(spells: List[int], potions: List[int], success: int) -> List[int]:
def valid_position(sorted_potions: List[int], target: int, current_spell: int) -> int:
"""This retrieves the first position of a potion which if multiplied with a spell returns at least the given
strength
Args:
sorted_potions (List): list of sorted potions
target (int): success.
current_spell (int): spell.
Returns:
index of the first potion that will return at least success when multiplied with spell
"""
potion_needed = (target + current_spell - 1) // current_spell
left, right = 0, len(sorted_potions)

while left < right:
middle = (left + right) >> 1

if sorted_potions[middle] >= potion_needed:
right = middle
else:
left = middle + 1
return left

pairs = []
potions.sort()

for spell in spells:
count = len(potions) - valid_position(potions, success, spell)
pairs.append(count)

return pairs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import unittest

from . import successful_pairs, successful_pairs_2


class SuccessfulPairsTestCase(unittest.TestCase):
def test_1(self):
"""spells = [5,1,3], potions = [1,2,3,4,5], success = 7 should return [4,0,3]"""
spells = [5, 1, 3]
potions = [1, 2, 3, 4, 5]
success = 7
expected = [4, 0, 3]
actual = successful_pairs(spells, potions, success)
self.assertEqual(expected, actual)

def test_2(self):
"""spells = [3,1,2], potions = [8,5,8], success = 16 should return [2,0,2]"""
spells = [3, 1, 2]
potions = [8, 5, 8]
success = 16
expected = [2, 0, 2]
actual = successful_pairs(spells, potions, success)
self.assertEqual(expected, actual)


class SuccessfulPairs2TestCase(unittest.TestCase):
def test_1(self):
"""spells = [5,1,3], potions = [1,2,3,4,5], success = 7 should return [4,0,3]"""
spells = [5, 1, 3]
potions = [1, 2, 3, 4, 5]
success = 7
expected = [4, 0, 3]
actual = successful_pairs_2(spells, potions, success)
self.assertEqual(expected, actual)

def test_2(self):
"""spells = [3,1,2], potions = [8,5,8], success = 16 should return [2,0,2]"""
spells = [3, 1, 2]
potions = [8, 5, 8]
success = 16
expected = [2, 0, 2]
actual = successful_pairs_2(spells, potions, success)
self.assertEqual(expected, actual)


if __name__ == '__main__':
unittest.main()

0 comments on commit dddcc72

Please sign in to comment.