NOTE: Many of the “answers” are only suggestive of how you might solve the problem, and shouldn’t be considered answers that would get you full credit on any assignment.
Hints: Here are some things that are helpful:
>>> pow(5,30000,31)-pow(6,123456,31) 0But, seriously, you should learn to do these things by hand. Use Fermat’s Little Theorem, which says that if $p$ is prime, then $a^{p-1} \equiv 1 \pmod p$. Note that 31 is prime. 30000 is a multiple of 30 so $5^{30000}\:\textrm{mod}\:31$ is 1. 123456 is not a multiple of 30, but 123450 is (remember from grade school how to tell if something is divisible by 3?). So $$\begin{eqnarray} 6^{123456}\;(\textrm{mod}\:31) &=& 6^{123450} \times 6^6\;(\textrm{mod}\:31) \nonumber \\ &=& 6^6\;(\textrm{mod}\:31) \nonumber \\ &=& 36 \times 36 \times 36\;(\textrm{mod}\:31) \nonumber \\ &=& 5 \times 5 \times 5\;(\textrm{mod}\:31) \nonumber \\ &=& 125\;(\textrm{mod}\:31) \nonumber \\ &=& 1 \nonumber \end{eqnarray}$$ Both are 1 (mod 31), so their difference is 0 (mod 31) and hence is divisible by 31.
First, let’s see if this makes sense:
$n$ | Binary | $\log_2 (n+1)$ | $\lceil \log_2 (n+1) \rceil$ |
---|---|---|---|
1 | 1 | 1 | 1 |
2 | 10 | 1.58496 | 2 |
3 | 11 | 2 | 2 |
4 | 100 | 2.32193 | 3 |
5 | 101 | 2.58496 | 3 |
6 | 110 | 2.80735 | 3 |
7 | 111 | 3 | 3 |
8 | 1000 | 3.16993 | 4 |
Okay so it looks right. How do we prove it? Well, we can get further intuition like this:
So let’s prove this thing. The possible values of a $b$-bit number are 100...0 through 111...1, i.e., from $2^{b-1}$ to $2^b-1$. Since we are dealing with integers only we can do some neat things:
$$ \begin{eqnarray} 2^{b-1} & \leq & n & \leq & 2^b-1 \\ 2^{b-1} & \leq & n & < & 2^b \\ 2^{b-1} & < & n+1 & \leq & 2^b \\ b-1 & < & \log_2(n+1) & \leq & b \\ & & \lceil \log_2(n+1) \rceil & = & b \end{eqnarray} $$>>> (2**64-1) / 60 / 60 / 24 / 365.2522 584538525256.2511So over 584 billion years.
>>> sum(2*n+1 for n in range(64)) 4096It would take 4096 seconds to count them all, which is 68 minutes and 16 seconds.
Horner’s Rule in Python, with unit tests!
class Polynomial: def __init__(self, coefficients): self.coefficients = coefficients def eval(self, x): result = 0 for e in reversed(range(max(self.coefficients.keys())+1)): result = result * x + self.coefficients.get(e, 0) return result import unittest class EvaluatorTest(unittest.TestCase): TEST_CASES = [ ({0:5}, [(2,5), (12,5)]), # 5 ({1:2}, [(2,4), (10,20)]), # 2x ({1:2, 0:4}, [(2,8), (-3,-2)]), # 2x + 4 ({3:2, 1:5, 0:-1}, [(1,6), (3,68)]), # 2x^3 + 5x - 1 ({8:-6, 4:1, 2:3}, [(1,-2), (2,-1508)]), # -6x^8 + x^4 + 3x^2 ({7:2, 1:-5, 2:-2}, [(0,0), (2,238)]), # 2x^7 - 2x^2 - 5x ] def test_eval(self): for (coefficients, cases) in EvaluatorTest.TEST_CASES: for (x, expected) in cases: self.assertEqual(Polynomial(coefficients).eval(x), expected) unittest.main()
Here it is in Java:
import java.util.Collections; import java.util.Map; public class Polynomial { private Map<Integer, Integer> coefficients; public Polynomial(Map<Integer, Integer> coefficients) { this.coefficients = coefficients; } public double eval(double x) { double result = 0; for (int e = Collections.max(coefficients.keySet()); e >= 0; e--) { result = result * x + coefficients.getOrDefault(e, 0); } return result; } }
import org.junit.Assert; import org.junit.Test; import com.google.common.collect.ImmutableMap; public class PolynomialTest { @Test public void test5() { Polynomial p = new Polynomial(ImmutableMap.of(0, 5)); Assert.assertEquals(p.eval(2), 5, 0.0000001); Assert.assertEquals(p.eval(12), 5, 0.0000001); } @Test public void test2x() { Polynomial p = new Polynomial(ImmutableMap.of(1, 2)); Assert.assertEquals(p.eval(2), 4, 0.0000001); Assert.assertEquals(p.eval(10), 20, 0.0000001); } @Test public void test2xPlus4() { Polynomial p = new Polynomial(ImmutableMap.of(1, 2, 0, 4)); Assert.assertEquals(p.eval(2), 8, 0.0000001); Assert.assertEquals(p.eval(-3), -2, 0.0000001); } @Test public void testSlightlyLongerPolynomials() { Polynomial p = new Polynomial(ImmutableMap.of(3, 2, 1, 5, 0, -1)); Assert.assertEquals(p.eval(1), 6, 0.0000001); Assert.assertEquals(p.eval(3), 68, 0.0000001); p = new Polynomial(ImmutableMap.of(8, -6, 4, 1, 2, 3)); Assert.assertEquals(p.eval(1), -2, 0.0000001); Assert.assertEquals(p.eval(2), -1508, 0.0000001); p = new Polynomial(ImmutableMap.of(7, 2, 1, -5, 2, -2)); Assert.assertEquals(p.eval(0), 0, 0.0000001); Assert.assertEquals(p.eval(2), 238, 0.0000001); } }
def helper(a, target): if len(a) == 3: return True for i in range(1, len(a)-1): for j in range(i+1, len(a)): if a[0] + a[i] + a[j] == target: if helper(a[1:i] + a[i+1:j] + a[j+1:], target): return True return False def three_partition(a): if len(a) in (0, 3): return True if len(a) % 3 != 0: return False chunks = len(a) // 3 if sum(a) % chunks != 0: return False return helper(a, sum(a) // chunks)
cache = {} def c(n, k): if (n, k) in cache: return cache[(n,k)] result = 1 if k <= 0 or k >= n else c(n-1,k-1) + c(n-1,k) cache[(n,k)] = result return result import unittest class CominationTester(unittest.TestCase): def test_some_things(self): self.assertEqual(c(8,0), 1) self.assertEqual(c(17,12), 6188) self.assertEqual(c(20,11), 167960) self.assertEqual(c(99999,99999), 1) self.assertEqual(c(200,195), 2535650040) unittest.main()
If you do this in Java, you should probably index the hashmap by
a string combination of $n$ and $k$. You could also make a Pair
class but you would have to remember to override both equals
and hashCode
.