Skip to content

Instantly share code, notes, and snippets.

@DimsFromDergachy
Last active December 12, 2025 16:30
Show Gist options
  • Select an option

  • Save DimsFromDergachy/28e501cb57557eaf070a67eac22e5e8f to your computer and use it in GitHub Desktop.

Select an option

Save DimsFromDergachy/28e501cb57557eaf070a67eac22e5e8f to your computer and use it in GitHub Desktop.
static class KeyBoard
{
internal static IEnumerable<char> UnEscape(string a)
{
// Stacks keep good indexes
var lowers = new Stack<(int, char chr)>(a.Count());
var uppers = new Stack<(int, char chr)>(a.Count());
for (int i = 0; i < a.Count(); i++)
{
var ch = a[i];
switch (ch)
{
case 'b':
lowers.TryPop(out _); break;
case 'B':
uppers.TryPop(out _); break;
case var o when char.IsLower(o):
lowers.Push((i, ch)); break;
case var o when char.IsUpper(o):
uppers.Push((i, ch)); break;
default:
throw new NotSupportedException($"Unsupported character: '{ch}'");
}
}
var result = new Stack<char>(a.Length);
while (lowers.Any() || uppers.Any())
{
if (!lowers.Any())
{
result.Push(uppers.Pop().chr); continue;
}
if (!uppers.Any())
{
result.Push(lowers.Pop().chr); continue;
}
(int i1, _) = lowers.Peek();
(int i2, _) = uppers.Peek();
if (i1 > i2)
{
result.Push(lowers.Pop().chr); continue;
}
if (i1 < i2)
{
result.Push(uppers.Pop().chr); continue;
}
throw new NotSupportedException("Broken invariant");
}
return result.ToArray();
}
}
public class KeyBoardTest
{
[Theory]
[InlineData("abcd", "cd")]
[InlineData("ABCD", "CD")]
[InlineData("abba", "a")]
[InlineData("ABBA", "A")]
[InlineData("aAbB", "")]
[InlineData("xXyYzZbB", "xXyY")]
[InlineData("xXyYBbzZ", "xXzZ")]
[InlineData("abcdefgijklmnopqrstuvwxyz", "cdefgijklmnopqrstuvwxyz")]
[InlineData("ABCDEFGIJKLMNOPQRSTUVWXYZ", "CDEFGIJKLMNOPQRSTUVWXYZ")]
public void UnEscape(string a, string e)
{
Assert.Equal(e, new string(KeyBoard.UnEscape(a).ToArray()));
}
}
@Kreator22
Copy link

На строках до 150к символов Ваше решение по абсолютной скорости проигрывает даже квадратичному.
Больше 150к символов не тестировал.

https://github.com/Kreator22/st.OtherTasks/tree/master/BrokenKeyboard
Print1 - моё решение с квадратичной скоростью в худшем случае
Print2 - моё решение с использованием стеков
Print3 - Ваше решение с использованием стеков

Сравнение скорости на произвольной строке
b и B встречаются так же часто, как и остальные символы
00:00:00.0031987 - Print1
00:00:00.0055658 - Print2
00:00:26.7634005 - Print3

Сравнение скорости для плохого случая
Треть от всех символов - b, почти все в конце строки
00:00:56.7992200 - Print1
00:00:00.0126809 - Print2
00:00:59.9919553 - Print3

@insanity13
Copy link

@Kreator22 по мотивам статьи на Habr тоже решил попробовать решить примеры
https://github.com/insanity13/sandbox/tree/main/Sandbox/Keyboard

Для строк до 20000 получил следующие результаты

Method Mean Error StdDev Gen0 Gen1 Gen2 Allocated
DimsFromDergachyVersion 5,840.082 ms 37.6586 ms 35.2259 ms 5000.0000 3000.0000 3000.0000 51.72 MB
Kreator22_1 3.766 ms 0.0239 ms 0.0223 ms 718.7500 78.1250 - 5.75 MB
Kreator22_2 6.636 ms 0.1267 ms 0.1408 ms 1937.5000 382.8125 - 15.49 MB
MySolutionVersion 1.358 ms 0.0226 ms 0.0200 ms 500.0000 37.1094 - 4 MB

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment