如何判断一组点是否构成三角形?求更Pythonic的实现方案
Hey there! Let's break down your problem of determining if three points in a triangular number grid form a triangle, plus optimize your code to be more Pythonic.
Simplified Approach to Check for a Triangle
First, I assume you're working with a triangular number array—where the nth row has n numbers, starting at (n-1)*n//2 + 1 and ending at n*(n+1)//2. For three points to form a triangle, they just need to not be collinear. Collinearity here falls into three cases:
- All three points are on the same row (same row number
n) - All three lie on a left-slanting diagonal (where
n - kis constant;kis the position in the row, starting at 1 from the left) - All three lie on a right-slanting diagonal (where
n + kis constant)
So the straightforward steps are:
- Convert each value
vto its corresponding(n, k)coordinate in the grid - Check if the three coordinates meet any of the collinearity conditions above
- If none are met, the points form a triangle
Pythonic Implementation
Your original code uses sympy for solving equations, which is overkill and slow. We can replace that with direct math to compute coordinates, then use clean Pythonic checks:
import math def get_grid_coords(value): # Calculate row number n: satisfies (n-1)*n//2 < value <= n*(n+1)//2 sqrt_term = math.sqrt(8 * value - 7) row = math.ceil((sqrt_term - 1) / 2) # Calculate position k in the row pos = value - (row - 1) * row // 2 return (row, pos) def forms_triangle(values): if len(values) != 3: return False # We're only handling 3-point checks here coords = [get_grid_coords(v) for v in values] # Check if all share the same row rows = {row for row, pos in coords} if len(rows) == 1: return False # Check left-slanting diagonal (row - pos is constant) left_diags = {row - pos for row, pos in coords} if len(left_diags) == 1: return False # Check right-slanting diagonal (row + pos is constant) right_diags = {row + pos for row, pos in coords} if len(right_diags) == 1: return False # No collinearity = valid triangle return True # Test with your example values vals = [8, 17, 19] print(forms_triangle(vals)) # Will return True/False based on actual collinearity
Why This Is Better Than Your Original Code
- No more equation solving: We use a mathematical formula to compute the row directly, avoiding loops and symbolic computation—way faster.
- Clean collinearity checks: Using sets to check if all coordinates share a row/diagonal is concise and readable, which is very Pythonic.
- Modular functions: Breaking the logic into small, reusable functions makes the code easier to debug and extend later.
Your original stepsb and stepsf variables are equivalent to pos-1 and row-pos respectively, but we don't need them explicitly here since we can use the row and pos values directly to check diagonals.
内容的提问来源于stack exchange,提问作者Roy Ancri

