|
1 | 1 | from enum import Enum, auto
|
2 | 2 | from collections import namedtuple
|
3 | 3 | from numbers import Number
|
| 4 | +from typing import TypeVar, Callable, Union |
4 | 5 |
|
5 | 6 |
|
6 | 7 | Coordinate = namedtuple("Coordinate", ["x", "y"])
|
7 | 8 | Coordinate3 = namedtuple("Coordinate3", ["x", "y", "z"])
|
| 9 | +AnyCoordinate = Coordinate | Coordinate3 |
8 | 10 |
|
9 | 11 |
|
10 |
| -def add(a: Coordinate, b: Coordinate) -> Coordinate: |
11 |
| - xa, ya = a |
12 |
| - xb, yb = b |
13 |
| - return Coordinate(xa + xb, ya + yb) |
| 12 | +def _coordmap(a: AnyCoordinate, b: AnyCoordinate, fn: Callable) -> AnyCoordinate: |
| 13 | + at = type(a) |
| 14 | + return at(*map(fn, zip(a, b))) |
14 | 15 |
|
15 | 16 |
|
16 |
| -def sub(a: Coordinate, b: Coordinate) -> Coordinate: |
17 |
| - xa, ya = a |
18 |
| - xb, yb = b |
19 |
| - return Coordinate(xa - xb, ya - yb) |
| 17 | +def add(a: AnyCoordinate, b: AnyCoordinate) -> AnyCoordinate: |
| 18 | + return _coordmap(a, b, lambda x: x[0] + x[1]) |
20 | 19 |
|
21 | 20 |
|
22 |
| -def mult(a: Coordinate, b: Number) -> Coordinate: |
23 |
| - x, y = a |
24 |
| - return Coordinate(x * b, y * b) |
| 21 | +def sub(a: AnyCoordinate, b: AnyCoordinate) -> AnyCoordinate: |
| 22 | + return _coordmap(a, b, lambda x: x[0] - x[1]) |
25 | 23 |
|
26 | 24 |
|
27 |
| -def manhattan_dist(a: Coordinate, b: Coordinate) -> Number: |
28 |
| - x, y = sub(b, a) |
29 |
| - return abs(x) + abs(y) |
| 25 | +def mult(a: AnyCoordinate, b: Number) -> AnyCoordinate: |
| 26 | + at = type(a) |
| 27 | + return at(*map(lambda x: x * b, a)) |
30 | 28 |
|
31 | 29 |
|
| 30 | +def manhattan_dist(a: AnyCoordinate, b: AnyCoordinate) -> Number: |
| 31 | + return sum(map(abs, sub(b, a))) |
| 32 | + |
| 33 | + |
32 | 34 | def area(x: list[Coordinate]) -> Number:
|
33 | 35 | """
|
34 | 36 | Finds the area of a closed polygon.
|
|
0 commit comments