This case study portfolio demonstrates how Apple uses foundational algorithms to solve complex, large-scale problems in areas like route optimization, predictive search, and supply chain logistics—balancing performance and elegance.
The selected case studies reflect Apple’s use of data structures and algorithms across various services. These include autocomplete using Tries, route optimization via A*, and duplicate detection using Bloom filters.
This blend of clean algorithms and user-centric innovation mirrors Apple’s philosophy of elegant performance, which is what this portfolio embodies.
Each solution showcased is grounded in simplicity, scalability, and real-world relevance—hallmarks of Apple’s engineering ethos.
By combining structured logic with intuitive design, this portfolio reflects the seamless integration of technology and user experience that Apple stands for.
import heapq
class Node:
def __init__(self, position, g=0, h=0, parent=None):
self.position = position # (x, y)
self.g = g # Cost from start to current node
self.h = h # Heuristic cost to goal
self.f = g + h # Total cost
self.parent = parent # For path reconstruction
def __lt__(self, other):
return self.f < other.f # Priority Queue uses this
def heuristic(a, b):
# Manhattan distance
return abs(a[0] - b[0]) + abs(a[1] - b[1])
def astar(grid, start, end):
open_set = []
closed_set = set()
start_node = Node(start, g=0, h=heuristic(start, end))
heapq.heappush(open_set, start_node)
while open_set:
current = heapq.heappop(open_set)
if current.position == end:
path = []
while current:
path.append(current.position)
current = current.parent
return path[::-1] # reverse
closed_set.add(current.position)
for dx, dy in [(-1,0),(1,0),(0,-1),(0,1)]: # neighbors (up, down, left, right)
neighbor_pos = (current.position[0] + dx, current.position[1] + dy)
if (0 <= neighbor_pos[0] < len(grid) and
0 <= neighbor_pos[1] < len(grid[0]) and
grid[neighbor_pos[0]][neighbor_pos[1]] == 0 and # 0 = walkable
neighbor_pos not in closed_set):
g = current.g + 1
h = heuristic(neighbor_pos, end)
neighbor = Node(neighbor_pos, g, h, parent=current)
if any(n.position == neighbor.position and n.f <= neighbor.f for n in open_set):
continue # Already have better path
heapq.heappush(open_set, neighbor)
return None # No path found
# Example usage
grid = [
[0, 0, 0, 0, 1],
[1, 1, 0, 1, 0],
[0, 0, 0, 0, 0],
[0, 1, 1, 1, 0],
[0, 0, 0, 1, 0]
]
start = (0, 0)
end = (4, 4)
path = astar(grid, start, end)
print("Shortest Path:", path)
class TrieNode:
def __init__(self):
self.children = {}
self.is_end = False
class Trie:
def __init__(self):
self.root = TrieNode()
def insert(self, word):
node = self.root
for char in word:
if char not in node.children:
node.children[char] = TrieNode()
node = node.children[char]
node.is_end = True
def autocomplete(self, prefix):
node = self.root
for char in prefix:
if char not in node.children:
return []
node = node.children[char]
return self._collect_words(node, prefix)
def _collect_words(self, node, prefix):
words = []
if node.is_end:
words.append(prefix)
for char, child in node.children.items():
words.extend(self._collect_words(child, prefix + char))
return words
# Example usage
trie = Trie()
for word in ["hello", "help", "helium", "hero"]:
trie.insert(word)
print(trie.autocomplete("he"))
import mmh3
class BloomFilter:
def __init__(self, size, hash_count):
self.size = size
self.hash_count = hash_count
self.bit_array = [0] * size
def add(self, string):
for i in range(self.hash_count):
index = mmh3.hash(string, i) % self.size
self.bit_array[index] = 1
def check(self, string):
for i in range(self.hash_count):
index = mmh3.hash(string, i) % self.size
if self.bit_array[index] == 0:
return False
return True
# Example usage
bf = BloomFilter(1000, 5)
bf.add("photo_123")
print(bf.check("photo_123")) # Likely True
print(bf.check("photo_999")) # Likely False or False Positive
class Node:
def __init__(self, key, value):
self.key = key
self.value = value
self.prev = self.next = None
class LRUCache:
def __init__(self, capacity):
self.capacity = capacity
self.cache = {}
self.head = Node(0, 0)
self.tail = Node(0, 0)
self.head.next = self.tail
self.tail.prev = self.head
def _remove(self, node):
p, n = node.prev, node.next
p.next, n.prev = n, p
def _add(self, node):
n = self.head.next
self.head.next = node
node.prev = self.head
node.next = n
n.prev = node
def get(self, key):
if key in self.cache:
node = self.cache[key]
self._remove(node)
self._add(node)
return node.value
return -1
def put(self, key, value):
if key in self.cache:
self._remove(self.cache[key])
node = Node(key, value)
self._add(node)
self.cache[key] = node
if len(self.cache) > self.capacity:
lru = self.tail.prev
self._remove(lru)
del self.cache[lru.key]
# Example usage
lru = LRUCache(2)
lru.put(1, 1)
lru.put(2, 2)
print(lru.get(1))
print(lru.get(2))
lru.put(3, 3)
print(lru.get(1)) # -1, evicted
class UnionFind:
def __init__(self, n):
self.parent = list(range(n))
self.rank = [0] * n
def find(self, x):
if self.parent[x] != x:
self.parent[x] = self.find(self.parent[x]) # Path compression
return self.parent[x]
def union(self, x, y):
root_x = self.find(x)
root_y = self.find(y)
if root_x == root_y:
return
if self.rank[root_x] < self.rank[root_y]:
self.parent[root_x] = root_y
elif self.rank[root_x] > self.rank[root_y]:
self.parent[root_y] = root_x
else:
self.parent[root_y] = root_x
self.rank[root_x] += 1
def connected(self, x, y):
return self.find(x) == self.find(y)
# Example usage
uf = UnionFind(5)
uf.union(0, 1)
uf.union(2, 3)
print(uf.connected(0, 1)) # True
print(uf.connected(1, 2)) # False