fork 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. Console.WriteLine("Testing SpinSergey: " + SpinSergey(text));
  37. Console.WriteLine("Testing SpinSergey: " + SpinSergey(text));
  38. Console.WriteLine("Testing SpinSergey: " + SpinSergey(text));
  39. Console.WriteLine("Testing SpinSergey: " + SpinSergey(text));
  40. Console.WriteLine("Testing SpinSergey: " + SpinSergey(text));
  41. Console.WriteLine("Testing SpinSergey: " + SpinSergey(text));
  42. Console.WriteLine("Testing SpinSergey: " + SpinSergey(text));
  43. Console.WriteLine("Testing SpinSergey: " + SpinSergey(text));
  44. Console.WriteLine("Testing SpinSergey: " + SpinSergey(text));
  45. Console.WriteLine("Testing SpinSergey: " + SpinSergey(text));
  46.  
  47. Stopwatch s1 = new Stopwatch();
  48. Stopwatch s2 = new Stopwatch();
  49. Stopwatch s3 = new Stopwatch();
  50.  
  51. for (int i = 0; i < 100000; i++)
  52. {
  53. s1.Start(); SpinRE(text); s1.Stop();
  54. s2.Start(); SpinNoRE(text); s2.Stop();
  55. s3.Start(); SpinSergey(text); s3.Stop();
  56. }
  57.  
  58. Console.WriteLine("\nTime elapsed over 100,000 runs of each in alternation:\n");
  59. Console.WriteLine("SpinRE: " + String.Format("{0:00}.{1:000}", s1.Elapsed.Seconds, s1.Elapsed.Milliseconds) + "s");
  60. Console.WriteLine("SpinNoRE: " + String.Format("{0:00}.{1:000}", s2.Elapsed.Seconds, s2.Elapsed.Milliseconds) + "s");
  61. Console.WriteLine("SpinSergey: " + String.Format("{0:00}.{1:000}", s3.Elapsed.Seconds, s3.Elapsed.Milliseconds) + "s");
  62. }
  63.  
  64. public static String SpinRE(String text)
  65. {
  66. while (true)
  67. {
  68. Match m = reg.Match(text);
  69. if (!m.Success) break;
  70. parts = m.Value.Substring(1, m.Value.Length-2).Split('|');
  71. text = text.Substring(0, m.Index) + parts[rand.Next(parts.Length)] + text.Substring(m.Index + m.Length);
  72. }
  73. return text;
  74. }
  75.  
  76. public static String SpinNoRE(String text)
  77. {
  78. int i; // stores index of current open brace.
  79. int j; // stores index of current close brace.
  80. int e; // stores index of earliest untouched open brace.
  81.  
  82. // helpers.
  83. char[] curls = new char[] {'{', '}'};
  84.  
  85. // hack to prevent ArgumentOutOfRangeExceptions without having to check.
  86. text += '~';
  87.  
  88. // index of "earliest untouched open brace" is unknown at start.
  89. e = -1;
  90.  
  91. do
  92. {
  93. i = e;
  94. e = -1;
  95.  
  96. // loop as long as an open brace is found.
  97. while ((i = text.IndexOf('{', i+1)) != -1)
  98. {
  99. j = i;
  100.  
  101. // loop as long as a brace is found and it is not a close brace.
  102. while ((j = text.IndexOfAny(curls, j+1)) != -1 && text[j] != '}')
  103. {
  104. // means nested spintax was found; make j (the inner open
  105. // brace) the "new" i and continue search for close brace.
  106.  
  107. // nested spintax found; we're going to skip the current
  108. // open brace in favor of this new one; but remember the
  109. // index of the current open brace if it's the first such
  110. // to be skipped; make j the "new" i; continue the search.
  111. if (e == -1) e = i;
  112. i = j;
  113. }
  114.  
  115. // if close brace found, process spintax.
  116. if (j != -1)
  117. {
  118. parts = text.Substring(i+1, (j-1)-(i+1-1)).Split('|');
  119. text = text.Remove(i, j-(i-1)).Insert(i, parts[rand.Next(parts.Length)]);
  120. }
  121. }
  122. }
  123. // loop as long as an earlier untouched open brace exists (decrement e
  124. // before looping: the next loop begins its search at "i+1" == "e+1").
  125. while (e-- != -1);
  126.  
  127. // undo aforementioned hack and return.
  128. return text.Remove(text.Length-1);
  129. }
  130.  
  131. // @SergeyS's code:
  132.  
  133. static int[] partIndices = new int[100];
  134. static int[] depth = new int[100];
  135. static char[] symbolsOfTextProcessed = new char[100000];
  136.  
  137. public static String SpinSergey(String text)
  138. {
  139. int cur = SpinEvenMoreFasterInner(text, 0, text.Length, 0);
  140. return new String(symbolsOfTextProcessed, 0, cur);
  141. }
  142.  
  143. public static int SpinEvenMoreFasterInner(String text, int start, int end, int symbolIndex)
  144. {
  145. int last = start;
  146. for (int i = start; i < end; i++)
  147. {
  148. if (text[i] == '{')
  149. {
  150. int k = 1;
  151. int j = i + 1;
  152. int index = 0;
  153. partIndices[0] = i;
  154. depth[0] = 1;
  155. for (; j < end && k > 0; j++)
  156. {
  157. if (text[j] == '{')
  158. k++;
  159. else if (text[j] == '}')
  160. k--;
  161. else if (text[j] == '|')
  162. {
  163. if (k == 1)
  164. {
  165. partIndices[++index] = j;
  166. depth[index] = 1;
  167. }
  168. else
  169. depth[index] = k;
  170. }
  171. }
  172. if (k == 0)
  173. {
  174. partIndices[++index] = j - 1;
  175. int part = rand.Next(index);
  176. text.CopyTo(last, symbolsOfTextProcessed, symbolIndex, i - last);
  177. symbolIndex += i - last;
  178. if (depth[part] == 1)
  179. {
  180. text.CopyTo(partIndices[part] + 1, symbolsOfTextProcessed, symbolIndex, partIndices[part + 1] - partIndices[part] - 1);
  181. symbolIndex += partIndices[part + 1] - partIndices[part] - 1;
  182. }
  183. else
  184. {
  185. symbolIndex = SpinEvenMoreFasterInner(text, partIndices[part] + 1, partIndices[part + 1], symbolIndex);
  186. }
  187. i = j - 1;
  188. last = j;
  189. }
  190. }
  191. }
  192. text.CopyTo(last, symbolsOfTextProcessed, symbolIndex, end - last);
  193. return symbolIndex + end - last;
  194. }
  195. }
Success #stdin #stdout 4.9s 34664KB
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! You're here!
Testing SpinRE:     Oh! How are you?
Testing SpinRE:     Oh! How are you?
Testing SpinRE:     Oh! How are you?
Testing SpinRE:     Oh! How are you?
Testing SpinRE:     Oh! How are you?
Testing SpinRE:     Oh! You're here!
Testing SpinRE:     Oh! I'm here!
Testing SpinRE:     Oh! How are you?
Testing SpinNoRE:   Oh! I'm here!
Testing SpinNoRE:   Oh! You're here!
Testing SpinNoRE:   Oh! I'm here!
Testing SpinNoRE:   Oh! How are you?
Testing SpinNoRE:   Oh! How are you doing?
Testing SpinNoRE:   Oh! You're here!
Testing SpinNoRE:   Oh! How are you?
Testing SpinNoRE:   Oh! How are you doing?
Testing SpinNoRE:   Oh! How are you doing, buddy?
Testing SpinNoRE:   Oh! How are you doing, pal?
Testing SpinSergey: Oh! You're here!
Testing SpinSergey: Oh! I'm here!
Testing SpinSergey: Oh! I'm here!
Testing SpinSergey: Oh! You're here!
Testing SpinSergey: Oh! I'm here!
Testing SpinSergey: Oh! I'm here!
Testing SpinSergey: Oh! I'm here!
Testing SpinSergey: Oh! I'm here!
Testing SpinSergey: Oh! How are you?
Testing SpinSergey: Oh! You're here!

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

SpinRE:           03.760s
SpinNoRE:         00.795s
SpinSergey:       00.148s