Parcourir la source

Added exercise crypto-square

Piet van Dongen il y a 11 ans
Parent
révision
de5e9d6f9e

+ 2
- 1
config.json Voir le fichier

@@ -25,7 +25,8 @@
25 25
     "allergies",
26 26
     "strain",
27 27
     "atbash-cipher",
28
-    "accumulate"
28
+    "accumulate",
29
+    "crypto-square"
29 30
   ],
30 31
   "deprecated": [
31 32
   ],

+ 11
- 0
crypto-square/build.gradle Voir le fichier

@@ -0,0 +1,11 @@
1
+apply plugin: "java"
2
+apply plugin: "eclipse"
3
+apply plugin: "idea"
4
+
5
+repositories {
6
+  mavenCentral()
7
+}
8
+
9
+dependencies {
10
+  testCompile "junit:junit:4.10"
11
+}

+ 72
- 0
crypto-square/example.java Voir le fichier

@@ -0,0 +1,72 @@
1
+import java.util.ArrayList;
2
+import java.util.List;
3
+
4
+public class Crypto {
5
+
6
+    private String normalizedPlaintext;
7
+    private int squareSize;
8
+
9
+    public Crypto(String text) {
10
+        this.normalizedPlaintext = normalizeText(text);
11
+        this.squareSize = calculateSquareSize(normalizedPlaintext);
12
+    }
13
+
14
+    public String getNormalizedPlaintext() {
15
+        return normalizedPlaintext;
16
+    }
17
+
18
+    public int getSquareSize() {
19
+        return squareSize;
20
+    }
21
+
22
+    private static String normalizeText(String text) {
23
+        return text.toLowerCase().codePoints()
24
+                .filter(x -> Character.isLetterOrDigit(x))
25
+                .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
26
+                .toString();
27
+    }
28
+
29
+    private static int calculateSquareSize(String text) {
30
+        return (int) Math.ceil(Math.sqrt(text.length()));
31
+    }
32
+
33
+    public List<String> getPlaintextSegments() {
34
+        return getSegmentText(normalizedPlaintext, squareSize);
35
+    }
36
+
37
+    private static List<String> getSegmentText(String text, int squareSize) {
38
+        List<String> segments = new ArrayList<>();
39
+        int index = 0;
40
+
41
+        while (index < text.length()) {
42
+            if (index + squareSize < text.length()) {
43
+                segments.add(text.substring(index, index + squareSize));
44
+            } else {
45
+                segments.add(text.substring(index));
46
+            }
47
+            index += squareSize;
48
+        }
49
+
50
+        return segments;
51
+    }
52
+
53
+    public String getCipherText() {
54
+        StringBuilder cipherText = new StringBuilder(normalizedPlaintext.length());
55
+
56
+        for (int index = 0; index < squareSize; index++) {
57
+            for (String segment : getPlaintextSegments()) {
58
+                if (index < segment.length()) {
59
+                    cipherText.append(segment.charAt(index));
60
+                }
61
+            }
62
+        }
63
+
64
+        return cipherText.toString();
65
+    }
66
+
67
+    public String getNormalizedCipherText() {
68
+        String cipher = getCipherText();
69
+
70
+        return String.join(" ", getSegmentText(cipher, squareSize - 1));
71
+    }
72
+}

+ 0
- 0
crypto-square/src/main/java/.keep Voir le fichier


+ 2
- 0
crypto-square/src/main/java/Crypto.java Voir le fichier

@@ -0,0 +1,2 @@
1
+public class Crypto {
2
+}

+ 129
- 0
crypto-square/src/test/java/CryptoSquareTest.java Voir le fichier

@@ -0,0 +1,129 @@
1
+import org.junit.Test;
2
+
3
+import java.util.Arrays;
4
+import java.util.List;
5
+
6
+import static org.junit.Assert.assertEquals;
7
+
8
+public class CryptoSquareTest {
9
+
10
+    @Test
11
+    public void strangeCharactersAreStrippedDuringNormalization() {
12
+        Crypto crypto = new Crypto("s#$%^&plunk");
13
+        String expectedOutput = "splunk";
14
+
15
+        assertEquals(expectedOutput, crypto.getNormalizedPlaintext());
16
+    }
17
+
18
+    @Test
19
+    public void lettersAreLowerCasedDuringNormalization() {
20
+        Crypto crypto = new Crypto("WHOA HEY!");
21
+        String expectedOutput = "whoahey";
22
+
23
+        assertEquals(expectedOutput, crypto.getNormalizedPlaintext());
24
+    }
25
+
26
+    @Test
27
+    public void numbersAreKeptDuringNormalization() {
28
+        Crypto crypto = new Crypto("1, 2, 3, GO!");
29
+        String expectedOutput = "123go";
30
+
31
+        assertEquals(expectedOutput, crypto.getNormalizedPlaintext());
32
+    }
33
+
34
+    @Test
35
+    public void smallestSquareSizeIs2() {
36
+        Crypto crypto = new Crypto("1234");
37
+        int expectedOutput = 2;
38
+
39
+        assertEquals(expectedOutput, crypto.getSquareSize());
40
+    }
41
+
42
+    @Test
43
+    public void sizeOfTextWhoseLengthIsPerfectSquareIsItsSquareRoot() {
44
+        Crypto crypto = new Crypto("123456789");
45
+        int expectedOutput = 3;
46
+
47
+        assertEquals(expectedOutput, crypto.getSquareSize());
48
+    }
49
+
50
+    @Test
51
+    public void sizeOfTextWhoseLengthIsNoPerfectSquareIsNextBiggestSquareRoot() {
52
+        Crypto crypto = new Crypto("123456789abc");
53
+        int expectedOutput = 4;
54
+
55
+        assertEquals(expectedOutput, crypto.getSquareSize());
56
+    }
57
+
58
+    @Test
59
+    public void sizeIsDeterminedByNormalizedText() {
60
+        Crypto crypto = new Crypto("Oh hey, this is nuts!");
61
+        int expectedOutput = 4;
62
+
63
+        assertEquals(expectedOutput, crypto.getSquareSize());
64
+    }
65
+
66
+    @Test
67
+    public void segmentsAreSplitBySquareSize() {
68
+        Crypto crypto = new Crypto("Never vex thine heart with idle woes");
69
+        List<String> expectedOutput = Arrays.asList(new String[]{"neverv", "exthin", "eheart", "withid", "lewoes"});
70
+
71
+        assertEquals(expectedOutput, crypto.getPlaintextSegments());
72
+    }
73
+
74
+    @Test
75
+    public void segmentsAreSplitBySquareSizeUntilTextRunsOut() {
76
+        Crypto crypto = new Crypto("ZOMG! ZOMBIES!!!");
77
+        List<String> expectedOutput = Arrays.asList(new String[]{"zomg", "zomb", "ies"});
78
+
79
+        assertEquals(expectedOutput, crypto.getPlaintextSegments());
80
+    }
81
+
82
+    @Test
83
+    public void cipherTextCombinesTextByColumn() {
84
+        Crypto crypto = new Crypto("First, solve the problem. Then, write the code.");
85
+        String expectedOutput = "foeewhilpmrervrticseohtottbeedshlnte";
86
+
87
+        assertEquals(expectedOutput, crypto.getCipherText());
88
+    }
89
+
90
+    @Test
91
+    public void cipherTextSkipsCellsWithNoText() {
92
+        Crypto crypto = new Crypto("Time is an illusion. Lunchtime doubly so.");
93
+        String expectedOutput = "tasneyinicdsmiohooelntuillibsuuml";
94
+
95
+        assertEquals(expectedOutput, crypto.getCipherText());
96
+    }
97
+
98
+    @Test
99
+    public void normalizedCipherTextIsSplitByHeightOfSquare() {
100
+        Crypto crypto = new Crypto("Vampires are people too!");
101
+        String expectedOutput = "vrel aepe mset paoo irpo";
102
+
103
+        assertEquals(expectedOutput, crypto.getNormalizedCipherText());
104
+    }
105
+
106
+    @Test
107
+    public void normalizedCipherNotExactlyDivisibleBy5SpillsIntoSmallerSegment() {
108
+        Crypto crypto = new Crypto("Madness, and then illumination.");
109
+        String expectedOutput = "msemo aanin dninn dlaet ltshu i";
110
+
111
+        assertEquals(expectedOutput, crypto.getNormalizedCipherText());
112
+    }
113
+
114
+    @Test
115
+    public void normalizedCipherIsSplitIntoSegmentsOfCorrectSize() {
116
+        Crypto crypto = new Crypto("If man was meant to stay on the ground god would have given us roots");
117
+        String expectedOutput = "imtgdvs fearwer mayoogo anouuio ntnnlvt wttddes aohghns seoau";
118
+
119
+        assertEquals(expectedOutput, crypto.getNormalizedCipherText());
120
+    }
121
+
122
+    @Test
123
+    public void normalizedCipherTextIsSplitIntoSegmentsOfCorrectSizeWithPunctuation() {
124
+        Crypto crypto = new Crypto("Have a nice day. Feed the dog & chill out!");
125
+        String expectedOutput = "hifei acedl veeol eddgo aatcu nyhht";
126
+
127
+        assertEquals(expectedOutput, crypto.getNormalizedCipherText());
128
+    }
129
+}