Skip to content

Instantly share code, notes, and snippets.

@DimsFromDergachy
Last active January 11, 2026 12:08
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()));
}
}
@mychka
Copy link

mychka commented Jan 11, 2026

Классическое решение (аналогично MySolutionVersion):

public static String getTypedString(String keystrokes) {
    StringBuilder result = new StringBuilder();
    int skipLower = 0;
    int skipUpper = 0;

    // Process the string in reverse
    for (int i = keystrokes.length() - 1; i >= 0; i--) {
        char c = keystrokes.charAt(i);
        if (c == 'b') {
            skipLower++;
        } else if (c == 'B') {
            skipUpper++;
        } else if (Character.isLowerCase(c)) {
            if (skipLower > 0) {
                skipLower--;
            } else {
                result.append(c);
            }
        } else { // Uppercase letter
            if (skipUpper > 0) {
                skipUpper--;
            } else {
                result.append(c);
            }
        }
    }

    // Reverse to get the original order
    return result.reverse().toString();
}

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