Compare commits

...

2 Commits

Author SHA1 Message Date
a8d82b180a
Sorting linked list with mutation (oh no) 2023-10-21 08:41:41 -04:00
337a795ad0
Linked list sorting (?) 2023-10-21 08:23:14 -04:00
5 changed files with 128 additions and 1 deletions

1
leetcode/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
.envrc

View File

@ -25,7 +25,8 @@ classifiers = [
"Programming Language :: Python :: Implementation :: PyPy", "Programming Language :: Python :: Implementation :: PyPy",
] ]
dependencies = [ dependencies = [
"ipython" "ipython",
"ipdb"
] ]
[project.urls] [project.urls]

9
leetcode/stdlib.py Normal file
View File

@ -0,0 +1,9 @@
import typing
class ListNode:
"""ListNode is the leetcode "standard library" type used in linked lists"""
def __init__(self, val=0, next: typing.Optional["ListNode"] = None): # no qa
self.val = val
self.next = next

View File

@ -1,5 +1,7 @@
import typing import typing
import stdlib
def yep(s: str) -> bool: def yep(s: str) -> bool:
return s.strip().lower().startswith("y") return s.strip().lower().startswith("y")
@ -158,3 +160,42 @@ class MinStack:
def getMin(self) -> int: # no qa def getMin(self) -> int: # no qa
return self._min[-1] return self._min[-1]
def linked_list_to_list(head: stdlib.ListNode | None) -> list[int]:
seen: set[int] = set()
ret: list[int] = []
while head is not None:
if hash(head) in seen:
return ret
seen.add(hash(head))
ret.append(head.val)
head = head.next
return ret
def sort_linked_list(head: stdlib.ListNode | None) -> stdlib.ListNode | None:
by_val: list[tuple[int, stdlib.ListNode]] = []
ret: stdlib.ListNode | None = None
while head is not None:
by_val.append((head.val, head))
head = head.next
cur = ret
for _, node in sorted(by_val, key=lambda v: v[0]):
if cur is None:
cur = ret = node
continue
cur.next = node
cur = cur.next
if cur is not None:
cur.next = None
return ret

View File

@ -1,6 +1,7 @@
import pytest import pytest
import stuff import stuff
import stdlib
@pytest.mark.parametrize( @pytest.mark.parametrize(
@ -77,3 +78,77 @@ def test_min_stack(ops: list[tuple[str] | tuple[str, int]], expected: list[int |
returned.append(getattr(inst, method)(arg)) returned.append(getattr(inst, method)(arg))
assert returned == expected assert returned == expected
@pytest.mark.parametrize(
("head", "expected"),
[
(None, None),
(
stdlib.ListNode(
4, stdlib.ListNode(2, stdlib.ListNode(1, stdlib.ListNode(3)))
),
stdlib.ListNode(
1, stdlib.ListNode(2, stdlib.ListNode(3, stdlib.ListNode(4)))
),
),
(
stdlib.ListNode(
4,
stdlib.ListNode(
19,
stdlib.ListNode(
14,
stdlib.ListNode(
5,
stdlib.ListNode(
-3,
stdlib.ListNode(
1,
stdlib.ListNode(
8,
stdlib.ListNode(
5, stdlib.ListNode(11, stdlib.ListNode(15))
),
),
),
),
),
),
),
),
stdlib.ListNode(
-3,
stdlib.ListNode(
1,
stdlib.ListNode(
4,
stdlib.ListNode(
5,
stdlib.ListNode(
5,
stdlib.ListNode(
8,
stdlib.ListNode(
11,
stdlib.ListNode(
14, stdlib.ListNode(15, stdlib.ListNode(19))
),
),
),
),
),
),
),
),
),
],
)
def test_sort_linked_list(head: stdlib.ListNode | None, expected: stdlib.ListNode | None):
if head is None:
assert stuff.sort_linked_list(head) == expected
return
assert stuff.linked_list_to_list(
stuff.sort_linked_list(head)
) == stuff.linked_list_to_list(expected)