Skip to content

Commit

Permalink
Merge pull request #16 from marcode24/2023
Browse files Browse the repository at this point in the history
2023
  • Loading branch information
marcode24 authored Dec 25, 2023
2 parents 721cc68 + 0fcb834 commit f42f125
Show file tree
Hide file tree
Showing 28 changed files with 1,466 additions and 0 deletions.
87 changes: 87 additions & 0 deletions 2023/12-es-una-copia-valida/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# Reto 12: Es una copia valida

## Problema

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.

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.

**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.

Existe una gran **probabilidad** de que un caracter se degrade en cada copia (¡no pasa siempre!). Y al ocurrir, la regla que sigue es:

- Los caracteres de la A a la Z se degradan de mayúsculas a minúsculas (A-Z ⇒ a-z)
- Las letras se degradan en una serie de caracteres en este orden: a-z ⇒ # ⇒ + ⇒ : ⇒ . ⇒
- Una vez degradadas las letras en los símbolos, se pueden continuar degradando.
- Ten en cuenta que el último es un espacio en blanco, no un caracter vacío.
- Los caracteres que no son letras (como los dígitos) no se degradan.

Sabiendo esto y recibiendo dos cartas. La supuesta original y la copia. Debes determinar si la copia es una copia de la otra.

```js
checkIsValidCopy(
'Santa Claus is coming',
'sa#ta Cl#us i+ comin#'
) // true
checkIsValidCopy(
's#nta Cla#s is coming',
'p#nt: cla#s #s c+min#'
) // false (por la p inicial)
checkIsValidCopy('Santa Claus', 's#+:. c:. s') // true
checkIsValidCopy('Santa Claus', 's#+:.#c:. s') // false (hay un # donde no debería)
```

Para entender cómo funcionan las fotocopiadoras y su degradación, mira este ejemplo:

```txt
original: 'Santa Claus'
1ª copia: 'santa cla#s'
2ª copia: 'sa#t# cl#+s'
3ª copia: 'sa+## c#+:s'
4ª copia: 's#++. c+:.s'
5ª copia: 's#+:. c:. s'
```

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.

Basado en el desafío de CodeWars Photocopy decay

## Mi solución

```js
function checkIsValidCopy(original, copy) {
let isValidCopy = true;
const symbolSequence = '#+:. ';

let copyIndex = 0;

// eslint-disable-next-line no-restricted-syntax
for (const letter of original) {
const copyLetter = copy[copyIndex];
const symbolIndex = symbolSequence.indexOf(letter);

const symbols = symbolIndex !== -1
? symbolSequence.slice(symbolIndex)
: symbolSequence;

const isValidLetter = `${letter}${letter.toLowerCase()}${symbols}`
.includes(copyLetter);

const isLetterBlankSpace = letter === ' ';
const isCopyLetterBlankSpace = copyLetter === ' ';

const isValidCharacter = isLetterBlankSpace
? isCopyLetterBlankSpace
: isValidLetter;

if (!isValidCharacter) {
isValidCopy = false;
break;
}

copyIndex++;
}

return isValidCopy;
}
```
37 changes: 37 additions & 0 deletions 2023/12-es-una-copia-valida/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
function checkIsValidCopy(original, copy) {
let isValidCopy = true;
const symbolSequence = '#+:. ';

let copyIndex = 0;

// eslint-disable-next-line no-restricted-syntax
for (const letter of original) {
const copyLetter = copy[copyIndex];
const symbolIndex = symbolSequence.indexOf(letter);

const symbols = symbolIndex !== -1
? symbolSequence.slice(symbolIndex)
: symbolSequence;

const isValidLetter = `${letter}${letter.toLowerCase()}${symbols}`
.includes(copyLetter);

const isLetterBlankSpace = letter === ' ';
const isCopyLetterBlankSpace = copyLetter === ' ';

const isValidCharacter = isLetterBlankSpace
? isCopyLetterBlankSpace
: isValidLetter;

if (!isValidCharacter) {
isValidCopy = false;
break;
}

copyIndex++;
}

return isValidCopy;
}

module.exports = checkIsValidCopy;
34 changes: 34 additions & 0 deletions 2023/12-es-una-copia-valida/index.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
const checkIsValidCopy = require('./index');

describe('12 => Es una copia valida', () => {
const testCases = [
{
input: ['Santa Claus is coming', 'sa#ta Cl#us i+ comin#'],
output: true,
},
{
input: ['s#nta Cla#s is coming', 'p#nt: cla#s #s c+min#'],
output: false,
},
{
input: ['Santa Claus', 's#+:. c:. s'],
output: true,
},
{
input: ['Santa Claus', 's#+:.#c:. s'],
output: false,
},
{
input: ['s+#:.#c:. s', 's#+:.#c:. s'],
output: false,
},
];

it('should return a boolean type', () => {
expect(typeof checkIsValidCopy(...testCases[0].input)).toBe('boolean');
});

it.each(testCases)('should return $output', ({ input, output }) => {
expect(checkIsValidCopy(...input)).toBe(output);
});
});
55 changes: 55 additions & 0 deletions 2023/17-optimizando-el-alquiler/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Reto 17: Optimizando el alquiler

## Problema

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.

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.

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:**

```js
optimizeIntervals([
[5, 8],
[2, 7],
[3, 4]
]) // [[2, 8]]

optimizeIntervals([
[1, 3],
[8, 10],
[2, 6]
]) // [[1, 6], [8, 10]]

optimizeIntervals([
[3, 4],
[1, 2],
[5, 6]
]) // [[1, 2], [3, 4], [5, 6]]
```

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.**

Los números de horas pueden llegar hasta la cifra 9999.

## Mi solución

```js
const optimizeIntervals = (intervals) => {
const result = [
intervals.sort((a, b) => a[0] - b[0])[0],
];

// eslint-disable-next-line no-restricted-syntax
for (const val of intervals) {
const [start, end] = val;
const max = result[result.length - 1][1];

start > max
? result.push(val)
: (result[result.length - 1][1] = Math.max(end, max));
}

return result;
};
```
19 changes: 19 additions & 0 deletions 2023/17-optimizando-el-alquiler/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const optimizeIntervals = (intervals) => {
const result = [
intervals.sort((a, b) => a[0] - b[0])[0],
];

// eslint-disable-next-line no-restricted-syntax
for (const val of intervals) {
const [start, end] = val;
const max = result[result.length - 1][1];

start > max
? result.push(val)
: (result[result.length - 1][1] = Math.max(end, max));
}

return result;
};

module.exports = optimizeIntervals;
38 changes: 38 additions & 0 deletions 2023/17-optimizando-el-alquiler/index.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
const optimizeIntervals = require('./index');

describe('17 => Optimizando el alquiler', () => {
const testCases = [
{
input: [
[5, 8],
[2, 7],
[3, 4],
],
output: [[2, 8]],
},
{
input: [
[1, 3],
[8, 10],
[2, 6],
],
output: [[1, 6], [8, 10]],
},
{
input: [
[3, 4],
[1, 2],
[5, 6],
],
output: [[1, 2], [3, 4], [5, 6]],
},
];

it('should return an array type', () => {
expect(Array.isArray(optimizeIntervals([...testCases[0].input]))).toBe(true);
});

it.each(testCases)('should return the correct output', (testCase) => {
expect(optimizeIntervals([...testCase.input])).toEqual(testCase.output);
});
});
66 changes: 66 additions & 0 deletions 2023/18-el-reloj-digital/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Reto 18: El reloj digital

## Problema

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.

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.

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).

Por ejemplo, si la función recibe 01:30 debe devolver:

drawClock('01:30') // ⬇️

[
['*', '*', '*', ' ', ' ', ' ', '*', ' ', ' ', ' ', '*', '*', '*', ' ', '*', '*', '*'],
['*', ' ', '*', ' ', ' ', ' ', '*', ' ', ' ', ' ', ' ', ' ', '*', ' ', '*', ' ', '*'],
['*', ' ', '*', ' ', ' ', ' ', '*', ' ', '*', ' ', ' ', ' ', '*', ' ', '*', ' ', '*'],
['*', ' ', '*', ' ', ' ', ' ', '*', ' ', ' ', ' ', '*', '*', '*', ' ', '*', ' ', '*'],
['*', ' ', '*', ' ', ' ', ' ', '*', ' ', '*', ' ', ' ', ' ', '*', ' ', '*', ' ', '*'],
['*', ' ', '*', ' ', ' ', ' ', '*', ' ', ' ', ' ', ' ', ' ', '*', ' ', '*', ' ', '*'],
['*', '*', '*', ' ', ' ', ' ', '*', ' ', ' ', ' ', '*', '*', '*', ' ', '*', '*', '*']
]
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 ():

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

## Mi solución

```js
function drawClock(time) {
const digitPatterns = {
0: ['***', '* *', '* *', '* *', '* *', '* *', '***'],
1: [' *', ' *', ' *', ' *', ' *', ' *', ' *'],
2: ['***', ' *', ' *', '***', '* ', '* ', '***'],
3: ['***', ' *', ' *', '***', ' *', ' *', '***'],
4: ['* *', '* *', '* *', '***', ' *', ' *', ' *'],
5: ['***', '* ', '* ', '***', ' *', ' *', '***'],
6: ['***', '* ', '* ', '***', '* *', '* *', '***'],
7: ['***', ' *', ' *', ' *', ' *', ' *', ' *'],
8: ['***', '* *', '* *', '***', '* *', '* *', '***'],
9: ['***', '* *', '* *', '***', ' *', ' *', '***'],
':': [' ', ' ', '*', ' ', '*', ' ', ' '],
};

const firstDigitPattern = digitPatterns[time[0]];
const secondDigitPattern = digitPatterns[time[1]];
const colonPattern = digitPatterns[':'];
const thirdDigitPattern = digitPatterns[time[3]];
const fourthDigitPattern = digitPatterns[time[4]];

const result = [...firstDigitPattern];
let position = 0;

// eslint-disable-next-line no-restricted-syntax
for (const row of result) {
const rowString = `${row} ${secondDigitPattern[position]} `
+ `${colonPattern[position]} ${thirdDigitPattern[position]} `
+ `${fourthDigitPattern[position]}`;
result[position] = [...rowString];
position++;
}

return result;
}
```
37 changes: 37 additions & 0 deletions 2023/18-el-reloj-digital/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
function drawClock(time) {
const digitPatterns = {
0: ['***', '* *', '* *', '* *', '* *', '* *', '***'],
1: [' *', ' *', ' *', ' *', ' *', ' *', ' *'],
2: ['***', ' *', ' *', '***', '* ', '* ', '***'],
3: ['***', ' *', ' *', '***', ' *', ' *', '***'],
4: ['* *', '* *', '* *', '***', ' *', ' *', ' *'],
5: ['***', '* ', '* ', '***', ' *', ' *', '***'],
6: ['***', '* ', '* ', '***', '* *', '* *', '***'],
7: ['***', ' *', ' *', ' *', ' *', ' *', ' *'],
8: ['***', '* *', '* *', '***', '* *', '* *', '***'],
9: ['***', '* *', '* *', '***', ' *', ' *', '***'],
':': [' ', ' ', '*', ' ', '*', ' ', ' '],
};

const firstDigitPattern = digitPatterns[time[0]];
const secondDigitPattern = digitPatterns[time[1]];
const colonPattern = digitPatterns[':'];
const thirdDigitPattern = digitPatterns[time[3]];
const fourthDigitPattern = digitPatterns[time[4]];

const result = [...firstDigitPattern];
let position = 0;

// eslint-disable-next-line no-restricted-syntax
for (const row of result) {
const rowString = `${row} ${secondDigitPattern[position]} `
+ `${colonPattern[position]} ${thirdDigitPattern[position]} `
+ `${fourthDigitPattern[position]}`;
result[position] = [...rowString];
position++;
}

return result;
}

module.exports = drawClock;
Loading

0 comments on commit f42f125

Please sign in to comment.