locked
What is wrong with this code? RRS feed

  • Question

  • I am having a problem decoding this secret code.  I feel like i have everything correct except I am not getting the results I need.  If someone could take a look at it I would appreciate it.
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Data;
    using System.IO;
    
    /*Write a program that decodes secret messages read from a text file using an "alphabetic shift." So, for example, a shift might appear as:
    
    ORIGINAL ABCDE...XYZ
    SHIFTED. CDEFG...ZAB
    
    You must:
    
    1.) Read the encoded message from the attached MessageIn.txt file using StreamReader (see attached demo),
    2.) Count the instance of each character in the file,
    3.) The most common character in the message should be an "E". Use this information to calculate the amount of the shift,
    4.) Print out the decoded message.
    
    I have included test.java as an attachment which demonstrates one way a character can be assigned an index value.
    
     * On Board
     * Read encrypted MSG from File
     * Build Array w/ #occurences of each letter
     * find index of largest # in array
     * calculate shift 20-4
     * go through string and shift each letter
    */
    //HVWGWGHVSPSGHQCADIHSFSLSFQWGSWVOJSSJSFSLDSFWSBQSR
    
    
    namespace BradAssignment14
    {
        class Program
        {
            private static StreamReader inFile;  //Declares a file stream object
    
            private static int[] instanceArray = new int[26]; //number of instnaces array
    
    
            static void Main(string[] args)
            {
                string inValue;
                int index = 0;
                int shift = 0;
                string decodedMessage = "";
    
                try
                {
                    inFile = new StreamReader("MessageIn.txt");  //assumes file is in the /bin/Debug folder
    
    
                    while ((inValue = inFile.ReadLine()) != null)
                    {
                        Console.WriteLine("Original Message: " + inValue);
                        println(1);
    
                        countInstances(inValue);
                        index = largestIndex();
                        shift = calculateShift(index);
                        decodedMessage = decodeMessage(inValue, shift);
                    }
                }
    
                catch (System.IO.IOException exc)
                {
                    Console.WriteLine("ERROR");
                }
    
                printResults(index, shift, decodedMessage);
                println(3);
    
            }
    
    
            private static void printResults(int index, int shift, String decodedMessage)
            {
                Console.WriteLine("Here is the following instance array: ");
                for (int i = 0; i < instanceArray.Length; i++)
                    Console.Write(instanceArray[i] + " ");
    
                println(1);
    
                Console.WriteLine("Index with greatest # of instances: " + index);
                Console.WriteLine("Amount of shift: " + shift);
                Console.WriteLine("Decoded Message: " + decodedMessage);
    
    
            }
    
            private static String decodeMessage(String s, int shift)
            {
                String decodedMessage = "";
                String r = "";
                int newLetter = 0;
    
                for (int i = 0; i < s.Length; i++)
                {
    
                    r = s.Substring(i, 1);
    
                    switch (r)
                    {
                        case "A": newLetter = (0 - shift);
                            break;
                        case "B": newLetter = (1 - shift);
                            break;
                        case "C": newLetter = (2 - shift);
                            break;
                        case "D": newLetter = (3 - shift);
                            break;
                        case "E": newLetter = (4 - shift);
                            break;
                        case "F": newLetter = (5 - shift);
                            break;
                        case "G": newLetter = (6 - shift);
                            break;
                        case "H": newLetter = (7 - shift);
                            break;
                        case "I": newLetter = (8 - shift);
                            break;
                        case "J": newLetter = (9 - shift);
                            break;
                        case "K": newLetter = (10 - shift);
                            break;
                        case "L": newLetter = (11 - shift);
                            break;
                        case "M": newLetter = (12 - shift);
                            break;
                        case "N": newLetter = (13 - shift);
                            break;
                        case "O": newLetter = (14 - shift);
                            break;
                        case "P": newLetter = (15 - shift);
                            break;
                        case "Q": newLetter = (16 - shift);
                            break;
                        case "R": newLetter = (17 - shift);
                            break;
                        case "S": newLetter = (18 - shift);
                            break;
                        case "T": newLetter = (19 - shift);
                            break;
                        case "U": newLetter = (20 - shift);
                            break;
                        case "V": newLetter = (21 - shift);
                            break;
                        case "W": newLetter = (22 - shift);
                            break;
                        case "X": newLetter = (23 - shift);
                            break;
                        case "Y": newLetter = (24 - shift);
                            break;
                        case "Z": newLetter = (25 - shift);
                            break;
    
                    }
    
                    if (newLetter < 0)
                        newLetter = newLetter + 26;
    
                    //build decoded message
                    decodedMessage = decodedMessage + changeLetter(newLetter);
    
                }
    
                return decodedMessage;
    
            }
    
            private static String changeLetter(int spot)
            {
                String r = "";
    
                switch (spot)
                {
                    case 0: r = "A";
                        break;
                    case 1: r = "B";
                        break;
                    case 2: r = "C";
                        break;
                    case 3: r = "D";
                        break;
                    case 4: r = "E";
                        break;
                    case 5: r = "F";
                        break;
                    case 6: r = "G";
                        break;
                    case 7: r = "H";
                        break;
                    case 8: r = "I";
                        break;
                    case 9: r = "J";
                        break;
                    case 10: r = "K";
                        break;
                    case 11: r = "L";
                        break;
                    case 12: r = "M";
                        break;
                    case 13: r = "N";
                        break;
                    case 14: r = "O";
                        break;
                    case 15: r = "P";
                        break;
                    case 16: r = "Q";
                        break;
                    case 17: r = "R";
                        break;
                    case 18: r = "S";
                        break;
                    case 19: r = "T";
                        break;
                    case 20: r = "U";
                        break;
                    case 21: r = "V";
                        break;
                    case 22: r = "W";
                        break;
                    case 23: r = "X";
                        break;
                    case 24: r = "Y";
                        break;
                    case 25: r = "Z";
                        break;
                }
                return r;
            }
    
            private static int calculateShift(int index)
            {
                int shift = 0;
    
                //the most common letter is E so that is 4 subtract that from index
                shift = index - 4;
                return shift;
    
            }
    
            //find index with largest nubmer in array
            private static int largestIndex()
            {
                int largestIndex = 0;
    
                for (int i = 0; i < instanceArray.Length; i++)
                {
                    if (i == 0)
                        largestIndex = instanceArray[i];
                    else if (instanceArray[i] > largestIndex)
                        largestIndex = instanceArray[i];
    
                    if (largestIndex == instanceArray[i])
                        largestIndex = i;
                }
    
                return largestIndex;
    
            }
    
    
            //println method
            private static void println(int i)
            {
                for (int j = 0; j < i; j++)
                    Console.WriteLine();
            }
    
            //count instances of each character and increment count in the array
            private static void countInstances(String s)
            {
                String r;
    
                for (int i = 0; i < s.Length; i++)
                {
                    r = s.Substring(i, 1);
    
                    switch (r)
                    {
                        case "A": instanceArray[0] = instanceArray[0] + 1;
                            break;
                        case "B": instanceArray[1] = instanceArray[1] + 1;
                            break;
                        case "C": instanceArray[2] = instanceArray[2] + 1;
                            break;
                        case "D": instanceArray[3] = instanceArray[3] + 1;
                            break;
                        case "E": instanceArray[4] = instanceArray[4] + 1;
                            break;
                        case "F": instanceArray[5] = instanceArray[5] + 1;
                            break;
                        case "G": instanceArray[6] = instanceArray[6] + 1;
                            break;
                        case "H": instanceArray[7] = instanceArray[7] + 1;
                            break;
                        case "I": instanceArray[8] = instanceArray[8] + 1;
                            break;
                        case "J": instanceArray[9] = instanceArray[9] + 1;
                            break;
                        case "K": instanceArray[10] = instanceArray[10] + 1;
                            break;
                        case "L": instanceArray[11] = instanceArray[11] + 1;
                            break;
                        case "M": instanceArray[12] = instanceArray[12] + 1;
                            break;
                        case "N": instanceArray[13] = instanceArray[13] + 1;
                            break;
                        case "O": instanceArray[14] = instanceArray[14] + 1;
                            break;
                        case "P": instanceArray[15] = instanceArray[15] + 1;
                            break;
                        case "Q": instanceArray[16] = instanceArray[16] + 1;
                            break;
                        case "R": instanceArray[17] = instanceArray[17] + 1;
                            break;
                        case "S": instanceArray[18] = instanceArray[18] + 1;
                            break;
                        case "T": instanceArray[19] = instanceArray[19] + 1;
                            break;
                        case "U": instanceArray[20] = instanceArray[20] + 1;
                            break;
                        case "V": instanceArray[21] = instanceArray[21] + 1;
                            break;
                        case "W": instanceArray[22] = instanceArray[22] + 1;
                            break;
                        case "X": instanceArray[23] = instanceArray[23] + 1;
                            break;
                        case "Y": instanceArray[24] = instanceArray[24] + 1;
                            break;
                        case "Z": instanceArray[25] = instanceArray[25] + 1;
                            break;
    
                    }
                }
            }
        }
    }
    


    Thursday, November 15, 2012 12:50 AM

Answers

  • Greetings again.

    I've had another look, and your largestIndex method is up the creek. It's confusing the value of the largest index with the index itself.

    For example, if the letter "e" occurs 50 times, you are saving the value of 50 (so far so good), but then you overwrite that with 4 (the index of e in the array, if the shift is zero). Thus if another letter occurs 5 or more times, the method will conclude that this is more frequent than "e" which it thinks occurs 4 times.

    In order for this approach to work you must keep track of the index and its value in separate variables. Compare the values each time through the loop, and each time you get a higher one save that and its index, then return the index from the method at the end.
    • Marked as answer by bvance Monday, November 19, 2012 6:25 PM
    Thursday, November 15, 2012 2:44 AM

All replies

  • Greetings.

    I haven't gone through the whole code, but there's one rather obvious mistake in the following block.

                    while ((inValue = inFile.ReadLine()) != null)
                    {
                        Console.WriteLine("Original Message: " + inValue);
                        println(1);
    
                        countInstances(inValue);
                        index = largestIndex();
                        shift = calculateShift(index);
                        decodedMessage = decodeMessage(inValue, shift);
                    }

    What you are doing is reading a line, then counting the instances in that line, then decoding that line. This won't work unless the letter "e" is the most common on every line.

    What you should be doing is reading the whole file, then counting the instances for the whole file and decode it. So inside your while loop you should be building up a list of all the lines, then move everything after countInstances outside the loop and decode the overall result.
    Thursday, November 15, 2012 1:28 AM
  • Greetings again.

    I've had another look, and your largestIndex method is up the creek. It's confusing the value of the largest index with the index itself.

    For example, if the letter "e" occurs 50 times, you are saving the value of 50 (so far so good), but then you overwrite that with 4 (the index of e in the array, if the shift is zero). Thus if another letter occurs 5 or more times, the method will conclude that this is more frequent than "e" which it thinks occurs 4 times.

    In order for this approach to work you must keep track of the index and its value in separate variables. Compare the values each time through the loop, and each time you get a higher one save that and its index, then return the index from the method at the end.
    • Marked as answer by bvance Monday, November 19, 2012 6:25 PM
    Thursday, November 15, 2012 2:44 AM
  • I think I can't get your idea. Could you give me an example you want  or an error message you got? 
    Thursday, November 15, 2012 3:09 AM
  • Much as we shouldn't do people's homework for them you seem to have a good go at this one.  I haven't looked at your code tl;dr (respect to Ante Meridian for reading it, Aussies are good people).  I have a solution which you would not be able to hand in, I doubt that your teacher would believe that the code was your own work.

    var encrypted = new StreamReader(@"E:\MessageIn.txt").ReadLine();
    var offset = encrypted.GroupBy(l=>l)
                          .OrderByDescending (l =>l.Count ( ) )
                          .First ()
                          .Key - 'E';
    var messageOut = string.Join("", 
                 encrypted.Select(c=>(char) (
                            c-64 >= offset ? 
                                    c-offset : 
                                    c-offset+26)
                                 )
                                );

    I also have a two line version but it requires reading the file twice.

    So, what does this do?

    encrypted is just the text from the file as a string.

    offset is the number of characters between the most common letter and 'E'.

    messageOut is the decrypted string.

    offset is calculated using GroupBy which organises the sequence of letters into groups.  Each group is all the instances of each disctinct letter.  There will be as many groups as there are unique letters.  Each group will have as many members as the number of times that letter appears in the input.  Then OrderByDescending sorts those groups using the Count() of the number of members. The First() group is therefore all the copies of the most common letter in the message. The Key of this group is the most common letter. Subtracting 'E' from that letter gives us the required offset.

    MessageOut is calculated by SELECTing each character of MessageIn and either subtracting the offset from it to make a new character or sutracting the offset and adding 26 back to make the new character.  If the most common letter in the message is 'M', for example, then the offset would be 8.  Subtracting 8 from any letter between 'I' and 'Z' gives you another letter ('I' is the 9th=8+1 letter of the alphabet, subtracting 8 gets you back to 'A').  If the input letter is less than 'I' then subtracting 8 does not give you a letter, so add 26 (letters in the alphabet) to get a letter.  That is 'I' would become 'A' but 'H' should become 'Z'.

    String.Join stitches the individual char elements in to a string (with nothing between each character)

    As I said, I hope that your teacher would not believe that you had writen this code if you tried to hand it in.

    Oh, nearly forgot, the answer is

    THISISTHEBESTCOMPUTEREXERCISEIHAVEEVEREXPERIENCED

    Paul Linton

    Thursday, November 15, 2012 6:30 AM
  • Appreciate the help guys.  I marked Ante as answer even though i have not figured out what i need to do because he took the time to read my code.  I am working on it though. The directions and what i need to do are all in the comments of my code block a_neils.  When i debug the program i do not get what i am trying to get.  It seems as though it is a very small error in the syntax of my code even though the program does run.  I will rewrite using Ante suggestions. 

    Monday, November 19, 2012 6:31 PM
  • He asked what was wrong with his code idiot, he didn't ask for you to do it for him. Your code is more confusing then his. Next time just try to stay quite, we don't need more snotty people in the world.
    Friday, July 12, 2013 8:36 PM