-
Notifications
You must be signed in to change notification settings - Fork 0
/
PolygonConcavityIndex.js
39 lines (31 loc) · 1.2 KB
/
PolygonConcavityIndex.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// Task: https://app.codility.com/programmers/lessons/99-future_training/polygon_concavity_index/
// Result: https://app.codility.com/demo/results/trainingQ2RS5E-FUB/
function solution(A) {
const normIndex = i => (A.length + i % A.length) % A.length
const a = i => A[normIndex(i)]
const turnDir = i => sinSign({x: a(i).x - a(i-1).x, y: a(i).y - a(i-1).y},
{x: a(i+1).x - a(i).x, y: a(i+1).y - a(i).y})
const nextTurn = i => {
return turnDir(i) == 0 ? nextTurn(i+1) :i
}
const nextOppositeTurn = (i, dir, remain ) => {
if(remain==0) return -1
const nt = nextTurn(i+1)
const ntDir = turnDir(nt)
if(ntDir * dir < 0 ) return nt
else return nextOppositeTurn(nt, dir, remain-1)
}
let left = 0
for(let i = 0; i < A.length ; i++ ){
if( a(left).x > a(i).x ) left = i
}
const res = nextOppositeTurn(nextTurn(left), turnDir(nextTurn(left)), A.length * 2 )
return res<0 ? -1 : normIndex(res)
}
function sinSign(inVector,outVector) {
return dotProd(inVector,{x: -outVector.y, y: outVector.x})
}
function dotProd(a,b) {
return a.x*b.x + a.y*b.y
}
module.exports = solution