#include <stdlib.h>
#define MAXC 1001 // coordinates are in [0, 1000]
typedef struct {
int cnt[MAXC][MAXC];
int (*pts)[2]; // distinct points, so count() walks only those
int len, cap;
} DetectSquares;
DetectSquares *detectSquaresCreate() {
DetectSquares *obj = calloc(1, sizeof(DetectSquares));
obj->cap = 16;
obj->pts = malloc(sizeof(int[2]) * obj->cap);
return obj;
}
void detectSquaresAdd(DetectSquares *obj, int *point, int pointSize) {
int x = point[0], y = point[1];
if (obj->cnt[x][y]++ > 0)
return;
if (obj->len == obj->cap) {
obj->cap *= 2;
obj->pts = realloc(obj->pts, sizeof(int[2]) * obj->cap);
}
obj->pts[obj->len][0] = x;
obj->pts[obj->len][1] = y;
obj->len++;
}
int detectSquaresCount(DetectSquares *obj, int *point, int pointSize) {
int x = point[0], y = point[1], res = 0;
for (int i = 0; i < obj->len; i++) {
int px = obj->pts[i][0], py = obj->pts[i][1];
if (px == x || abs(px - x) != abs(py - y))
continue; // must be a diagonal corner with side length > 0
res += obj->cnt[px][py] * obj->cnt[x][py] * obj->cnt[px][y];
}
return res;
}
void detectSquaresFree(DetectSquares *obj) {
free(obj->pts);
free(obj);
}
#include <cstdlib>
#include <map>
#include <utility>
#include <vector>
using namespace std;
class DetectSquares {
map<pair<int, int>, int> cnt;
int get(int x, int y) {
auto it = cnt.find({x, y});
return it == cnt.end() ? 0 : it->second;
}
public:
DetectSquares() {}
void add(vector<int> point) { cnt[{point[0], point[1]}]++; }
int count(vector<int> point) {
int x = point[0], y = point[1], res = 0;
for (auto &[p, c] : cnt) {
int px = p.first, py = p.second;
if (px == x || abs(px - x) != abs(py - y))
continue; // must be a diagonal corner with side length > 0
res += c * get(x, py) * get(px, y);
}
return res;
}
};
package mathgeometry
type DetectSquares struct {
cnt map[[2]int]int
}
func Constructor() DetectSquares {
return DetectSquares{cnt: map[[2]int]int{}}
}
func (this *DetectSquares) Add(point []int) {
this.cnt[[2]int{point[0], point[1]}]++
}
func abs(a int) int {
if a < 0 {
return -a
}
return a
}
func (this *DetectSquares) Count(point []int) int {
x, y, res := point[0], point[1], 0
for p, c := range this.cnt {
px, py := p[0], p[1]
if px == x || abs(px-x) != abs(py-y) {
continue // must be a diagonal corner with side length > 0
}
res += c * this.cnt[[2]int{x, py}] * this.cnt[[2]int{px, y}]
}
return res
}
import java.util.HashMap;
import java.util.Map;
class DetectSquares {
private final Map<Long, Integer> cnt = new HashMap<>();
private static long key(int x, int y) {
return ((long) x << 32) | y;
}
private int get(int x, int y) {
return cnt.getOrDefault(key(x, y), 0);
}
public DetectSquares() {
}
public void add(int[] point) {
cnt.merge(key(point[0], point[1]), 1, Integer::sum);
}
public int count(int[] point) {
int x = point[0], y = point[1], res = 0;
for (Map.Entry<Long, Integer> e : cnt.entrySet()) {
int px = (int) (e.getKey() >> 32), py = (int) (long) e.getKey();
if (px == x || Math.abs(px - x) != Math.abs(py - y))
continue; // must be a diagonal corner with side length > 0
res += e.getValue() * get(x, py) * get(px, y);
}
return res;
}
}
var DetectSquares = function () {
this.cnt = new Map(); // "x,y" -> count
};
DetectSquares.prototype.get = function (x, y) {
return this.cnt.get(`${x},${y}`) ?? 0;
};
/**
* @param {number[]} point
* @return {void}
*/
DetectSquares.prototype.add = function (point) {
const k = `${point[0]},${point[1]}`;
this.cnt.set(k, (this.cnt.get(k) ?? 0) + 1);
};
/**
* @param {number[]} point
* @return {number}
*/
DetectSquares.prototype.count = function (point) {
const [x, y] = point;
let res = 0;
for (const [k, c] of this.cnt) {
const [px, py] = k.split(",").map(Number);
if (px === x || Math.abs(px - x) !== Math.abs(py - y))
continue; // must be a diagonal corner with side length > 0
res += c * this.get(x, py) * this.get(px, y);
}
return res;
};
from collections import Counter
from typing import List
class DetectSquares:
def __init__(self):
self.cnt = Counter()
def add(self, point: List[int]) -> None:
self.cnt[tuple(point)] += 1
def count(self, point: List[int]) -> int:
x, y = point
res = 0
for (px, py), c in self.cnt.items():
if px == x or abs(px - x) != abs(py - y):
continue # must be a diagonal corner with side length > 0
res += c * self.cnt[(x, py)] * self.cnt[(px, y)]
return res
use std::collections::HashMap;
struct DetectSquares {
cnt: HashMap<(i32, i32), i32>,
}
impl DetectSquares {
fn new() -> Self {
DetectSquares { cnt: HashMap::new() }
}
fn get(&self, x: i32, y: i32) -> i32 {
*self.cnt.get(&(x, y)).unwrap_or(&0)
}
fn add(&mut self, point: Vec<i32>) {
*self.cnt.entry((point[0], point[1])).or_insert(0) += 1;
}
fn count(&self, point: Vec<i32>) -> i32 {
let (x, y) = (point[0], point[1]);
let mut res = 0;
for (&(px, py), &c) in &self.cnt {
if px == x || (px - x).abs() != (py - y).abs() {
continue; // must be a diagonal corner with side length > 0
}
res += c * self.get(x, py) * self.get(px, y);
}
res
}
}