Skip to main content
added 2 characters in body
Source Link
maxb
  • 1.6k
  • 7
  • 19

Let's call the maximum and minimum side lengths \$l_{max}\$ and \$l_{min}\$

We can see that for a certain choice of $i and $j, we can directly calculate the number of choices for $k as \$min(i+j-j, l_{max}+1-j) = min(i, l_{max}+1-j)\$, which suggests that wee can remove the innermost loop.

Now we've got our hopes up, and we hope that the second loop can be removed in a similar fashion. For a fixed value of \$i\$, we know that \$i < l_{max} + 1 - j \iff j < l_{max} + 1 - i\$. We also have to take care of the cases where either sum has a negative number of terms. This way, the second loop can be written as two sums:

$$ \sum_{j = i}^{l_{max}-i}i = i\cdot \text{max}(0, l_{max}-2i+1)$$ $$ \sum_{j = \text{max}(a, l_{max}-i+1)}^{l_{max}}l_{max}+1-j = (l_{max} - \text{max}(i, l_{max}-i+1)+1)(l_{max}+1) - \sum_{j = \text{max}(i, l_{max}-i+1)}^{l_{max}}j$$ $$ = (l_{max} - \text{max}(i, l_{max}-i+1)+1)((l_{max}+1) - \frac{l_{max} + \text{max}(i, l_{max}-i+1)}{2})$$

This got a bit messy, but both are arithmetic sums, and can be calculated fairly easily. Now the entire calculation can be reduced to one loop. I wrote a python script to test it:

minL = 5
maxL = 25
total_ways = 0
for a in range(minL, maxLmaxL+1):
    right_terms = maxL-max(a, maxL-a+1)+1
    left_sum = a*max(0, maxL-2*a+1)
    right_sum = right_terms*(maxL+1) - right_terms*(maxL + max(a, maxL-a+1))//2
    total_ways += left_sum + right_sum
print(total_ways)

It produces identical output for all test cases I've found, and should be way faster. Please ask for any clarifications.

Let's call the maximum and minimum side lengths \$l_{max}\$ and \$l_{min}\$

We can see that for a certain choice of $i and $j, we can directly calculate the number of choices for $k as \$min(i+j-j, l_{max}+1-j) = min(i, l_{max}+1-j)\$, which suggests that wee can remove the innermost loop.

Now we've got our hopes up, and we hope that the second loop can be removed in a similar fashion. For a fixed value of \$i\$, we know that \$i < l_{max} + 1 - j \iff j < l_{max} + 1 - i\$. We also have to take care of the cases where either sum has a negative number of terms. This way, the second loop can be written as two sums:

$$ \sum_{j = i}^{l_{max}-i}i = i\cdot \text{max}(0, l_{max}-2i+1)$$ $$ \sum_{j = \text{max}(a, l_{max}-i+1)}^{l_{max}}l_{max}+1-j = (l_{max} - \text{max}(i, l_{max}-i+1)+1)(l_{max}+1) - \sum_{j = \text{max}(i, l_{max}-i+1)}^{l_{max}}j$$ $$ = (l_{max} - \text{max}(i, l_{max}-i+1)+1)((l_{max}+1) - \frac{l_{max} + \text{max}(i, l_{max}-i+1)}{2})$$

This got a bit messy, but both are arithmetic sums, and can be calculated fairly easily. Now the entire calculation can be reduced to one loop. I wrote a python script to test it:

minL = 5
maxL = 25
total_ways = 0
for a in range(minL, maxL):
    right_terms = maxL-max(a, maxL-a+1)+1
    left_sum = a*max(0, maxL-2*a+1)
    right_sum = right_terms*(maxL+1) - right_terms*(maxL + max(a, maxL-a+1))//2
    total_ways += left_sum + right_sum
print(total_ways)

It produces identical output for all test cases I've found, and should be way faster. Please ask for any clarifications.

Let's call the maximum and minimum side lengths \$l_{max}\$ and \$l_{min}\$

We can see that for a certain choice of $i and $j, we can directly calculate the number of choices for $k as \$min(i+j-j, l_{max}+1-j) = min(i, l_{max}+1-j)\$, which suggests that wee can remove the innermost loop.

Now we've got our hopes up, and we hope that the second loop can be removed in a similar fashion. For a fixed value of \$i\$, we know that \$i < l_{max} + 1 - j \iff j < l_{max} + 1 - i\$. We also have to take care of the cases where either sum has a negative number of terms. This way, the second loop can be written as two sums:

$$ \sum_{j = i}^{l_{max}-i}i = i\cdot \text{max}(0, l_{max}-2i+1)$$ $$ \sum_{j = \text{max}(a, l_{max}-i+1)}^{l_{max}}l_{max}+1-j = (l_{max} - \text{max}(i, l_{max}-i+1)+1)(l_{max}+1) - \sum_{j = \text{max}(i, l_{max}-i+1)}^{l_{max}}j$$ $$ = (l_{max} - \text{max}(i, l_{max}-i+1)+1)((l_{max}+1) - \frac{l_{max} + \text{max}(i, l_{max}-i+1)}{2})$$

This got a bit messy, but both are arithmetic sums, and can be calculated fairly easily. Now the entire calculation can be reduced to one loop. I wrote a python script to test it:

minL = 5
maxL = 25
total_ways = 0
for a in range(minL, maxL+1):
    right_terms = maxL-max(a, maxL-a+1)+1
    left_sum = a*max(0, maxL-2*a+1)
    right_sum = right_terms*(maxL+1) - right_terms*(maxL + max(a, maxL-a+1))//2
    total_ways += left_sum + right_sum
print(total_ways)

It produces identical output for all test cases I've found, and should be way faster. Please ask for any clarifications.

added 48 characters in body
Source Link
maxb
  • 1.6k
  • 7
  • 19

Let's call the maximum and minimum side lengths \$l_{max}\$ and \$l_{min}\$

We can see that for a certain choice of $i and $j, we can directly calculate the number of choices for $k as \$min(i+j-j, l_{max}+1-j) = min(i, l_{max}+1-j)\$, which suggests that wee can remove the innermost loop.

Now we've got our hopes up, and we hope that the second loop can be removed in a similar fashion. For a fixed value of \$i\$, we know that \$i < l_{max} + 1 - j \iff j < l_{max} + 1 - i\$. We also have to take care of the cases where either sum has a negative number of terms. This way, the second loop can be written as two sums:

$$ \sum_{j = i}^{l_{max}-i}i = i*max(0, l_{max}-2i+1)$$$$ \sum_{j = i}^{l_{max}-i}i = i\cdot \text{max}(0, l_{max}-2i+1)$$ $$ \sum_{j = max(a, l_{max}-i+1)}^{l_{max}}l_{max}+1-j = (l_{max} - max(i, l_{max}-i+1)+1)(l_{max}+1) - \sum_{j = max(i, l_{max}-i+1)}^{l_{max}}j$$$$ \sum_{j = \text{max}(a, l_{max}-i+1)}^{l_{max}}l_{max}+1-j = (l_{max} - \text{max}(i, l_{max}-i+1)+1)(l_{max}+1) - \sum_{j = \text{max}(i, l_{max}-i+1)}^{l_{max}}j$$ $$ = (l_{max} - max(i, l_{max}-i+1)+1)((l_{max}+1) - \frac{l_{max} + max(i, l_{max}-i+1)}{2})$$$$ = (l_{max} - \text{max}(i, l_{max}-i+1)+1)((l_{max}+1) - \frac{l_{max} + \text{max}(i, l_{max}-i+1)}{2})$$

This got a bit messy, but both are arithmetic sums, and can be calculated fairly easily. Now the entire calculation can be reduced to one loop. I wrote a python script to test it:

minL = 5
maxL = 25
total_ways = 0
for a in range(minL, maxL):
    right_terms = maxL-max(a, maxL-a+1)+1
    left_sum = a*max(0, maxL-2*a+1)
    right_sum = right_terms*(maxL+1) - right_terms*(maxL + max(a, maxL-a+1))//2
    total_ways += left_sum + right_sum
print(total_ways)

It produces identical output for all test cases I've found, and should be way faster. Please ask for any clarifications.

Let's call the maximum and minimum side lengths \$l_{max}\$ and \$l_{min}\$

We can see that for a certain choice of $i and $j, we can directly calculate the number of choices for $k as \$min(i+j-j, l_{max}+1-j) = min(i, l_{max}+1-j)\$, which suggests that wee can remove the innermost loop.

Now we've got our hopes up, and we hope that the second loop can be removed in a similar fashion. For a fixed value of \$i\$, we know that \$i < l_{max} + 1 - j \iff j < l_{max} + 1 - i\$. We also have to take care of the cases where either sum has a negative number of terms. This way, the second loop can be written as two sums:

$$ \sum_{j = i}^{l_{max}-i}i = i*max(0, l_{max}-2i+1)$$ $$ \sum_{j = max(a, l_{max}-i+1)}^{l_{max}}l_{max}+1-j = (l_{max} - max(i, l_{max}-i+1)+1)(l_{max}+1) - \sum_{j = max(i, l_{max}-i+1)}^{l_{max}}j$$ $$ = (l_{max} - max(i, l_{max}-i+1)+1)((l_{max}+1) - \frac{l_{max} + max(i, l_{max}-i+1)}{2})$$

This got a bit messy, but both are arithmetic sums, and can be calculated fairly easily. Now the entire calculation can be reduced to one loop. I wrote a python script to test it:

minL = 5
maxL = 25
total_ways = 0
for a in range(minL, maxL):
    right_terms = maxL-max(a, maxL-a+1)+1
    left_sum = a*max(0, maxL-2*a+1)
    right_sum = right_terms*(maxL+1) - right_terms*(maxL + max(a, maxL-a+1))//2
    total_ways += left_sum + right_sum
print(total_ways)

It produces identical output for all test cases I've found, and should be way faster. Please ask for any clarifications.

Let's call the maximum and minimum side lengths \$l_{max}\$ and \$l_{min}\$

We can see that for a certain choice of $i and $j, we can directly calculate the number of choices for $k as \$min(i+j-j, l_{max}+1-j) = min(i, l_{max}+1-j)\$, which suggests that wee can remove the innermost loop.

Now we've got our hopes up, and we hope that the second loop can be removed in a similar fashion. For a fixed value of \$i\$, we know that \$i < l_{max} + 1 - j \iff j < l_{max} + 1 - i\$. We also have to take care of the cases where either sum has a negative number of terms. This way, the second loop can be written as two sums:

$$ \sum_{j = i}^{l_{max}-i}i = i\cdot \text{max}(0, l_{max}-2i+1)$$ $$ \sum_{j = \text{max}(a, l_{max}-i+1)}^{l_{max}}l_{max}+1-j = (l_{max} - \text{max}(i, l_{max}-i+1)+1)(l_{max}+1) - \sum_{j = \text{max}(i, l_{max}-i+1)}^{l_{max}}j$$ $$ = (l_{max} - \text{max}(i, l_{max}-i+1)+1)((l_{max}+1) - \frac{l_{max} + \text{max}(i, l_{max}-i+1)}{2})$$

This got a bit messy, but both are arithmetic sums, and can be calculated fairly easily. Now the entire calculation can be reduced to one loop. I wrote a python script to test it:

minL = 5
maxL = 25
total_ways = 0
for a in range(minL, maxL):
    right_terms = maxL-max(a, maxL-a+1)+1
    left_sum = a*max(0, maxL-2*a+1)
    right_sum = right_terms*(maxL+1) - right_terms*(maxL + max(a, maxL-a+1))//2
    total_ways += left_sum + right_sum
print(total_ways)

It produces identical output for all test cases I've found, and should be way faster. Please ask for any clarifications.

Source Link
maxb
  • 1.6k
  • 7
  • 19

Let's call the maximum and minimum side lengths \$l_{max}\$ and \$l_{min}\$

We can see that for a certain choice of $i and $j, we can directly calculate the number of choices for $k as \$min(i+j-j, l_{max}+1-j) = min(i, l_{max}+1-j)\$, which suggests that wee can remove the innermost loop.

Now we've got our hopes up, and we hope that the second loop can be removed in a similar fashion. For a fixed value of \$i\$, we know that \$i < l_{max} + 1 - j \iff j < l_{max} + 1 - i\$. We also have to take care of the cases where either sum has a negative number of terms. This way, the second loop can be written as two sums:

$$ \sum_{j = i}^{l_{max}-i}i = i*max(0, l_{max}-2i+1)$$ $$ \sum_{j = max(a, l_{max}-i+1)}^{l_{max}}l_{max}+1-j = (l_{max} - max(i, l_{max}-i+1)+1)(l_{max}+1) - \sum_{j = max(i, l_{max}-i+1)}^{l_{max}}j$$ $$ = (l_{max} - max(i, l_{max}-i+1)+1)((l_{max}+1) - \frac{l_{max} + max(i, l_{max}-i+1)}{2})$$

This got a bit messy, but both are arithmetic sums, and can be calculated fairly easily. Now the entire calculation can be reduced to one loop. I wrote a python script to test it:

minL = 5
maxL = 25
total_ways = 0
for a in range(minL, maxL):
    right_terms = maxL-max(a, maxL-a+1)+1
    left_sum = a*max(0, maxL-2*a+1)
    right_sum = right_terms*(maxL+1) - right_terms*(maxL + max(a, maxL-a+1))//2
    total_ways += left_sum + right_sum
print(total_ways)

It produces identical output for all test cases I've found, and should be way faster. Please ask for any clarifications.