Durante uma discussão lá no .Net Architects sobre a necessidade de faculdade mencionou-se que você aprende BubbleSort na faculdade, e fora dela talvez seja mais difícil. Pois bem, já há um artigo na Wikipedia (em inglês e em português) para quem quiser aprender, além de um monte de outras fontes. Fiquei com vontade de implementá-lo, e foi divertido. Daí tive a idéia de apresentar um kata, e como não participo de nenhum grupo de coding dojo, nada melhor do que gravar e colocar aqui no blog.
Pois bem, nesse não há musica de fundo como no outro que fiz, que foi sobre fatoriais primos. Fui fazendo e explicando. Até por isso levou um pouco mais de tempo.
Como os katas sempre são feitos com TDD, é uma boa oportunidade de ver TDD funcionando na prática também.
Fiz o vídeo em um take só, de primeira, após ter executado o algoritmo 4 vezes, então a execução está bem realista. Tive pouquíssimos esquecimentos ou errinhos ao longo do kata. Vejam o que acham, se gostarem vou seguir fazendo. Estou pensando em fazer o HeapSort também, que é um pouco mais complicado, mas talvez demore um pouco.
Aqui o link do vídeo:
Aqui o código final:
[TestFixture] public class Dado_Um_Ordenador { [Test] public void Quando_Eu_Ordeno_Uma_Lista_Vazia_Recebo_Outra_Lista_Vazia() { Assert.AreElementsEqual(new int[] { }, new int[] { }.Ordenar()); } [Test] public void Quando_Eu_Ordeno_Uma_Lista_Com_1_Recebo_Os_mesmos_Elementos() { Assert.AreElementsEqual(new [] { 1 }, new [] { 1 }.Ordenar()); } [Test] public void Quando_Eu_Ordeno_Uma_Lista_Com_1_2_Recebo_Os_mesmos_Elementos() { Assert.AreElementsEqual(new [] { 1, 2 }, new [] { 1, 2 }.Ordenar()); } [Test] public void Consigo_Ordenar_Uma_Lista_Com_2_1() { Assert.AreElementsEqual(new [] { 1, 2 }, new [] { 2, 1 }.Ordenar()); } [Test] public void Consigo_Ordenar_Uma_Lista_Com_3_2_1() { Assert.AreElementsEqual(new [] { 1, 2, 3 }, new [] { 3, 2, 1 }.Ordenar()); } [Test] public void Consigo_Ordenar_Uma_Lista_Com_4_3_2_1() { Assert.AreElementsEqual(new [] { 1, 2, 3, 4 }, new [] { 4, 3, 2, 1 }.Ordenar()); } [Test] public void Consigo_Ordenar_Uma_Lista_Com_5_4_3_2_1() { Assert.AreElementsEqual(new[] { 1, 2, 3, 4, 5 }, new[] { 5, 4, 3, 2, 1 }.Ordenar()); } [Test] public void Consigo_Ordenar_Uma_Lista_Com_30_a_1() { Assert.AreElementsEqual(1.Ate(30), 30.Ate(1).Ordenar()); } [Test] public void Consigo_Ordenar_Uma_Lista_Com_1_a_30_E_Passa_Uma_Vez_So() { Assert.AreElementsEqual(1.Ate(30), 1.Ate(30).Ordenar()); Assert.AreEqual(1, Ordenador.Passadas); } } public static class ExtensoesDeTeste { public static int[] Ate(this int numero, int ate) { var numeros = new List<int>(); if (ate > numero) for (int i = numero; i <= ate; i++) numeros.Add(i); else if (ate < numero) for (int i = numero; i >= ate; i--) numeros.Add(i); return numeros.ToArray(); } } public static class Ordenador { public static int[] Ordenar(this int[] numeros) { var length = numeros.Length; while (true) { var inverteu = false; for (int i = 0; i < length - 1; i++) { if (numeros[i] > numeros[i + 1]) { numeros.Inverter(i, i + 1); inverteu = true; } } Passadas++; if (!inverteu) break; length--; } return numeros; } public static void Inverter(this int[] numeros, int zero, int um) { Console.Write("Invertendo numero {0} (posição {1} com numero {2} (posição {3}. Array: {4}).", numeros[zero], zero, numeros[um], um, numeros.EscreverNumeros()); var numeroParaInverter = numeros[um]; numeros[um] = numeros[zero]; numeros[zero] = numeroParaInverter; Console.WriteLine("Array após inverter: {0})", numeros.EscreverNumeros()); } public static string EscreverNumeros(this int[] numeros) { var numerosTexto = "{"; foreach (var i in numeros) { numerosTexto += i + ", "; } numerosTexto = numerosTexto.Substring(0, numerosTexto.Length - 2) + "}"; return numerosTexto; } public static int Passadas { get; set; } }
Feedbacks são bem vindos, como sempre.
Giovanni Bassi
Arquiteto e desenvolvedor, agilista, escalador, provocador. É fundador e CSA da Lambda3. Programa porque gosta. Acredita que pessoas autogerenciadas funcionam melhor e por acreditar que heterarquia é mais eficiente que hierarquia. Foi reconhecido Microsoft MVP há mais de dez anos, dos mais de vinte que atua no mercado. Já palestrou sobre .NET, Rust, microsserviços, JavaScript, TypeScript, Ruby, Node.js, Frontend e Backend, Agile, etc, no Brasil, e no exterior. Liderou grupos de usuários em assuntos como arquitetura de software, Docker, e .NET.