import java.util.ArrayList; import java.util.List; /** * @author Arran Stewart * */ public class Message { /** If you work out the correct deck order to use * when decrypting the message -- the "deck string" * (comma-separated values which can be used to re-create * a Deck object in that order) should be stored in this * instance variable. */ private String deckString; /** If you work out what the decrypted message is -- * it should be stored in this instance variable */ private String decryptedText; /** The encrypted message you find. */ public final static String encryptedText = "DGNKAJBQKCGBOOYHCINCKDDXXIZVYLDFFKNXDZZAQFRNNRGBSMASCE"; /** The partial card deck ordering you find -- with one * card missing. */ public final static int partialDeck[] = { 8, 48, 52, 13, 14, 47, 18, 19, 20, 11, 2, 25, 26, 27, 28, 29, 23, 32, 9, 53, 17, 12, 15, 1, 30, 31, 33, 34, 24, 35, 21, 22, 3, 4, 16, 41, 54, 36, 37, 38, 50, 42, 43, 44, 45, 46, 40, 51, 49, 5, 6, 7, 10 }; /** Return the "deck string" -- when used to * construct a Deck object, this string should * produce a Deck with its cards in * the correct order for decrypting the message contained * in "encryptedText". * * @return Returns a string that can be passed to Deck(String inputString). */ public String getDeckString() { return deckString; } /** Return the "decrypted text" -- this should be the result * of decrypting the message in "encryptedText". * * @return Returns the decrypted text */ public String getDecodedMessage() { return decryptedText; } /** Join values in an array into a comma-separated string. * Part of SOLUTION */ private static String joinArray(int[] arr) { List list = new ArrayList<>(); for (int i : arr) { list.add( "" + i ); } return String.join(",", list); } /** Given a position at which the missing card (the King of * Hearts) could be, this method returns a String which * can be used to construct a Deck with the King at that * position. * * @param kingPos A possible position for the King of Hearts * @return A String which can be used to initialize a Deck */ public String tryPosition(int kingPos) { final int kingVal = 39; String partialDeckString = joinArray(partialDeck); String[] strings = partialDeckString.split(","); ArrayList strLst = new ArrayList<>(); for(int sIdx = 0; sIdx < strings.length; sIdx++) { if (sIdx == kingPos) { strLst.add("" + kingVal); } strLst.add(strings[sIdx]); } String rejoined = String.join(",", strLst); return rejoined; } /* Devise code for a constructor which will test * various positions at which the missing card * (the King of Hearts) could be, calling tryPosition() * to obtain a "deck string" for that position. * * You will then need to find out which of those * deck orderings correctly decrypts the message. * (Hint: use the debugger to view the decryption results). * When the correct position for the King is found, * the constructor should store the decrypted message in * the "decryptedText" instance variable, and the "deck string" in the * "deckString" instance variable. */ public Message() { String partialDeckString = joinArray(partialDeck); String[] strings = partialDeckString.split(","); // try inserting 39 at each point // king of hearts for(int kingPos = 0; kingPos < strings.length; kingPos++) { String deckString = tryPosition(kingPos); Deck d = new Deck(deckString); Encoder e = new Encoder(d); String result = e.decrypt(encryptedText); if (result.startsWith("THEMAPONTHE") ) { this.decryptedText = result; // make a deck string this.deckString = deckString; } } } }