Skip to content

Commit 721cc68

Browse files
authored
Merge pull request #15 from marcode24/2023
✨ add challenge-11 solution
2 parents 9af3ee2 + 529b4ac commit 721cc68

File tree

15 files changed

+671
-0
lines changed

15 files changed

+671
-0
lines changed
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Reto 11: Los elfos estudiosos
2+
3+
## Problema
4+
5+
En el taller de Santa, los elfos aman los acertijos 🧠. Este año, han creado uno especial: un desafío para formar un palíndromo navideño.
6+
7+
**Un palíndromo es una palabra que se lee igual hacia adelante y hacia atrás.** Los elfos quieren saber si es posible formar un palíndromo haciendo, como mucho, un intercambio de letras.
8+
9+
Crea una función `getIndexsForPalindrome` que reciba una cadena de caracteres y devolverá:
10+
11+
- Si ya es un palíndromo, un array vacío.
12+
- Si no es posible, null.
13+
- Si se puede formar un palíndromo con un cambio, un array con las dos posiciones (índices) que se deben intercambiar para poder crearlo.
14+
15+
Por ejemplo:
16+
17+
```js
18+
getIndexsForPalindrome('anna') // []
19+
getIndexsForPalindrome('abab') // [0, 1]
20+
getIndexsForPalindrome('abac') // null
21+
getIndexsForPalindrome('aaaaaaaa') // []
22+
getIndexsForPalindrome('aaababa') // [1, 3]
23+
getIndexsForPalindrome('caababa') // null``
24+
```
25+
26+
Si se puede formar el palíndromo con diferentes intercambios, **siempre se debe devolver el primero que se encuentre.**
27+
28+
## Mi solución
29+
30+
```js
31+
function getIndexsForPalindrome(word) {
32+
const wordLength = word.length;
33+
const isPalindrome = (str) => str === [...str].reverse().join('');
34+
35+
if (isPalindrome(word)) return [];
36+
37+
for (let i = 0; i < wordLength; i++) {
38+
for (let j = i + 1; j < wordLength; j++) {
39+
const newWord = [...word];
40+
[newWord[i], newWord[j]] = [newWord[j], newWord[i]];
41+
42+
if (newWord.join('') === newWord.reverse().join('')) {
43+
return [i, j];
44+
}
45+
}
46+
}
47+
48+
return null;
49+
}
50+
```

2023/11-los-elfos-estudiosos/index.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
function getIndexsForPalindrome(word) {
2+
const wordLength = word.length;
3+
const isPalindrome = (str) => str === [...str].reverse().join('');
4+
5+
if (isPalindrome(word)) return [];
6+
7+
for (let i = 0; i < wordLength; i++) {
8+
for (let j = i + 1; j < wordLength; j++) {
9+
const newWord = [...word];
10+
[newWord[i], newWord[j]] = [newWord[j], newWord[i]];
11+
12+
if (newWord.join('') === newWord.reverse().join('')) {
13+
return [i, j];
14+
}
15+
}
16+
}
17+
18+
return null;
19+
}
20+
21+
module.exports = getIndexsForPalindrome;
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
const getIndexsForPalindrome = require('./index');
2+
3+
describe('11 => Los elfos estudiosos', () => {
4+
const testCases = [
5+
{
6+
input: 'anna',
7+
output: [],
8+
},
9+
{
10+
input: 'abab',
11+
output: [0, 1],
12+
},
13+
{
14+
input: 'abac',
15+
output: null,
16+
},
17+
{
18+
input: 'aaaaaaaa',
19+
output: [],
20+
},
21+
{
22+
input: 'aaababa',
23+
output: [1, 3],
24+
},
25+
{
26+
input: 'caababa',
27+
output: null,
28+
},
29+
];
30+
31+
it('should return an array type if the input is a palindrome', () => {
32+
expect(getIndexsForPalindrome('abab')).toEqual([0, 1]);
33+
});
34+
35+
it('should return null type if the input could not be a palindrome', () => {
36+
expect(getIndexsForPalindrome('abac')).toBeNull();
37+
});
38+
39+
it.each(testCases)('should return $output', ({ input, output }) => {
40+
expect(getIndexsForPalindrome(input)).toEqual(output);
41+
});
42+
});
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Reto 13: Calculando el tiempo
2+
3+
## Problema
4+
5+
Los elfos están preparando **la víspera de Navidad** y necesitan tu ayuda para calcular si van sobrados o no de tiempo ⏳.
6+
7+
Para ello te pasan un array con la duración de cada entrega. El formato de la duración es HH:mm:ss, las entregas empiezan a las 00:00:00 y el límite de tiempo es 07:00:00.
8+
9+
**Tu función debe devolver el tiempo que les faltará o el tiempo que les sobrará** para terminar las entregas. El formato de la duración devuelta debe ser HH:mm:ss.
10+
11+
Si terminan antes de las 07:00:00, el tiempo restante hasta las 07:00:00 debe ser mostrado con un signo negativo. Por ejemplo, **si sobran 1 hora y 30 minutos, devuelve -01:30:00**
12+
13+
```js
14+
calculateTime(['00:10:00', '01:00:00', '03:30:00'])
15+
// '-02:20:00'
16+
17+
calculateTime(['02:00:00', '05:00:00', '00:30:00'])
18+
// '00:30:00'
19+
20+
calculateTime([
21+
'00:45:00',
22+
'00:45:00',
23+
'00:00:30',
24+
'00:00:30'
25+
]) // '-05:29:00'
26+
```
27+
28+
## Mi solución
29+
30+
```js
31+
function calculateTime(deliveries) {
32+
const deliveryLimit = 7 * 3600; // Límite de tiempo en segundos (7 horas)
33+
let totalSeconds = 0;
34+
35+
// eslint-disable-next-line no-restricted-syntax
36+
for (const time of deliveries) {
37+
const [hours, minutes, seconds] = time.split(':').map(Number);
38+
totalSeconds += hours * 3600 + minutes * 60 + seconds;
39+
}
40+
41+
const remainingSeconds = deliveryLimit - totalSeconds;
42+
const pad = (value) => (value < 10 ? `0${value}` : `${value}`);
43+
const sign = remainingSeconds <= 0 ? '' : '-';
44+
const absRemainingSeconds = Math.abs(remainingSeconds);
45+
const resultHours = pad(Math.floor(absRemainingSeconds / 3600));
46+
const resultMinutes = pad(Math.floor((absRemainingSeconds % 3600) / 60));
47+
const resultSeconds = pad(absRemainingSeconds % 60);
48+
return `${sign}${resultHours}:${resultMinutes}`
49+
+ `:${resultSeconds}`;
50+
}
51+
```

2023/13-calculando-el-tiempo/index.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
function calculateTime(deliveries) {
2+
const deliveryLimit = 7 * 3600; // Límite de tiempo en segundos (7 horas)
3+
let totalSeconds = 0;
4+
5+
// eslint-disable-next-line no-restricted-syntax
6+
for (const time of deliveries) {
7+
const [hours, minutes, seconds] = time.split(':').map(Number);
8+
totalSeconds += hours * 3600 + minutes * 60 + seconds;
9+
}
10+
11+
const remainingSeconds = deliveryLimit - totalSeconds;
12+
const pad = (value) => (value < 10 ? `0${value}` : `${value}`);
13+
const sign = remainingSeconds <= 0 ? '' : '-';
14+
const absRemainingSeconds = Math.abs(remainingSeconds);
15+
const resultHours = pad(Math.floor(absRemainingSeconds / 3600));
16+
const resultMinutes = pad(Math.floor((absRemainingSeconds % 3600) / 60));
17+
const resultSeconds = pad(absRemainingSeconds % 60);
18+
return `${sign}${resultHours}:${resultMinutes}`
19+
+ `:${resultSeconds}`;
20+
}
21+
22+
module.exports = calculateTime;
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
const calculateTime = require('./index');
2+
3+
describe('13 => Calculando el tiempo', () => {
4+
const testCases = [
5+
{
6+
input: ['00:10:00', '01:00:00', '03:30:00'],
7+
output: '-02:20:00',
8+
},
9+
{
10+
input: ['02:00:00', '05:00:00', '00:30:00'],
11+
output: '00:30:00',
12+
},
13+
{
14+
input: ['00:45:00', '00:45:00', '00:00:30', '00:00:30'],
15+
output: '-05:29:00',
16+
},
17+
];
18+
19+
it('should return a string type', () => {
20+
expect(typeof calculateTime(testCases[0].input)).toBe('string');
21+
});
22+
23+
it.each(testCases)('should return $output', (testCase) => {
24+
expect(calculateTime(testCase.input)).toBe(testCase.output);
25+
});
26+
});

2023/14-evita-la-alarma/README.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Reto 14: Evita la alarma
2+
3+
## Problema
4+
5+
Con el tema de las redes sociales, Santa Claus **tiene pánico que los niños se despierten mientras él está repartiendo regalos en sus casos,** usen el móvil para grabarlo y se haga viral en TikTok.
6+
7+
Quiere evitarlo a toda costa. Cada casa en esa calle tiene un número de regalos preparados. Sin embargo, **las casas tienen un sistema de seguridad conectado entre casas adyacentes,** por lo que **no puede dejar los regalos en dos casas seguidas,** o se activará la alarma que alertará a los niños.
8+
9+
Dada un **array de enteros no negativos regalos** que representa la cantidad de regalos en cada casa, tu tarea es ayudar a Papá Noel a determinar la **máxima cantidad de regalos que puede entregar** en una noche sin activar ninguna alarma.
10+
11+
```js
12+
maxGifts([2, 4, 2]) // 4 (4)
13+
maxGifts([5, 1, 1, 5]) // 10 (5 + 5)
14+
maxGifts([4, 1, 1, 4, 2, 1]) // 9 (4 + 4 + 1)
15+
maxGifts([1, 3, 1, 3, 100]) // 103 (3 + 100)
16+
```
17+
18+
## Mi solución
19+
20+
```js
21+
const maxGifts = (houses) => {
22+
let incl = 0;
23+
let excl = 0;
24+
25+
// eslint-disable-next-line no-restricted-syntax
26+
for (const current of houses) {
27+
[incl, excl] = [excl + current, Math.max(incl, excl)];
28+
}
29+
30+
return Math.max(incl, excl);
31+
};
32+
```

2023/14-evita-la-alarma/index.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
const maxGifts = (houses) => {
2+
let incl = 0;
3+
let excl = 0;
4+
5+
// eslint-disable-next-line no-restricted-syntax
6+
for (const current of houses) {
7+
[incl, excl] = [excl + current, Math.max(incl, excl)];
8+
}
9+
10+
return Math.max(incl, excl);
11+
};
12+
13+
module.exports = maxGifts;

2023/14-evita-la-alarma/index.test.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
const maxGifts = require('./index');
2+
3+
describe('14 => Evita la alarma', () => {
4+
const testCases = [
5+
{
6+
input: [2, 4, 2],
7+
output: 4,
8+
},
9+
{
10+
input: [5, 1, 1, 5],
11+
output: 10,
12+
},
13+
{
14+
input: [4, 1, 1, 4, 2, 1],
15+
output: 9,
16+
},
17+
{
18+
input: [1, 3, 1, 3, 100],
19+
output: 103,
20+
},
21+
];
22+
23+
it('should return a number type', () => {
24+
expect(typeof maxGifts([1, 2, 3])).toBe('number');
25+
});
26+
27+
it.each(testCases)('should return $output', ({ input, output }) => {
28+
expect(maxGifts(input)).toBe(output);
29+
});
30+
});

2023/15-robot-autonomo/README.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Reto 15: Robot autonomo
2+
3+
## Problema
4+
5+
Estamos programando unos **robots** llamados giftbot 🤖🎁 que navegan de forma autónoma por los almacenes de regalos.
6+
7+
Estamos creando una función a la que le pasamos: el almacén 🏬 que deben navegar y los movimientos ↔️ que pueden realizar.
8+
9+
El almacén se representa como un **array de cadenas de texto,** donde:
10+
11+
- `.` significa que hay vía libre.
12+
- `*` significa que hay un obstáculo.
13+
- `!` es la posición inicial del robot.
14+
15+
Los movimientos son un **array de cadenas de texto,** donde:
16+
17+
- `R` mueve al robot una posición a la derecha.
18+
- `L` mueve al robot una posición a la izquierda.
19+
- `U` mueve al robot una posición hacia arriba.
20+
- `D` mueve al robot una posición hacia abajo.
21+
22+
Hay que tener en cuenta que **el robot no puede superar los obstáculos ni los límites del almacén.**
23+
24+
Dados un almacén y los movimientos, debemos devolver el array con la posición final de nuestro robot.
25+
26+
```js
27+
const store = ['..!....', '...*.*.']
28+
29+
const movements = ['R', 'R', 'D', 'L']
30+
const result = autonomousDrive(store, movements)
31+
console.log(result)
32+
/*
33+
[
34+
".......",
35+
"...*!*."
36+
]
37+
*/
38+
39+
// El último movimiento es hacia la izquierda, pero no puede moverse porque hay un obstáculo.
40+
```
41+
42+
Ten en cuenta que la store es **un array que puede ser de un número de filas que va de 1 a 100,** ya que tenemos almacenes de todos los tamaños.
43+
44+
También que el robot **es posible que termine en su posición inicial** si no puede moverse o si está dando vueltas.
45+
46+
## Mi solución
47+
48+
```js
49+
function autonomousDrive(store, movements) {
50+
let currentRow = store.findIndex((line) => line.includes('!'));
51+
let currentCol = store[currentRow].indexOf('!');
52+
store[currentRow] = store[currentRow].replace('!', '.');
53+
54+
// eslint-disable-next-line no-restricted-syntax
55+
for (const movement of movements) {
56+
const di = +(movement === 'D') - +(movement === 'U');
57+
const dj = +(movement === 'R') - +(movement === 'L');
58+
currentRow += +(store[currentRow + di]?.[currentCol] === '.' && di);
59+
currentCol += +(store[currentRow][currentCol + dj] === '.' && dj);
60+
}
61+
62+
const currentLine = store[currentRow];
63+
store[currentRow] = `${currentLine.substring(0, currentCol)}!${
64+
currentLine.substring(currentCol + 1)}`;
65+
66+
return store;
67+
}
68+
```

2023/15-robot-autonomo/index.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
function autonomousDrive(store, movements) {
2+
let currentRow = store.findIndex((line) => line.includes('!'));
3+
let currentCol = store[currentRow].indexOf('!');
4+
store[currentRow] = store[currentRow].replace('!', '.');
5+
6+
// eslint-disable-next-line no-restricted-syntax
7+
for (const movement of movements) {
8+
const di = +(movement === 'D') - +(movement === 'U');
9+
const dj = +(movement === 'R') - +(movement === 'L');
10+
currentRow += +(store[currentRow + di]?.[currentCol] === '.' && di);
11+
currentCol += +(store[currentRow][currentCol + dj] === '.' && dj);
12+
}
13+
14+
const currentLine = store[currentRow];
15+
store[currentRow] = `${currentLine.substring(0, currentCol)}!${
16+
currentLine.substring(currentCol + 1)}`;
17+
18+
return store;
19+
}
20+
21+
module.exports = autonomousDrive;

0 commit comments

Comments
 (0)