Here’s the Java version first:
import java.util.Random; import java.util.Arrays; /** * A little utility class with a bozosort method for integer arrays. A main * method is also thrown in that prints a little table showing the average * number of swaps required to sort arrays of various sizes. */ public class Bozosorter { private static boolean isSorted(int[] a) { for (int i = 1; i < a.length; i++) { if (a[i - 1] > a[i]) { return false; } } return true; } /** * Bozosorts a given array using the given random number generator, returning * the number of swaps required to sort. */ public static int sort(int[] a, Random random) { int swaps = 0; while (!isSorted(a)) { int i = random.nextInt(a.length); int j = random.nextInt(a.length); if (i != j) { int x = a[i]; int y = a[j]; a[i] = y; a[j] = x; swaps++; } } return swaps; } public static void main(String[] args) { Random random = new Random(); int iterations = 50; System.out.println("Size Avg # of swaps"); for (int size = 1; size <= 10; size++) { int swaps = 0; for (int k = 0; k < iterations; k++) { swaps += sort(random.ints(size).toArray(), random); } System.out.printf("%2d%20.2f\n", size, swaps / (double) iterations); } } }
Here is one particular output (your results will differ):
$ java edu.lmu.cs.sorting.Bozosorter Size Avg # of swaps 1 0.00 2 0.46 3 3.94 4 22.48 5 114.64 6 804.12 7 6239.96 8 49741.50 9 404976.52 10 3959040.06
I also wrote this in Python. But it gets realy slow once the size gets to be 9, unless you use PyPy.
from random import randint, shuffle def bozosort(a): n = len(a) - 1 swaps = 0 while not all(a[i] <= a[i+1] for i in range(n)): i, j = randint(0, n), randint(0, n) a[i], a[j] = a[j], a[i] swaps += 1 return swaps def main(): NUM_TRIALS, NUM_ITERATIONS = 10, 20 print('Size Avg # of swaps') for size in range(1, NUM_TRIALS): swaps = 0 for _ in range(1, NUM_ITERATIONS): swaps += bozosort([randint(0,1000) for i in range(size)]) print(f'{size:2d}{swaps/NUM_ITERATIONS:20.2f}') main()
Since the problem asked you to treat characters as code points, it’s reasonable to infer we’re moving into the realm of encrypting real data, and not just the boring set of characters A-Z. Code points are integers, so we implement both our messages and keys as arrays of integers, not strings or arrays of characters. Here is my Java solution:
/** * An auto-key Vigenere cipher. During encryption, the input text is used for * the key stream after the initial key is used up. During decryption, we get * the key characters from the plaintext we are recovering. */ public class AutoKeyVigenere { public static int[] encipher(int[] message, int[] key) { return encipher(message, key, 1); } public static int[] decipher(int[] cipher, int[] key) { return encipher(cipher, key, -1); } private static int[] encipher(int[] input, int[] key, int multiplier) { if (key.length == 0) { throw new IllegalArgumentException("Key cannot be empty"); } int[] output = new int[input.length]; for (int i = 0, n = input.length; i < n; i++) { int block = i < key.length ? key[i] : multiplier == 1 ? input[i - key.length] : output[i - key.length]; output[i] = block * multiplier + input[i]; } return output; } }
And a unit test for it:
import java.util.Arrays; import org.junit.Assert; import org.junit.Test; public class AutoKeyVigenereTest { @Test public void testRoundTrip() { int[][] messages = { { 34634634, 423423, 23423525, 4574574, 47467, 0, 45, 423523677, 97938746 }, { 4, 3, 7, 6, 5, 8, 9, 66, 54, 32, 1132, 87, 898, 87, 787, 878789, 9, 89, 8, 89, 89, 1 }, { 7 }, {} }; int[][] keys = { { 546363434, 3545, 204311244 }, { 0xffffffff, 0xffffff33 } }; for (int[] message : messages) { for (int[] key : keys) { int[] cipher = AutoKeyVigenere.encipher(message, key); int[] recovered = AutoKeyVigenere.decipher(cipher, key); Assert.assertTrue(Arrays.equals(message, recovered)); } } } @Test(expected = IllegalArgumentException.class) public void testEmptyKey() { AutoKeyVigenere.encipher(new int[] { 3453, 4234235, 123 }, new int[] {}); } }
Now if you are not yet using Eclipse or NetBeans or IntelliJ or other IDE yet (C’mon people it’s time), then you can run this on the command line like this (assuming you downloaded JUnit):
$ javac -cp ~/lib/junit-4.10.jar:. crypto/AutoKeyVigenere.java crypto/AutoKeyVigenereTest.java $ java -cp ~/lib/junit-4.10.jar:. org.junit.runner.JUnitCore edu.lmu.cs.crypto.AutoKeyVigenereTest JUnit version 4.10 .. Time: 0.003 OK (2 tests)
The Python version will appear shortly.
p = BigInt(23847623789462398745236743254827634647) q = BigInt(80147623789462398745236743254827634711) N = p * q t = (p-1)*(q-1) e = 7 # Techincally we should iterate to find this.... @assert(gcd(e, t) == 1) d = invmod(e,t) println("Public key is ($N, $e)") println("Private key is ($N, $d)")
The output is
Public key is (1911330379750465988511865475607817924950038631764482538080744390093883432017, 7) Private key is (1911330379750465988511865475607817924950038631764482538080744390093883432017, 546094394214418853860532993030805121384583824053016497311505972452636617903)
"ray"
with encoding {a:1, r:2, y:3}
and
RSA with $p=5$, $q=11$, $e=3$. So $N=pq=55$ and
$d=\mathrm{invmod}(3,40)=27$. Now I’ll sign $(2,1,3)$ as follows:
$(2^{27}\bmod 55, 1^{27}\bmod 55, 1^{27}\bmod 55) = (18,1,42)$.
Now, let’s check:
$(18^{3}\bmod 55, 1^{3}\bmod 55, 42^{3}\bmod 55) = (2,1,3)$.
All good.
julia> factor(391) Dict{Int64,Int64} with 2 entries: 23 => 1 17 => 1 julia> invmod(17, 22*16) 145So the answer is 145.
def majority_naive(a): for x in a: if a.count(x) > len(a) // 2: return x return None def majority_linearithmic(a): if len(a) == 0: return None if len(a) == 1: return a[0] half = len(a) // 2 left = majority_linearithmic(a[0:half]) right = majority_linearithmic(a[half:]) if left == right: return left if a.count(left) > half: return left if a.count(right) > half: return right return None from collections import Counter def majority_with_dictionary(a): counts = Counter() for x in a: counts[x] += 1 for value, count in counts.items(): if count > len(a) // 2: return value return None def majority_linear(a): count = 0 for x in a: if count == 0: candidate = x; if x == candidate: count += 1 else: count -= 1 if a and a.count(candidate) > len(a) // 2: return candidate return None tests = [ ([], None), ([1], 1), ([4,3], None), ([4,4], 4), ([4,4,1], 4), ([4,0,4], 4), ([4,1,8], None), ([3,3,3,3,3,0,0,0,0,0], None), ([3,3,3,3,3,0,0,0,3,0], 3), ([1,1,1,3,3,2,2,3,3,3,2,3,3], 3), ([1,1,1,1,3,2,2,3,3,3,2,3,3], None), ] # Tests for fun in (majority_naive, majority_linearithmic, majority_with_dictionary, majority_linear): for a, expected in tests: if fun(a) != expected: print(f'Ooops, {fun.__name__}({a}) != {expected}')