package main
// Tuple3Int ...
type Tuple3Int struct {
_1 int
_2 int
_3 int
}
/**
* Definition for a point.
* type Point struct {
* X int
* Y int
* }
*/
func maxPoints(points []Point) (maxPts int) {
xAxisDir := make(map[int]int)
yAxisDir := make(map[int]int)
weight := make(map[Point]int)
for i := range points {
xAxisDir[points[i].X]++
yAxisDir[points[i].Y]++
weight[points[i]]++
}
lines := make(map[Tuple3Int]map[Point]int)
for i := 0; i < len(points); i++ {
for j := i + 1; j < len(points); j++ {
if points[i].X != points[j].X && points[i].Y != points[j].Y {
pair := getParamsOfLine(points[i], points[j])
if _, ok := lines[pair]; !ok {
lines[pair] = make(map[Point]int)
}
if _, ok := lines[pair][points[i]]; !ok {
lines[pair][points[i]] += weight[points[i]]
}
if _, ok := lines[pair][points[j]]; !ok {
lines[pair][points[j]] += weight[points[j]]
}
}
}
}
for _, v := range xAxisDir {
if v > maxPts {
maxPts = v
}
}
for _, v := range yAxisDir {
if v > maxPts {
maxPts = v
}
}
for _, m := range lines {
pts := 0
for _, v := range m {
pts += v
}
if pts > maxPts {
maxPts = pts
}
}
return
}
// Caculate params of given line ay = bx + c, return Tuple3Int{a, b, c}
func getParamsOfLine(p1, p2 Point) Tuple3Int {
y, x := p2.Y-p1.Y, p2.X-p1.X
a, b := x, y
for b != 0 {
a, b = b, a%b
}
return Tuple3Int{x / a, y / a, (x*p1.Y - y*p1.X) / a}
}
// func main() {
// println(maxPoints(
// []Point{{1, 1}, {2, 2}, {1, 1}}))
// println(maxPoints(
// []Point{{1, 1}, {2, 2}, {3, 3}}))
// println(maxPoints(
// []Point{{1, 1}, {3, 2}, {5, 3}, {4, 1}, {2, 3}, {1, 4}}))
// }