-
Notifications
You must be signed in to change notification settings - Fork 0
/
mod.ts
71 lines (66 loc) · 1.4 KB
/
mod.ts
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
const d =
(ax: number, ay: number) =>
(bx: number, by: number) =>
Math.sqrt(
(ax - bx) ** 2
+ (ay - by) ** 2
)
const kNN =
(data: {x: number, y: number, clas: string}[]) =>
([cx, cy]: [number, number]) =>
data
.map(({x, y, clas}, i, l) => ({
x, y, clas,
distance: d(x, y)(cx, cy)**2,
weight: 1/d(x, y)(cx, cy)**2,
}))
.map((row, _, l) => {
const { clas } = row
const rank = l.toSorted((a, b) => a.distance - b.distance).indexOf(row) + 1
return {
...row,
rank,
...(rank <= 3 ? {"k = 3": clas} : {}),
...(rank <= 5 ? {"k = 5": clas} : {}),
}
})
const format =
(n: number) =>
Math.round(n * 100) / 100
const objMap =
<V, O>
(f: (entry: [string, V]) => [string, O]) =>
(obj: Record<string, V>) =>
Object.fromEntries(
Object.entries(obj).map(f)
)
const data = `
1 5 blue
1 7 blue
2 6 blue
4 6 blue
5 7 blue
6 4 red
7 5 red
4 8 red
7 8 red
9 7 red
`
.trim()
.split("\n")
.map(x => x.trim().split(" "))
.map(([x, y, clas]) => ({
x: Number(x),
y: Number(y),
clas,
}))
console.table(
kNN(data)([5, 4.5]).map(
objMap(([k, v]) => [
k,
typeof v == "number"
? format(v)
: v
])
)
)