fork(2) download
  1. using System;
  2. using System.Text.RegularExpressions;
  3. using System.Diagnostics;
  4.  
  5. public class Test
  6. {
  7. static Regex reg = new Regex(@"\{[^\{\}]*\}", RegexOptions.Compiled);
  8. static Random rand = new Random((int)DateTime.Now.Ticks);
  9. static String[] parts;
  10.  
  11. public static void Main()
  12. {
  13. String text = "Oh! {{I'm|You're} here!|How are you{ doing{|, {buddy|pal|guy}}|}?}";
  14.  
  15. Console.WriteLine("Input Text: " + text);
  16. Console.WriteLine("Testing SpinRE: " + SpinRE(text));
  17. Console.WriteLine("Testing SpinRE: " + SpinRE(text));
  18. Console.WriteLine("Testing SpinRE: " + SpinRE(text));
  19. Console.WriteLine("Testing SpinRE: " + SpinRE(text));
  20. Console.WriteLine("Testing SpinRE: " + SpinRE(text));
  21. Console.WriteLine("Testing SpinRE: " + SpinRE(text));
  22. Console.WriteLine("Testing SpinRE: " + SpinRE(text));
  23. Console.WriteLine("Testing SpinRE: " + SpinRE(text));
  24. Console.WriteLine("Testing SpinRE: " + SpinRE(text));
  25. Console.WriteLine("Testing SpinRE: " + SpinRE(text));
  26. Console.WriteLine("Testing SpinNoRE: " + SpinNoRE(text));
  27. Console.WriteLine("Testing SpinNoRE: " + SpinNoRE(text));
  28. Console.WriteLine("Testing SpinNoRE: " + SpinNoRE(text));
  29. Console.WriteLine("Testing SpinNoRE: " + SpinNoRE(text));
  30. Console.WriteLine("Testing SpinNoRE: " + SpinNoRE(text));
  31. Console.WriteLine("Testing SpinNoRE: " + SpinNoRE(text));
  32. Console.WriteLine("Testing SpinNoRE: " + SpinNoRE(text));
  33. Console.WriteLine("Testing SpinNoRE: " + SpinNoRE(text));
  34. Console.WriteLine("Testing SpinNoRE: " + SpinNoRE(text));
  35. Console.WriteLine("Testing SpinNoRE: " + SpinNoRE(text));
  36.  
  37. Stopwatch s1 = new Stopwatch();
  38. Stopwatch s2 = new Stopwatch();
  39.  
  40. for (int i = 0; i < 100000; i++)
  41. {
  42. s1.Start(); SpinRE(text); s1.Stop();
  43. s2.Start(); SpinNoRE(text); s2.Stop();
  44. }
  45.  
  46. Console.WriteLine("\nTime elapsed over 100,000 runs of each in alternation:\n");
  47. Console.WriteLine("SpinRE: " + String.Format("{0:00}.{1:000}", s1.Elapsed.Seconds, s1.Elapsed.Milliseconds) + "s");
  48. Console.WriteLine("SpinNoRE: " + String.Format("{0:00}.{1:000}", s2.Elapsed.Seconds, s2.Elapsed.Milliseconds) + "s");
  49. }
  50.  
  51. public static String SpinRE(String text)
  52. {
  53. while (true)
  54. {
  55. Match m = reg.Match(text);
  56. if (!m.Success) break;
  57. parts = m.Value.Substring(1, m.Value.Length-2).Split('|');
  58. text = text.Substring(0, m.Index) + parts[rand.Next(parts.Length)] + text.Substring(m.Index + m.Length);
  59. }
  60. return text;
  61. }
  62.  
  63. public static String SpinNoRE(String text)
  64. {
  65. int i; // stores index of current open brace.
  66. int j; // stores index of current close brace.
  67. int e; // stores index of earliest untouched open brace.
  68.  
  69. // helpers.
  70. char[] curls = new char[] {'{', '}'};
  71.  
  72. // hack to prevent ArgumentOutOfRangeExceptions without having to check.
  73. text += '~';
  74.  
  75. // index of "earliest untouched open brace" is unknown at start.
  76. e = -1;
  77.  
  78. do
  79. {
  80. i = e;
  81. e = -1;
  82.  
  83. // loop as long as an open brace is found.
  84. while ((i = text.IndexOf('{', i+1)) != -1)
  85. {
  86. j = i;
  87.  
  88. // loop as long as a brace is found and it is not a close brace.
  89. while ((j = text.IndexOfAny(curls, j+1)) != -1 && text[j] != '}')
  90. {
  91. // means nested spintax was found; make j (the inner open
  92. // brace) the "new" i and continue search for close brace.
  93.  
  94. // nested spintax found; we're going to skip the current
  95. // open brace in favor of this new one; but remember the
  96. // index of the current open brace if it's the first such
  97. // to be skipped; make j the "new" i; continue the search.
  98. if (e == -1) e = i;
  99. i = j;
  100. }
  101.  
  102. // if close brace found, process spintax.
  103. if (j != -1)
  104. {
  105. parts = text.Substring(i+1, (j-1)-(i+1-1)).Split('|');
  106. text = text.Remove(i, j-(i-1)).Insert(i, parts[rand.Next(parts.Length)]);
  107. }
  108. }
  109. }
  110. // loop as long as an earlier untouched open brace exists (decrement e
  111. // before looping: the next loop begins its search at "i+1" == "e+1").
  112. while (e-- != -1);
  113.  
  114. // undo aforementioned hack and return.
  115. return text.Remove(text.Length-1);
  116. }
  117. }
Success #stdin #stdout 4.72s 34456KB
stdin
Standard input is empty
stdout
Input Text:       Oh! {{I'm|You're} here!|How are you{ doing{|, {buddy|pal|guy}}|}?}
Testing SpinRE:   Oh! You're here!
Testing SpinRE:   Oh! How are you doing?
Testing SpinRE:   Oh! How are you?
Testing SpinRE:   Oh! How are you doing, buddy?
Testing SpinRE:   Oh! I'm here!
Testing SpinRE:   Oh! How are you doing, guy?
Testing SpinRE:   Oh! How are you doing?
Testing SpinRE:   Oh! I'm here!
Testing SpinRE:   Oh! I'm here!
Testing SpinRE:   Oh! How are you doing?
Testing SpinNoRE: Oh! How are you doing, buddy?
Testing SpinNoRE: Oh! You're here!
Testing SpinNoRE: Oh! How are you?
Testing SpinNoRE: Oh! How are you?
Testing SpinNoRE: Oh! You're here!
Testing SpinNoRE: Oh! I'm here!
Testing SpinNoRE: Oh! How are you doing?
Testing SpinNoRE: Oh! How are you?
Testing SpinNoRE: Oh! How are you doing, buddy?
Testing SpinNoRE: Oh! I'm here!

Time elapsed over 100,000 runs of each in alternation:

SpinRE:           03.686s
SpinNoRE:         00.921s