diff --git a/conferences/2024/06-sorting/Readme.md b/conferences/2024/06-sorting/Readme.md new file mode 100644 index 0000000..de3118f --- /dev/null +++ b/conferences/2024/06-sorting/Readme.md @@ -0,0 +1,114 @@ +# Ordenación y Búsqueda + +Ordenación y búsqueda son dos de los problemas fundamentales en Ciencia de la Computación. + +## Búsqueda binaria + +Es el algoritmo de búsqueda más eficiente que se puede lograr si solo podemos comparar elementos. +La idea central es que si los elementos están ordenados, es posible descartar fácilmente hasta la mitad de los elementos haciendo una sola comparación. + +```csharp +public static int BinarySearch(int[] items, int x) +{ + int l = 0; + int r = items.Length - 1; + + while (l <= r) + { + int m = (l + r) / 2; + + if (items[m] < x) + l = m + 1; + else if (items[m] > x) + r = m - 1; + else + return m; + } + + return -1; +} +``` + + + +## Ordenación + +En última instancia, ordenar consiste en eliminar las inversiones. Una inversión es cualquier par $(i,j)$ tal que $i < j$ y $x_i > x_i$. + +## Bubble sort + +Bubble sort es un algoritmo de ordenación que funciona arreglando las inversiones una a una. + +```csharp +public static void BubbleSort(int[] array) +{ + for (int i = 0; i < array.Length; i++) + for (int j = 0; j < array.Length - 1; j++) + if (array[j] > array[j + 1]) + Swap(array, j, j + 1); +} +``` + + + +## Selection sort + +Selection sort es un algoritmo de ordenación que funciona escogiendo en todo momento el menor elemento de los que quedan por ordenar. + +```csharp +public static void SelectionSort(int[] array) +{ + for (int i = 0; i < array.Length; i++) + { + int min = i; + + for (int j = i + 1; j < array.Length; j++) + if (array[j] < array[min]) + min = j; + + Swap(array, min, i); + } +} +``` + + + +## Insertion sort + +Insertion sort es un algoritmo de ordenación que funciona en cada iteración ubicando el elemento i-ésimo en la posición que le corresponde. + +```csharp +public static void InsertionSort(int[] array) +{ + for (int i = 1; i < array.Length; i++) + { + int j = i - 1; + + while (j >= 0 && array[j] > array[j + 1]) + { + Swap(array, j, j + 1); + j = j - 1; + } + } +} +``` + + + +## Ejercicios + +1) ¿Qué sucede con `BinarySeach` cuando existen valores repetidos? Modifique el algoritmo para que en esos casos: + - a) Devuelva el índice del valor más a la izquierda. + - b) Devuelva el índice del valor más a la derecha. + +2) En `BubbleSort`, si una iteración del ciclo más interno no hace ningún intercambio, + se puede garantizar que el array está ordenado (¿Por qué?). + Modifique el algoritmo para que termine en ese caso. + + - a) En el mismo algoritmo, note que no siempre es necesario siempre llevar el ciclo más interno + hasta el final (¿Por qué?). Modifique el algoritmo en consecuencia. + +3) Modifique el método `InsertionSort` para que haga la menor cantidad de asignaciones posibles. + Hint: En el ciclo más interno, note que `Swap(j,j+1)`, siempre se intercambia con el mismo elemento. + +4) Bonus track: Modifique `BinarySearch` de forma que no necesite usar ciclos :) diff --git a/conferences/2024/06-sorting/code/sorting-examples/MatCom.Sorting.Tester/MatCom.Sorting.Tester.csproj b/conferences/2024/06-sorting/code/sorting-examples/MatCom.Sorting.Tester/MatCom.Sorting.Tester.csproj new file mode 100755 index 0000000..301fe8d --- /dev/null +++ b/conferences/2024/06-sorting/code/sorting-examples/MatCom.Sorting.Tester/MatCom.Sorting.Tester.csproj @@ -0,0 +1,14 @@ + + + + + + + + Exe + net6.0 + enable + enable + + + diff --git a/conferences/2024/06-sorting/code/sorting-examples/MatCom.Sorting.Tester/Program.cs b/conferences/2024/06-sorting/code/sorting-examples/MatCom.Sorting.Tester/Program.cs new file mode 100755 index 0000000..54d2aac --- /dev/null +++ b/conferences/2024/06-sorting/code/sorting-examples/MatCom.Sorting.Tester/Program.cs @@ -0,0 +1,54 @@ +using MatCom.Sorting; +using System.Text; + + +class Program +{ + static int[] GetRandomArray(int length) + { + Random r = new Random(); + int[] array = new int[length]; + + for (int i = 0; i < length; i++) + { + array[i] = r.Next(2 * length); + } + + return array; + } + + static string Format(int[] array) + { + StringBuilder sb = new StringBuilder("["); + + for (int i = 0; i < array.Length; i++) + { + sb.Append(array[i]); + + if (i < array.Length - 1) + sb.Append(", "); + } + + sb.Append("]"); + return sb.ToString(); + } + + static void Main() + { + for (int length = 1; length <= 1000; length = (int)(length * 2.5)) + { + Test(length, Sort.BubbleSort); + Test(length, Sort.SelectionSort); + Test(length, Sort.InsertionSort); + } + } + + static void Test(int length, Action method) + { + int[] array = GetRandomArray(length); + method(array); + + if (!Sort.IsSorted(array)) + throw new Exception(String.Format("Array {0} is not sorted!", Format(array))); + } +} \ No newline at end of file diff --git a/conferences/2024/06-sorting/code/sorting-examples/MatCom.Sorting/MatCom.Sorting.csproj b/conferences/2024/06-sorting/code/sorting-examples/MatCom.Sorting/MatCom.Sorting.csproj new file mode 100755 index 0000000..bafd05b --- /dev/null +++ b/conferences/2024/06-sorting/code/sorting-examples/MatCom.Sorting/MatCom.Sorting.csproj @@ -0,0 +1,9 @@ + + + + net6.0 + enable + enable + + + diff --git a/conferences/2024/06-sorting/code/sorting-examples/MatCom.Sorting/Sort.cs b/conferences/2024/06-sorting/code/sorting-examples/MatCom.Sorting/Sort.cs new file mode 100644 index 0000000..c862eed --- /dev/null +++ b/conferences/2024/06-sorting/code/sorting-examples/MatCom.Sorting/Sort.cs @@ -0,0 +1,96 @@ +namespace MatCom.Sorting +{ + public static class Sort + { + public static int BinarySearch(int[] items, int x) + { + int l = 0; + int r = items.Length - 1; + + while (l <= r) + { + int m = (l + r) / 2; + + if (items[m] < x) + l = m + 1; + else if (items[m] > x) + r = m - 1; + else + return m; + } + + return -1; + } + + + private static void Swap(int[] array, int a, int b) + { + int temp = array[a]; + array[a] = array[b]; + array[b] = temp; + } + + public static bool IsSorted(int[] array) + { + for (int i = 0; i < array.Length - 1; i++) + if (array[i] > array[i + 1]) + return false; + + return true; + } + + public static void BubbleSort(int[] array) + { + for (int i = 0; i < array.Length; i++) + for (int j = 0; j < array.Length - 1; j++) + if (array[j] > array[j + 1]) + Swap(array, j, j + 1); + } + + public static void SelectionSort(int[] array) + { + for (int i = 0; i < array.Length; i++) + { + int min = i; + + for (int j = i + 1; j < array.Length; j++) + if (array[j] < array[min]) + min = j; + + Swap(array, min, i); + } + } + + public static void InsertionSort(int[] array) + { + for (int i = 1; i < array.Length; i++) + { + int j = i - 1; + + while (j >= 0 && array[j] > array[j + 1]) + { + Swap(array, j, j + 1); + j = j - 1; + } + } + } + } +} + +// EJERCICIOS + +// 1. ¿Qué sucede con BinarySeach cuando existen valores repetidos? Modifique el algoritmo para que en esos casos: +// a) Devuelva el índice del valor más a la izquierda. +// b) Devuelva el índice del valor más a la derecha. + +// 2. En BubbleSort, si una iteración del ciclo más interno no hace ningún intercambio, +// se puede garantizar que el array está ordenado (¿Por qué?). +// Modifique el algoritmo para que termine en ese caso. + +// 2.1) En el mismo algoritmo, note que no siempre es necesario siempre llevar el ciclo más interno +// hasta el final (¿Por qué?). Modifique el algoritmo en consecuencia. + +// 3. Modifique el método InsertionSort para que haga la menor cantidad de asignaciones posibles. +// Hint: En el ciclo más interno, note que Swap(j,j+1), siempre se intercambia con el mismo elemento. + +// 4. Bonus track: Modifique búsqueda binaria de forma que no necesite usar ciclos :) diff --git a/conferences/2024/06-sorting/code/sorting-examples/Sorting.sln b/conferences/2024/06-sorting/code/sorting-examples/Sorting.sln new file mode 100755 index 0000000..6d4c835 --- /dev/null +++ b/conferences/2024/06-sorting/code/sorting-examples/Sorting.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MatCom.Sorting", "MatCom.Sorting\MatCom.Sorting.csproj", "{C561A49D-253E-4525-83A9-5A4AA41B25E5}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MatCom.Sorting.Tester", "MatCom.Sorting.Tester\MatCom.Sorting.Tester.csproj", "{EBB00DD5-46B6-447C-A75C-56C7A5C5E23F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C561A49D-253E-4525-83A9-5A4AA41B25E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C561A49D-253E-4525-83A9-5A4AA41B25E5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C561A49D-253E-4525-83A9-5A4AA41B25E5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C561A49D-253E-4525-83A9-5A4AA41B25E5}.Release|Any CPU.Build.0 = Release|Any CPU + {EBB00DD5-46B6-447C-A75C-56C7A5C5E23F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EBB00DD5-46B6-447C-A75C-56C7A5C5E23F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EBB00DD5-46B6-447C-A75C-56C7A5C5E23F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EBB00DD5-46B6-447C-A75C-56C7A5C5E23F}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/conferences/2024/06-sorting/code/sorting-examples/makefile b/conferences/2024/06-sorting/code/sorting-examples/makefile new file mode 100755 index 0000000..0c14539 --- /dev/null +++ b/conferences/2024/06-sorting/code/sorting-examples/makefile @@ -0,0 +1,5 @@ +test: + dotnet run --project MatCom.Sorting.Tester + +build: + dotnet build \ No newline at end of file