Skip to content

Commit

Permalink
Simplify allergies solution
Browse files Browse the repository at this point in the history
  • Loading branch information
Abhijit Sarkar committed Sep 8, 2024
1 parent 3b0d1bf commit 730a66b
Showing 1 changed file with 5 additions and 61 deletions.
66 changes: 5 additions & 61 deletions allergies/allergies.py
Original file line number Diff line number Diff line change
@@ -1,68 +1,12 @@
class Bitset:
def __init__(self, size: int) -> None:
self._bits = 0
self._size = size

def set(self, i: int) -> None:
self._bits |= 1 << i

def clear(self, i: int) -> None:
self._bits &= ~(1 << i)

def is_set(self, i: int) -> bool:
return (self._bits & 1 << i) > 0

def get_all_set(self) -> list[int]:
return [i for i in range(self._size) if self.is_set(i)]


class Allergies:
def __init__(self, score: int) -> None:
allergies = {
1: "eggs",
2: "peanuts",
4: "shellfish",
8: "strawberries",
16: "tomatoes",
32: "chocolate",
64: "pollen",
128: "cats",
}
bits = Bitset(8)
# Max score if a person is allergic to everything.
max_score = 255
Allergies._can_make_sum(list(allergies.keys()), 0, score & max_score, bits, {})
self._allergens = [allergies[pow(2, i)] for i in bits.get_all_set()]
allergies = ["eggs", "peanuts", "shellfish", "strawberries", "tomatoes", "chocolate", "pollen", "cats"]
# // If the ith bit is set, the result is that 2^i (greater than 0)
self.allergens = [allergies[i] for i in range(len(allergies)) if score & (1 << i) > 0]

def allergic_to(self, item: str) -> bool:
return item in self._allergens

# Subset sum.
@staticmethod
def _can_make_sum(nums: list[int], i: int, remaining: int, bits: Bitset, memo: dict[tuple[int, int], bool]) -> bool:
"""
Returns true is remaining can be made by the sum of a subset of the array nums[i:].
The elements chosen are indicated by the corresponding set bits in the bitset
"""
if remaining == 0:
return True
if i >= len(nums) or bits.is_set(i):
return False
key = (i, remaining)
if key in memo:
return memo[key]
found = False
if nums[i] <= remaining:
# Include nums[i].
bits.set(i)
found = Allergies._can_make_sum(nums, i + 1, remaining - nums[i], bits, memo)
if not found:
# Exclude nums[i].
bits.clear(i)
found = Allergies._can_make_sum(nums, i + 1, remaining, bits, memo)
memo[key] = found
return found
return item in self.allergens

@property
def lst(self) -> list[str]:
return self._allergens
return self.allergens

0 comments on commit 730a66b

Please sign in to comment.