diff --git a/contents/graham_scan/code/golang/graham.go b/contents/graham_scan/code/golang/graham.go new file mode 100644 index 000000000..4b405b8e8 --- /dev/null +++ b/contents/graham_scan/code/golang/graham.go @@ -0,0 +1,54 @@ +package main + +import ( + "fmt" + "math" + "sort" +) + +type point struct { + x, y int +} + +func counterClockwise(p1, p2, p3 point) bool { + return (p3.y-p1.y)*(p2.x-p1.x) >= (p2.y-p1.y)*(p3.x-p1.x) +} + +func polarAngle(ref, point point) float64 { + return math.Atan2(float64(point.y-ref.y), float64(point.x-ref.x)) +} + +func grahamScan(points []point) []point { + sort.Slice(points, func(a, b int) bool { + return points[a].y < points[b].y || (points[a].y == points[b].y && points[a].x < points[b].x) + }) + + start := points[0] + points = points[1:] + + sort.Slice(points, func(a, b int) bool { + return polarAngle(start, points[a]) < polarAngle(start, points[b]) + }) + + hull := []point{start, points[0], points[1]} + for _, p := range points[2:] { + for !counterClockwise(hull[len(hull)-2], hull[len(hull)-1], p) { + hull = hull[:len(hull)-1] + } + hull = append(hull, p) + } + + return hull +} + +func main() { + points := []point{{-5, 2}, {5, 7}, {-6, -12}, {-14, -14}, {9, 9}, + {-1, -1}, {-10, 11}, {-6, 15}, {-6, -8}, {15, -9}, + {7, -7}, {-2, -9}, {6, -5}, {0, 14}, {2, 8}} + + fmt.Println("The points in the hull are:") + hull := grahamScan(points) + for _, p := range hull { + fmt.Println(p) + } +} diff --git a/contents/graham_scan/graham_scan.md b/contents/graham_scan/graham_scan.md index 23dd942d0..65402dcf2 100644 --- a/contents/graham_scan/graham_scan.md +++ b/contents/graham_scan/graham_scan.md @@ -22,6 +22,8 @@ We can find whether a rotation is counter-clockwise with trigonometric functions [import:36-38, lang:"javascript"](code/javascript/graham-scan.js) {% sample lang="py" %} [import:4-6, lang:"python"](code/python/grahamScan.py) +{% sample lang="go" %} +[import:13-15, lang:"go"](code/golang/graham.go) {% sample lang="java" %} [import:27-29, lang:"java"](code/java/GrahamScan.java) {% endmethod %} @@ -48,6 +50,8 @@ In the end, the code should look something like this: [import:1-30, lang:"javascript"](code/javascript/graham-scan.js) {% sample lang="py" %} [import:14-27, lang:"python"](code/python/grahamScan.py) +{% sample lang="go" %} +[import:21-42, lang:"go"](code/golang/graham.go) {% sample lang="java" %} [import:35-70, lang:"java"](code/java/GrahamScan.java) {% endmethod %} @@ -69,6 +73,8 @@ In the end, the code should look something like this: [import, lang:"javascript"](code/javascript/graham-scan.js) {% sample lang="py" %} [import, lang:"python"](code/python/grahamScan.py) +{% sample lang="go" %} +[import, lang:"go"](code/golang/graham.go) {% sample lang="java" %} [import, lang:"java"](code/java/GrahamScan.java) {% endmethod %}