Smartly encrypting strings I am trying to encrypt the input string using the following rule:


1st Character of string will be increment by 4 ( a will become e )
2nd Character of string will be increment by 1 ( a will become b )
3rd Character of string will be increment by 7 ( a will become h )
Rest of the characters will be replaced using the above rules.


Examples:

(Before Enc)    (After Enc)
""              ""         
"b"             "f"       
"x"             "b"     
"imagine"       "mnhkjui"
"abcdef"        "ecjhfm"
"xz"            "ba"    


I have written the following code to achieve this:

public static string Puzzle(string str) 
{
    string result = "";
    var w = s.a;
    string x = "";
    foreach (var item in str)
    {
        if (item + (int)w &gt; 122)
        {
            x += (char)(96 + ((item + (int)w) % 122));
        }
        else
        {
            x += (char)((int)w + item);
        }
        w = Convert(w);
    }
    return x;
}

enum s { a = 4, b = 1, c = 7 };

private static s Convert(s w)
{
    if (w == s.a)
    {
        w = s.b;
    }
    else if (w == s.b)
    {
        w = s.c;
    }
    else
    {
        w = s.a;
    }
    return w;
}


What I want is a better and more efficient solution than the one I have written.
Your Convert function cycles through the values 4, 1, 7. You do this by comparing the given state with each possible state, and then return the next state. This could be made much simpler by using an index rather than values. Then instead of calling Convert, we can increment the index and if necessary wrap the index around by using a modulo operation. When we need the value, we can use the index to look it up in an array that contains these values.

This would look similar to:



int[] states = {4, 1, 7};
int i = 0;

// get the value:
states[i]

// increment the index:
i = (i + 1) % states.Length;


If we really want to go overboard with this, we could define a type that represents these cyclical states:

class Cycle&lt;T&gt;
{
    private readonly T[] values;
    private int i = 0;

    public Cycle(params T[] values)
    {
        this.values = values;
    }

    public T Value
    {
        get
        {
            return values[i];
        }

    }

    public static Cycle&lt;T&gt; operator++ (Cycle&lt;T&gt; cycle)
    {
        cycle.i = (cycle.i + 1) % cycle.values.Length;
        return cycle;
    }
}


Used as:

var states = new Cycle&lt;int&gt;(4, 1, 7);

// get the value:
states.Value

// increment the index:
++states;


While using such a class makes for a very nice interface, it's not exactly the most efficient thing to do. Using an array as shown at the top is probably a good compromise between good code and performance. In particular, both of my solutions allow you to set the values of the cycle at runtime, rather than hardcoding all values in an enum.