Skip to content

Commit f42f125

Browse files
authored
Merge pull request #16 from marcode24/2023
2023
2 parents 721cc68 + 0fcb834 commit f42f125

File tree

28 files changed

+1466
-0
lines changed

28 files changed

+1466
-0
lines changed

2023/12-es-una-copia-valida/README.md

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# Reto 12: Es una copia valida
2+
3+
## Problema
4+
5+
En el Polo Norte **todavía usan fotocopiadoras de papel.** Los elfos las usan para copiar las cartas que los niños envían a Santa y así poder enviarlas a todos los departamentos de regalos.
6+
7+
Sin embargo **ya son muy viejas y no funcionan muy bien.** Cada vez que hacen una copia, la calidad de la copia disminuye ligeramente, un fenómeno conocido como pérdida generacional.
8+
9+
**Necesitas detectar si una carta es una copia de otra.** Las cartas son muy largas y no puedes leerlas, pero puedes compararlas con un algoritmo.
10+
11+
Existe una gran **probabilidad** de que un caracter se degrade en cada copia (¡no pasa siempre!). Y al ocurrir, la regla que sigue es:
12+
13+
- Los caracteres de la A a la Z se degradan de mayúsculas a minúsculas (A-Z ⇒ a-z)
14+
- Las letras se degradan en una serie de caracteres en este orden: a-z ⇒ # ⇒ + ⇒ : ⇒ . ⇒
15+
- Una vez degradadas las letras en los símbolos, se pueden continuar degradando.
16+
- Ten en cuenta que el último es un espacio en blanco, no un caracter vacío.
17+
- Los caracteres que no son letras (como los dígitos) no se degradan.
18+
19+
Sabiendo esto y recibiendo dos cartas. La supuesta original y la copia. Debes determinar si la copia es una copia de la otra.
20+
21+
```js
22+
checkIsValidCopy(
23+
'Santa Claus is coming',
24+
'sa#ta Cl#us i+ comin#'
25+
) // true
26+
checkIsValidCopy(
27+
's#nta Cla#s is coming',
28+
'p#nt: cla#s #s c+min#'
29+
) // false (por la p inicial)
30+
checkIsValidCopy('Santa Claus', 's#+:. c:. s') // true
31+
checkIsValidCopy('Santa Claus', 's#+:.#c:. s') // false (hay un # donde no debería)
32+
```
33+
34+
Para entender cómo funcionan las fotocopiadoras y su degradación, mira este ejemplo:
35+
36+
```txt
37+
original: 'Santa Claus'
38+
1ª copia: 'santa cla#s'
39+
2ª copia: 'sa#t# cl#+s'
40+
3ª copia: 'sa+## c#+:s'
41+
4ª copia: 's#++. c+:.s'
42+
5ª copia: 's#+:. c:. s'
43+
```
44+
45+
Por lo tanto s#+:. c+:++ es una copia válida de Santa Claus. Y, como ves, la degradación de las letras no se produce en un orden específico, es aleatorio.
46+
47+
Basado en el desafío de CodeWars Photocopy decay
48+
49+
## Mi solución
50+
51+
```js
52+
function checkIsValidCopy(original, copy) {
53+
let isValidCopy = true;
54+
const symbolSequence = '#+:. ';
55+
56+
let copyIndex = 0;
57+
58+
// eslint-disable-next-line no-restricted-syntax
59+
for (const letter of original) {
60+
const copyLetter = copy[copyIndex];
61+
const symbolIndex = symbolSequence.indexOf(letter);
62+
63+
const symbols = symbolIndex !== -1
64+
? symbolSequence.slice(symbolIndex)
65+
: symbolSequence;
66+
67+
const isValidLetter = `${letter}${letter.toLowerCase()}${symbols}`
68+
.includes(copyLetter);
69+
70+
const isLetterBlankSpace = letter === ' ';
71+
const isCopyLetterBlankSpace = copyLetter === ' ';
72+
73+
const isValidCharacter = isLetterBlankSpace
74+
? isCopyLetterBlankSpace
75+
: isValidLetter;
76+
77+
if (!isValidCharacter) {
78+
isValidCopy = false;
79+
break;
80+
}
81+
82+
copyIndex++;
83+
}
84+
85+
return isValidCopy;
86+
}
87+
```

2023/12-es-una-copia-valida/index.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
function checkIsValidCopy(original, copy) {
2+
let isValidCopy = true;
3+
const symbolSequence = '#+:. ';
4+
5+
let copyIndex = 0;
6+
7+
// eslint-disable-next-line no-restricted-syntax
8+
for (const letter of original) {
9+
const copyLetter = copy[copyIndex];
10+
const symbolIndex = symbolSequence.indexOf(letter);
11+
12+
const symbols = symbolIndex !== -1
13+
? symbolSequence.slice(symbolIndex)
14+
: symbolSequence;
15+
16+
const isValidLetter = `${letter}${letter.toLowerCase()}${symbols}`
17+
.includes(copyLetter);
18+
19+
const isLetterBlankSpace = letter === ' ';
20+
const isCopyLetterBlankSpace = copyLetter === ' ';
21+
22+
const isValidCharacter = isLetterBlankSpace
23+
? isCopyLetterBlankSpace
24+
: isValidLetter;
25+
26+
if (!isValidCharacter) {
27+
isValidCopy = false;
28+
break;
29+
}
30+
31+
copyIndex++;
32+
}
33+
34+
return isValidCopy;
35+
}
36+
37+
module.exports = checkIsValidCopy;
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
const checkIsValidCopy = require('./index');
2+
3+
describe('12 => Es una copia valida', () => {
4+
const testCases = [
5+
{
6+
input: ['Santa Claus is coming', 'sa#ta Cl#us i+ comin#'],
7+
output: true,
8+
},
9+
{
10+
input: ['s#nta Cla#s is coming', 'p#nt: cla#s #s c+min#'],
11+
output: false,
12+
},
13+
{
14+
input: ['Santa Claus', 's#+:. c:. s'],
15+
output: true,
16+
},
17+
{
18+
input: ['Santa Claus', 's#+:.#c:. s'],
19+
output: false,
20+
},
21+
{
22+
input: ['s+#:.#c:. s', 's#+:.#c:. s'],
23+
output: false,
24+
},
25+
];
26+
27+
it('should return a boolean type', () => {
28+
expect(typeof checkIsValidCopy(...testCases[0].input)).toBe('boolean');
29+
});
30+
31+
it.each(testCases)('should return $output', ({ input, output }) => {
32+
expect(checkIsValidCopy(...input)).toBe(output);
33+
});
34+
});
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Reto 17: Optimizando el alquiler
2+
3+
## Problema
4+
5+
En Rovaniemi, Finlandia 🇫🇮, los trineos 🛷 se alquilan por intervalos de tiempo. **Cada intervalo se representa como un array de dos elementos,** donde el primer elemento es el inicio del alquiler y el segundo es el final.
6+
7+
Por ejemplo, el array [2, 7] representa un alquiler que comienza en la hora 2 y termina en la hora 7. El problema es que a veces los intervalos se superponen entre sí, haciendo que sea un lío entender de qué hora a qué hora se alquiló el trineo.
8+
9+
Nos piden que, para simplificar la tarea de calcular el tiempo total de alquiler, **escribamos una función que fusione todos los intervalos superpuestos y devolver un array de intervalos ordenados:**
10+
11+
```js
12+
optimizeIntervals([
13+
[5, 8],
14+
[2, 7],
15+
[3, 4]
16+
]) // [[2, 8]]
17+
18+
optimizeIntervals([
19+
[1, 3],
20+
[8, 10],
21+
[2, 6]
22+
]) // [[1, 6], [8, 10]]
23+
24+
optimizeIntervals([
25+
[3, 4],
26+
[1, 2],
27+
[5, 6]
28+
]) // [[1, 2], [3, 4], [5, 6]]
29+
```
30+
31+
Puedes asumir que **el primer elemento de cada intervalo siempre es menor o igual que el segundo elemento. Pero los intervalos no están necesariamente ordenados.**
32+
33+
Los números de horas pueden llegar hasta la cifra 9999.
34+
35+
## Mi solución
36+
37+
```js
38+
const optimizeIntervals = (intervals) => {
39+
const result = [
40+
intervals.sort((a, b) => a[0] - b[0])[0],
41+
];
42+
43+
// eslint-disable-next-line no-restricted-syntax
44+
for (const val of intervals) {
45+
const [start, end] = val;
46+
const max = result[result.length - 1][1];
47+
48+
start > max
49+
? result.push(val)
50+
: (result[result.length - 1][1] = Math.max(end, max));
51+
}
52+
53+
return result;
54+
};
55+
```
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
const optimizeIntervals = (intervals) => {
2+
const result = [
3+
intervals.sort((a, b) => a[0] - b[0])[0],
4+
];
5+
6+
// eslint-disable-next-line no-restricted-syntax
7+
for (const val of intervals) {
8+
const [start, end] = val;
9+
const max = result[result.length - 1][1];
10+
11+
start > max
12+
? result.push(val)
13+
: (result[result.length - 1][1] = Math.max(end, max));
14+
}
15+
16+
return result;
17+
};
18+
19+
module.exports = optimizeIntervals;
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
const optimizeIntervals = require('./index');
2+
3+
describe('17 => Optimizando el alquiler', () => {
4+
const testCases = [
5+
{
6+
input: [
7+
[5, 8],
8+
[2, 7],
9+
[3, 4],
10+
],
11+
output: [[2, 8]],
12+
},
13+
{
14+
input: [
15+
[1, 3],
16+
[8, 10],
17+
[2, 6],
18+
],
19+
output: [[1, 6], [8, 10]],
20+
},
21+
{
22+
input: [
23+
[3, 4],
24+
[1, 2],
25+
[5, 6],
26+
],
27+
output: [[1, 2], [3, 4], [5, 6]],
28+
},
29+
];
30+
31+
it('should return an array type', () => {
32+
expect(Array.isArray(optimizeIntervals([...testCases[0].input]))).toBe(true);
33+
});
34+
35+
it.each(testCases)('should return the correct output', (testCase) => {
36+
expect(optimizeIntervals([...testCase.input])).toEqual(testCase.output);
37+
});
38+
});

2023/18-el-reloj-digital/README.md

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# Reto 18: El reloj digital
2+
3+
## Problema
4+
5+
En la fábrica de juguetes, los elfos están programando un reloj digital para mantenerse en horario con la producción de regalos. Sin embargo, se han encontrado con un desafío de programación interesante. Necesitan una función que, dada una hora en formato 'HH:MM', cree una representación visual de esta hora en un reloj digital devolviendo un array de arrays de caracteres.
6+
7+
La pantalla del reloj tiene 7 filas y 17 columnas, y cada dígito de la hora ocupa 7 filas y 3 columnas. Los dígitos están compuestos por asteriscos (*) y espacios en blanco (). Entre cada dígito hay una columna vacía.
8+
9+
Los dos puntos para separar horas y minutos se dibujan usando dos asteríscos (*) y siempre se colocan en la misma posición, en las filas 2 y 4, en la columna 9, respectivamente (nota: la indexación de filas y columnas comienza en 0).
10+
11+
Por ejemplo, si la función recibe 01:30 debe devolver:
12+
13+
drawClock('01:30') // ⬇️
14+
15+
[
16+
['*', '*', '*', ' ', ' ', ' ', '*', ' ', ' ', ' ', '*', '*', '*', ' ', '*', '*', '*'],
17+
['*', ' ', '*', ' ', ' ', ' ', '*', ' ', ' ', ' ', ' ', ' ', '*', ' ', '*', ' ', '*'],
18+
['*', ' ', '*', ' ', ' ', ' ', '*', ' ', '*', ' ', ' ', ' ', '*', ' ', '*', ' ', '*'],
19+
['*', ' ', '*', ' ', ' ', ' ', '*', ' ', ' ', ' ', '*', '*', '*', ' ', '*', ' ', '*'],
20+
['*', ' ', '*', ' ', ' ', ' ', '*', ' ', '*', ' ', ' ', ' ', '*', ' ', '*', ' ', '*'],
21+
['*', ' ', '*', ' ', ' ', ' ', '*', ' ', ' ', ' ', ' ', ' ', '*', ' ', '*', ' ', '*'],
22+
['*', '*', '*', ' ', ' ', ' ', '*', ' ', ' ', ' ', '*', '*', '*', ' ', '*', '*', '*']
23+
]
24+
Para saber cómo dibujar cada dígito, nos han pasado la siguiente imagen. Como ves, cada dígito está compuesto por 7 filas y 3 columnas. Los píxeles en rojo, nosotros lo representaremos con un asterisco (*), y los píxeles en blanco, con un espacio ():
25+
26+
Representación de los dígitos para el reloj digital del 1 al 9, donde puedes ver lo que ocupa en píxeles cada número
27+
28+
## Mi solución
29+
30+
```js
31+
function drawClock(time) {
32+
const digitPatterns = {
33+
0: ['***', '* *', '* *', '* *', '* *', '* *', '***'],
34+
1: [' *', ' *', ' *', ' *', ' *', ' *', ' *'],
35+
2: ['***', ' *', ' *', '***', '* ', '* ', '***'],
36+
3: ['***', ' *', ' *', '***', ' *', ' *', '***'],
37+
4: ['* *', '* *', '* *', '***', ' *', ' *', ' *'],
38+
5: ['***', '* ', '* ', '***', ' *', ' *', '***'],
39+
6: ['***', '* ', '* ', '***', '* *', '* *', '***'],
40+
7: ['***', ' *', ' *', ' *', ' *', ' *', ' *'],
41+
8: ['***', '* *', '* *', '***', '* *', '* *', '***'],
42+
9: ['***', '* *', '* *', '***', ' *', ' *', '***'],
43+
':': [' ', ' ', '*', ' ', '*', ' ', ' '],
44+
};
45+
46+
const firstDigitPattern = digitPatterns[time[0]];
47+
const secondDigitPattern = digitPatterns[time[1]];
48+
const colonPattern = digitPatterns[':'];
49+
const thirdDigitPattern = digitPatterns[time[3]];
50+
const fourthDigitPattern = digitPatterns[time[4]];
51+
52+
const result = [...firstDigitPattern];
53+
let position = 0;
54+
55+
// eslint-disable-next-line no-restricted-syntax
56+
for (const row of result) {
57+
const rowString = `${row} ${secondDigitPattern[position]} `
58+
+ `${colonPattern[position]} ${thirdDigitPattern[position]} `
59+
+ `${fourthDigitPattern[position]}`;
60+
result[position] = [...rowString];
61+
position++;
62+
}
63+
64+
return result;
65+
}
66+
```

2023/18-el-reloj-digital/index.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
function drawClock(time) {
2+
const digitPatterns = {
3+
0: ['***', '* *', '* *', '* *', '* *', '* *', '***'],
4+
1: [' *', ' *', ' *', ' *', ' *', ' *', ' *'],
5+
2: ['***', ' *', ' *', '***', '* ', '* ', '***'],
6+
3: ['***', ' *', ' *', '***', ' *', ' *', '***'],
7+
4: ['* *', '* *', '* *', '***', ' *', ' *', ' *'],
8+
5: ['***', '* ', '* ', '***', ' *', ' *', '***'],
9+
6: ['***', '* ', '* ', '***', '* *', '* *', '***'],
10+
7: ['***', ' *', ' *', ' *', ' *', ' *', ' *'],
11+
8: ['***', '* *', '* *', '***', '* *', '* *', '***'],
12+
9: ['***', '* *', '* *', '***', ' *', ' *', '***'],
13+
':': [' ', ' ', '*', ' ', '*', ' ', ' '],
14+
};
15+
16+
const firstDigitPattern = digitPatterns[time[0]];
17+
const secondDigitPattern = digitPatterns[time[1]];
18+
const colonPattern = digitPatterns[':'];
19+
const thirdDigitPattern = digitPatterns[time[3]];
20+
const fourthDigitPattern = digitPatterns[time[4]];
21+
22+
const result = [...firstDigitPattern];
23+
let position = 0;
24+
25+
// eslint-disable-next-line no-restricted-syntax
26+
for (const row of result) {
27+
const rowString = `${row} ${secondDigitPattern[position]} `
28+
+ `${colonPattern[position]} ${thirdDigitPattern[position]} `
29+
+ `${fourthDigitPattern[position]}`;
30+
result[position] = [...rowString];
31+
position++;
32+
}
33+
34+
return result;
35+
}
36+
37+
module.exports = drawClock;

0 commit comments

Comments
 (0)