public class Solution {
Dictionary<(int a, int b, int c, int d), bool> memo = new ();
int maxLen = 0;
public bool Makesquare(int[] matchsticks) {
int sum = matchsticks.Sum();
if (sum % 4 != 0)
return false;
maxLen = sum / 4;
return isValid(matchsticks, 0, 0, 0, 0, 0);
}
bool isValid(int[] sticks, int index, int a, int b, int c, int d)
{
if (index >= sticks.Length)
{
return a == b && b == c && c == d;
}
// sort numbers so that a <= b <= c <= d
(a, b, c, d) = sort(a, b, c, d);
if (memo.ContainsKey((a, b, c, d)))
return memo[(a, b, c, d)];
bool ret = false;
if (a + sticks[index] <= maxLen)
ret = ret || isValid(sticks, index+1, a + sticks[index], b, c, d);
if (b + sticks[index] <= maxLen)
ret = ret || isValid(sticks, index+1, a, b + sticks[index], c, d);
if (c + sticks[index] <= maxLen)
ret = ret || isValid(sticks, index+1, a, b, c + sticks[index], d);
if (d + sticks[index] <= maxLen)
ret = ret || isValid(sticks, index+1, a, b, c, d + sticks[index]);
memo[(a, b, c, d)] = ret;
return ret;
}
(int a, int b, int c, int d) sort(int a, int b, int c, int d)
{
(a, b) = a > b ? (b, a) : (a, b);
(c, d) = c > d ? (d, c) : (c, d);
(a, c) = a > c ? (c, a) : (a, c);
(b, d) = b > d ? (d, b) : (b, d);
(b, c) = b > c ? (c, b) : (b, c);
return (a, b, c, d);
}
}