4
\$\begingroup\$

This was brought about by this codegolf question.

Problem

A program is said to be pristine if it is:

  1. A working program (No errors).
  2. The program will produce errors by removing any contiguous substring of N characters, where 1 <= N < program length.

My goal is to check if a given C# program's source is pristine or not with the assumption that the given program is already working.

What I Did

I generated all possible removal combinations and compiled the resulting string with CompileAssemblyFromSource. Compile errors are then checked with CompilerResults.Errors.

static bool isPristine(string sourceCode)
{
    using (var csc = new CSharpCodeProvider(new Dictionary<string, string>() { { "CompilerVersion", "v3.5" } }))
    {
        var parameters = new CompilerParameters(new[] { "mscorlib.dll", "System.Core.dll" });
        parameters.GenerateExecutable = true;

        int length = sourceCode.Length;

        for (int i = 0; i < length; i++)
        {
            for (int j = 1; j < length - i; j++)
            {
                string sourceWithRemoval = sourceCode.Remove(i, j);
                CompilerResults results = csc.CompileAssemblyFromSource(parameters, sourceWithRemoval);

                if (results.Errors.Count == 0)
                {
                    Debug.WriteLine("Still works by removing:");
                    Debug.WriteLine("@{0}@ ", sourceCode.Substring(i, j));
                    Debug.WriteLine("At index {0}.", i);

                    return false;
                }
            }
        }
    }

    return true;
}

Usage

static void Main(string[] args)
{
    string sourceCode = "class e{static void Main(){System.Console.Write(new char[1\n#if l\n#else\n*5]{'w','o','r','l','d'\n#if o\n#else\n});\n#endif\n}\n#endif\n}";

    Console.WriteLine(isPristine(sourceCode) ? "Pristine" : "Not pristine");
    Console.ReadLine();
}

Main Concerns

  • What can I improve (performance, readability)?
  • Are there better, faster C# techs that I should have used?
\$\endgroup\$
10
  • 1
    \$\begingroup\$ It never verifies if sourceCode is actually a valid program. It will return true for any number of spaces. \$\endgroup\$
    – Johnbot
    Commented Nov 10, 2015 at 12:48
  • \$\begingroup\$ I think "your" definition of pristine is not quite sufficient. Its still a bag of cack if its been formatted in a way that's unreadable. All this does is encourages people to produce polished turds. \$\endgroup\$ Commented Nov 10, 2015 at 14:53
  • \$\begingroup\$ @Johnbot Oh. Full disclosure, I did not code according to the problem statement, my intent was to make a verifier for my code-golfed program. This is "bugged" then. Delete? Or am I allowed to change my "goal"? \$\endgroup\$
    – Helix Quar
    Commented Nov 10, 2015 at 15:15
  • \$\begingroup\$ @Matt By "pristine", I do not mean C#-standard-pristine. It just so happens that "pristine" was the word chosen for this codegolf question. \$\endgroup\$
    – Helix Quar
    Commented Nov 10, 2015 at 15:18
  • \$\begingroup\$ @helix I think the question is fine as it is. Slightly changing the specification when there aren't any answers is fine. My comment is a comment and not an answer because it's knit picking details when your question makes the context absolutely clear. \$\endgroup\$
    – Johnbot
    Commented Nov 10, 2015 at 15:22

1 Answer 1

1
\$\begingroup\$

A few minors really:

  1. Standard C# naming convention for methods is PascalCase. So should be IsPristine.

  2. If it's important (or nice) to know which specific sequence is yielding the false result then you should consider returning that from the method. Something like this:

    public class PristineResult
    {
        public readonly bool IsPristine;
        public readonly string OffendingSequence;
        public readonly string OffendingIndex;
    
        public PristineResult(bool isPristine, string offendingSequence = null, int offendingIndex = -1)
        {
            IsPristine = isPristine;
            OffendingSequence = offendingSequence;
            OffendingIndex = offendingIndex;
        }
    }
    
    static PristineResult IsPristine(string sourceCode)
    {
        using (var csc = new CSharpCodeProvider(new Dictionary<string, string>() { { "CompilerVersion", "v3.5" } }))
        {
            var parameters = new CompilerParameters(new[] { "mscorlib.dll", "System.Core.dll" });
            parameters.GenerateExecutable = true;
    
            int length = sourceCode.Length;
    
            for (int i = 0; i < length; i++)
            {
                for (int j = 1; j < length - i; j++)
                {
                    string sourceWithRemoval = sourceCode.Remove(i, j);
                    CompilerResults results = csc.CompileAssemblyFromSource(parameters, sourceWithRemoval);
    
                    if (results.Errors.Count == 0)
                    {
                        return new PristineResult(false, sourceCode.Substring(i, j), i);
                    }
                }
            }
        }
    
        return new PristineResult(true);
    }     
    
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.