Usando C# para resolver um desafio de entrevista da Microsoft
- #C#
- #IA Generativa
Do Desafio à Solução: Resolvendo um Problema de Entrevista com C# e IA
Como muitos entusiastas de tecnologia, eu navegava pelo YouTube quando um título me chamou a atenção: "Microsoft coding interview questions LEAKED!!". A curiosidade foi imediata. O vídeo apresentava um desafio clássico de entrevistas técnicas: como comprimir e descomprimir uma longa sequência de dígitos repetidos sem gerar uma notação ambígua?
Este artigo detalha minha jornada de raciocínio, desde a formulação de uma hipótese até a implementação de uma solução funcional em C#, um processo que foi acelerado pela colaboração com uma IA generativa.
1. O Desafio: Compressão Sem Ambiguidade
O problema pode ser resumido da seguinte forma: dada uma string numérica como 111112223333
, como representá-la de forma compacta e reversível?
Uma primeira ideia seria contar as ocorrências: "cinco 1s, três 2s, quatro 3s". Se tentássemos traduzir isso para uma notação como 513243
, criaríamos uma armadilha. Ao ler 513243
, um descompressor não saberia se isso significa "51 vezes o 3, 2 vezes o 4..." ou a nossa intenção original. A ambiguidade torna essa abordagem inviável.
2. A Hipótese: Usando Base Hexadecimal e um Separador
Minha proposta para resolver o impasse se baseou em dois pilares:
- Contagem em Base Hexadecimal (0-9, A-F): A base 16 é mais compacta que a decimal para números maiores. Por exemplo, a contagem
255
em decimal viraFF
em hexadecimal, economizando um caractere. Para programadores, a notação é familiar e de fácil conversão. - Uso de um Caractere Separador: Para eliminar a ambiguidade, um caractere não numérico e não hexadecimal (como 'n', de "n vezes") seria inserido entre a contagem e o dígito em si.
Com essa lógica, a string 111112223333
seria analisada assim:
11111
-> 5 vezes o '1' -> Contagem5
em hex é5
-> Unidade:5n1
222
-> 3 vezes o '2' -> Contagem3
em hex é3
-> Unidade:3n2
3333
-> 4 vezes o '3' -> Contagem4
em hex é4
-> Unidade:4n3
Resultado Final Comprimido: 5n13n24n3
Essa notação é inequívoca. Sempre sabemos que o que vem antes do 'n' é a contagem (em hexadecimal) e o que vem depois é o dígito que se repete.
3. Colaboração com IA: Da Ideia ao Código
Com a hipótese formulada, utilizei uma IA generativa (Gemini) para validar a abordagem e acelerar o desenvolvimento. Descrevi o problema, minha solução teórica e pedi uma implementação em C#.
A IA confirmou a viabilidade da abordagem, destacando seus pontos fortes:
- Sem Ambiguidade: O separador é a chave para uma interpretação única.
- Compacta: A contagem em hexadecimal economiza espaço.
- Escalável: A solução funciona para qualquer tamanho de sequência.
A partir daí, a IA gerou uma classe estática em C# que materializou a lógica proposta.
4. A Implementação em C#: A Classe NumericCompressor
Abaixo está o código C# final, que encapsula a lógica de compressão e descompressão. A implementação é robusta, incluindo validações para garantir que a entrada seja adequada.
C#
using System;
using System.Globalization;
using System.Text;
using System.Text.RegularExpressions;
/// <summary>
/// Fornece métodos para comprimir e descomprimir strings numéricas longas
/// usando uma abordagem Run-Length Encoding (RLE) com contagem em hexadecimal.
/// </summary>
public static class NumericCompressor
{
// O caractere que separa a contagem (em hex) do dígito.
// 'n' é usado para representar a ideia de "n vezes".
private const char SEPARATOR = 'n';
/// <summary>
/// Comprime uma string numérica longa. Exemplo: "111122" se torna "4n12n2".
/// </summary>
public static string Compress(string longNumericString)
{
if (string.IsNullOrEmpty(longNumericString) || !Regex.IsMatch(longNumericString, @"^[0-9]+$"))
{
throw new ArgumentException("A string de entrada deve ser uma sequência numérica não nula.");
}
var compressedBuilder = new StringBuilder();
int currentIndex = 0;
while (currentIndex < longNumericString.Length)
{
char currentDigit = longNumericString[currentIndex];
int count = 1;
int nextIndex = currentIndex + 1;
while (nextIndex < longNumericString.Length && longNumericString[nextIndex] == currentDigit)
{
count++;
nextIndex++;
}
// Formato: [Contagem em Hex] + 'n' + [Dígito]
compressedBuilder.Append($"{count:X}{SEPARATOR}{currentDigit}");
currentIndex = nextIndex;
}
return compressedBuilder.ToString();
}
/// <summary>
/// Descomprime uma string de volta para seu formato numérico original. Exemplo: "4n12n2" se torna "111122".
/// </summary>
public static string Decompress(string compressedString)
{
if (string.IsNullOrEmpty(compressedString))
{
throw new ArgumentException("A string de entrada não pode ser nula ou vazia.");
}
var decompressedBuilder = new StringBuilder();
// A Regex encontra todos os padrões de "[ContagemHex]n[Dígito]"
var matches = Regex.Matches(compressedString, $@"([0-9A-Fa-f]+){SEPARATOR}(\d)");
foreach (Match match in matches)
{
string hexCount = match.Groups[1].Value;
char digit = match.Groups[2].Value[0];
int count = int.Parse(hexCount, NumberStyles.HexNumber);
decompressedBuilder.Append(digit, count);
}
// Validação final para garantir que a string inteira corresponde ao padrão esperado
if (decompressedBuilder.Length > 0 && compressedString != Compress(decompressedBuilder.ToString()))
{
throw new FormatException("O formato da string comprimida é inválido.");
}
return decompressedBuilder.ToString();
}
}
5. Testando a Solução
Para verificar a funcionalidade, o seguinte código de teste foi executado, cobrindo um caso simples e um com uma contagem grande.
C# (Utilizando a versão .NET5, como pode ser visto pela explicitação da classe Program e pelo método construtor public static void Main(string[] args))
public class Program
{
public static void Main(string[] args)
{
// Exemplo 1: Sequência variada
string original1 = "111112223333";
string compressed1 = NumericCompressor.Compress(original1);
string decompressed1 = NumericCompressor.Decompress(compressed1);
Console.WriteLine("--- Exemplo 1 ---");
Console.WriteLine($"Original: {original1}");
Console.WriteLine($"Comprimido: {compressed1}"); // Saída: 5n13n24n3
Console.WriteLine($"Descomprimido: {decompressed1}");
Console.WriteLine($"Sucesso: {original1 == decompressed1}");
Console.WriteLine();
// Exemplo 2: 4095 (FFF em hex) vezes o número 2
string original2 = new string('2', 4095);
string compressed2 = NumericCompressor.Compress(original2);
string decompressed2 = NumericCompressor.Decompress(compressed2);
Console.WriteLine("--- Exemplo 2: Contagem Grande ---");
Console.WriteLine($"Original: (4095 vezes o dígito '2')");
Console.WriteLine($"Comprimido: {compressed2}"); // Saída: FFFn2
Console.WriteLine($"Descomprimido: (Comprimento: {decompressed2.Length})");
Console.WriteLine($"Sucesso: {original2 == decompressed2}");
}
}
Conclusão: Mais que uma Ferramenta, uma Parceira de Raciocínio
Esta experiência demonstra o poder da IA generativa não como uma mera "fábrica de código", mas como uma parceira no processo de resolução de problemas. A jornada começou com uma centelha de curiosidade, evoluiu para uma hipótese lógica e, com a ajuda da IA, transformou-se rapidamente em uma solução prática e testável. Este fluxo de trabalho — ideia humana, validação e aceleração por IA, e refinamento final — representa uma nova e poderosa maneira de enfrentar desafios técnicos e inovar no desenvolvimento de software.