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:
BubbleSort Kata
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.
Postado na(s) categoria(s)
Kata
pelo
Giovanni Bassi em 7 de dezembro de 2009 às 02:03
| Tags:
c#,
testes,
tdd,
webcast
fbca84f3-0974-4853-8f2e-07b067c6ab3b|1|5.0