2013. Detect squares

#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
    }
}