Esta serie mantiene la mente fresca resolviendo, uno a uno, los ejercicios de HackerRank. Cada entrada toma un tema concreto y lo agota; todas las consultas están en MySQL salvo donde se indique.
Te invito a intentar cada ejercicio antes de leer la solución.
Aquí SQL deja de parecer SQL: dos ejercicios dibujan patrones con variables y bucles en SQL Server, uno recorre los primos hasta 1000, y el último vuelve a MySQL para clasificar triángulos con CASE WHEN.
Triangle
Draw The Triangle 1
P(R) represents a pattern drawn by Julia in R rows. The following pattern represents P(5):
* * * * *
* * * *
* * *
* *
*Write a query to print the pattern P(20).
Solución
En este caso usaremos Sql Server para poder resolver esto de forma mas cómoda, aparte que también me toco aprender sobre esto. En este caso es solamente verlo como si lo hubiéramos solucionado en algún lenguaje de programación como python, por ejemplo, para declarar una variable podemos usar DECLARE @i INT y ahora sabemos que @i es una variable de tipo INT la cual vale 20, nosotros queremos que imprimía inicialmente los 20 asteriscos y se reduzca -1 (n-1) asterisco cada vez que hace un recorrido hasta llegar a 0 donde acaba el bucle.
SET NOCOUNT ON;
DECLARE @i INT = 20;
WHILE @i > 0
BEGIN
PRINT REPLICATE('* ', @i);
SET @i = @i - 1;
END
goDraw The Triangle 2
P(R) represents a pattern drawn by Julia in R rows. The following pattern represents P(5):
*
* *
* * *
* * * *
* * * * *Write a query to print the pattern P(20).
Solución
Esto seria lo mismo pero de forma invertida.
SET NOCOUNT ON;
DECLARE @i INT = 1;
WHILE @i <= 20
BEGIN
PRINT REPLICATE('* ', @i);
SET @i = @i + 1;
END
goPrint Prime Numbers
Write a query to print all prime numbers less than or equal to 1000. Print your result on a single line, and use the ampersand (&) character as your separator (instead of a space).
For example, the output for all prime numbers ≤ 10 would be:
2&3&5&7
Solución
SET NOCOUNT ON;
DECLARE @i INT = 1000;
WHILE @i <= 1000
BEGIN
IF(@i % 2 = 0)
BEGIN
SET @Prime = @Prime + CAST(@i AS VARCHAR) + '&';
END
SET @i = @i + 1;
END
PRINT @Prime
goType of Triangle
Write a query identifying the type of each record in the TRIANGLES table using its three side lengths. Output one of the following statements for each record in the table:
- Equilateral: It's a triangle with 3 sides of equal length.
- Isosceles: It's a triangle with 2 sides of equal length.
- Scalene: It's a triangle with 3 sides of differing lengths.
- Not A Triangle: The given values of A, B, and C don't form a triangle.
Input Format
The TRIANGLES table is described as follows:
| Column | Type |
|---|---|
| A | INTEGER |
| B | INTEGER |
| C | INTEGER |
Each row in the table denotes the lengths of each of a triangle's three sides.
Sample Input
| A | B | C |
|---|---|---|
| 20 | 20 | 23 |
| 20 | 20 | 20 |
| 20 | 21 | 22 |
| 13 | 14 | 30 |
Sample Output
Isosceles
Equilateral
Scalene
Not A TriangleExplanation
Values in the tuple (20, 20, 23) form an Isosceles triangle, because A ≡ B. Values in the tuple (20, 20, 20) form an Equilateral triangle, because A ≡ B ≡ C. Values in the tuple (20, 21, 22) form a Scalene triangle, because A ≠ B ≠ C. Values in the tuple (13, 14, 30) cannot form a triangle because the combined value of sides A and B is not larger than that of side C.
Solución
Debemos clasificar cada registro de la tabla TRIANGLES en una de las cuatro categorías posibles. A simple vista parece un ejercicio sencillo de condicionales, pero tiene una trampa lógica muy común: el orden de las condiciones en un CASE WHEN es vital.
Si te fijas en la explicación del ejercicio, el último caso es el de . Si evaluamos primero si es un triángulo escaleno (todos los lados diferentes), esta tupla cumpliría la condición porque . Sin embargo, no es un triángulo.
Para que esto no pase, siempre debemos evaluar primero si es un triángulo válido. La regla matemática (Teorema de la desigualdad triangular) dice que la suma de dos lados debe ser siempre mayor al tercer lado (, , ). Si alguna de estas sumas es menor o igual, no es un triángulo.
Entonces, el orden lógico dentro del CASE WHEN debe ser:
- Not A Triangle: Si o o .
- Equilateral: Si y .
- Isosceles: Si o o .
- Scalene: Si no cumplió ninguna de las anteriores (usando ELSE).
Usamos la sintaxis de CASE WHEN dentro del SELECT, asignándole un alias como output para que el resultado sea solo el texto de la clasificación.
SELECT
CASE
WHEN A + B <= C OR A + C <= B OR B + C <= A THEN "Not A Triangle"
WHEN A = B AND B = C THEN "Equilateral"
WHEN A = B OR B = C OR A = C THEN "Isosceles"
ELSE "Scalene"
END AS output
FROM TRIANGLES