docs: add Spanish docs
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
---
|
||||
id: a3f503de51cf954ede28891d
|
||||
title: Find the Symmetric Difference
|
||||
localeTitle: Encuentra la diferencia simétrica
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Cree una función que tome dos o más matrices y devuelva una matriz de la <dfn>diferencia simétrica</dfn> ( <code>△</code> o <code>⊕</code> ) de las matrices proporcionadas.
|
||||
Dado dos conjuntos (por ejemplo, conjunto <code>A = {1, 2, 3}</code> y conjunto <code>B = {2, 3, 4}</code> ), el término matemático "diferencia simétrica" es el conjunto de elementos que se encuentran en cualquiera de los dos conjuntos, pero no en ambos ( <code>A △ B = C = {1, 4}</code> ). Por cada diferencia simétrica adicional que tome (por ejemplo, en un conjunto <code>D = {2, 3}</code> ), debe obtener el conjunto con elementos que están en cualquiera de los dos conjuntos pero no en ambos ( <code>C △ D = {1, 4} △ {2, 3} = {1, 2, 3, 4}</code> ). La matriz resultante debe contener solo valores únicos ( <em>no duplicados</em> ).
|
||||
Recuerda usar <a href='http://forum.freecodecamp.org/t/how-to-get-help-when-you-are-stuck/19514' target='_blank'>Read-Search-Ask</a> si te atascas. Trate de emparejar el programa. Escribe tu propio código.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: ' <code>sym([1, 2, 3], [5, 2, 1, 4])</code> debe devolver <code>[3, 4, 5]</code> .'
|
||||
testString: 'assert.sameMembers(sym([1, 2, 3], [5, 2, 1, 4]), [3, 4, 5], "<code>sym([1, 2, 3], [5, 2, 1, 4])</code> should return <code>[3, 4, 5]</code>.");'
|
||||
- text: ' <code>sym([1, 2, 3], [5, 2, 1, 4])</code> debe contener solo tres elementos.'
|
||||
testString: 'assert.equal(sym([1, 2, 3], [5, 2, 1, 4]).length, 3, "<code>sym([1, 2, 3], [5, 2, 1, 4])</code> should contain only three elements.");'
|
||||
- text: ' <code>sym([1, 2, 3, 3], [5, 2, 1, 4])</code> debe devolver <code>[3, 4, 5]</code> .'
|
||||
testString: 'assert.sameMembers(sym([1, 2, 3, 3], [5, 2, 1, 4]), [3, 4, 5], "<code>sym([1, 2, 3, 3], [5, 2, 1, 4])</code> should return <code>[3, 4, 5]</code>.");'
|
||||
- text: ' <code>sym([1, 2, 3, 3], [5, 2, 1, 4])</code> debe contener solo tres elementos.'
|
||||
testString: 'assert.equal(sym([1, 2, 3, 3], [5, 2, 1, 4]).length, 3, "<code>sym([1, 2, 3, 3], [5, 2, 1, 4])</code> should contain only three elements.");'
|
||||
- text: ' <code>sym([1, 2, 3], [5, 2, 1, 4, 5])</code> debe devolver <code>[3, 4, 5]</code> .'
|
||||
testString: 'assert.sameMembers(sym([1, 2, 3], [5, 2, 1, 4, 5]), [3, 4, 5], "<code>sym([1, 2, 3], [5, 2, 1, 4, 5])</code> should return <code>[3, 4, 5]</code>.");'
|
||||
- text: ' <code>sym([1, 2, 3], [5, 2, 1, 4, 5])</code> debe contener solo tres elementos.'
|
||||
testString: 'assert.equal(sym([1, 2, 3], [5, 2, 1, 4, 5]).length, 3, "<code>sym([1, 2, 3], [5, 2, 1, 4, 5])</code> should contain only three elements.");'
|
||||
- text: ' <code>sym([1, 2, 5], [2, 3, 5], [3, 4, 5])</code> debe devolver <code>[1, 4, 5]</code> '
|
||||
testString: 'assert.sameMembers(sym([1, 2, 5], [2, 3, 5], [3, 4, 5]), [1, 4, 5], "<code>sym([1, 2, 5], [2, 3, 5], [3, 4, 5])</code> should return <code>[1, 4, 5]</code>");'
|
||||
- text: ' <code>sym([1, 2, 5], [2, 3, 5], [3, 4, 5])</code> debe contener solo tres elementos.'
|
||||
testString: 'assert.equal(sym([1, 2, 5], [2, 3, 5], [3, 4, 5]).length, 3, "<code>sym([1, 2, 5], [2, 3, 5], [3, 4, 5])</code> should contain only three elements.");'
|
||||
- text: ' <code>sym([1, 1, 2, 5], [2, 2, 3, 5], [3, 4, 5, 5])</code> debe devolver <code>[1, 4, 5]</code> .'
|
||||
testString: 'assert.sameMembers(sym([1, 1, 2, 5], [2, 2, 3, 5], [3, 4, 5, 5]), [1, 4, 5], "<code>sym([1, 1, 2, 5], [2, 2, 3, 5], [3, 4, 5, 5])</code> should return <code>[1, 4, 5]</code>.");'
|
||||
- text: ' <code>sym([1, 1, 2, 5], [2, 2, 3, 5], [3, 4, 5, 5])</code> debe contener solo tres elementos.'
|
||||
testString: 'assert.equal(sym([1, 1, 2, 5], [2, 2, 3, 5], [3, 4, 5, 5]).length, 3, "<code>sym([1, 1, 2, 5], [2, 2, 3, 5], [3, 4, 5, 5])</code> should contain only three elements.");'
|
||||
- text: ' <code>sym([3, 3, 3, 2, 5], [2, 1, 5, 7], [3, 4, 6, 6], [1, 2, 3])</code> debe devolver <code>[2, 3, 4, 6, 7]</code> .
|
||||
testString: 'assert.sameMembers(sym([3, 3, 3, 2, 5], [2, 1, 5, 7], [3, 4, 6, 6], [1, 2, 3]), [2, 3, 4, 6, 7], "<code>sym([3, 3, 3, 2, 5], [2, 1, 5, 7], [3, 4, 6, 6], [1, 2, 3])</code> should return <code>[2, 3, 4, 6, 7]</code>.");'
|
||||
- text: ' <code>sym([3, 3, 3, 2, 5], [2, 1, 5, 7], [3, 4, 6, 6], [1, 2, 3])</code> debe contener solo cinco elementos.'
|
||||
testString: 'assert.equal(sym([3, 3, 3, 2, 5], [2, 1, 5, 7], [3, 4, 6, 6], [1, 2, 3]).length, 5, "<code>sym([3, 3, 3, 2, 5], [2, 1, 5, 7], [3, 4, 6, 6], [1, 2, 3])</code> should contain only five elements.");'
|
||||
- text: ' <code>sym([3, 3, 3, 2, 5], [2, 1, 5, 7], [3, 4, 6, 6], [1, 2, 3], [5, 3, 9, 8], [1])</code> debe devolver <code>[1, 2, 4, 5, 6, 7, 8, 9]</code> . '
|
||||
testString: 'assert.sameMembers(sym([3, 3, 3, 2, 5], [2, 1, 5, 7], [3, 4, 6, 6], [1, 2, 3], [5, 3, 9, 8], [1]), [1, 2, 4, 5, 6, 7, 8, 9], "<code>sym([3, 3, 3, 2, 5], [2, 1, 5, 7], [3, 4, 6, 6], [1, 2, 3], [5, 3, 9, 8], [1])</code> should return <code>[1, 2, 4, 5, 6, 7, 8, 9]</code>.");'
|
||||
- text: ' <code>sym([3, 3, 3, 2, 5], [2, 1, 5, 7], [3, 4, 6, 6], [1, 2, 3], [5, 3, 9, 8], [1])</code> debe contener solo ocho elementos '.
|
||||
testString: 'assert.equal(sym([3, 3, 3, 2, 5], [2, 1, 5, 7], [3, 4, 6, 6], [1, 2, 3], [5, 3, 9, 8], [1]).length, 8, "<code>sym([3, 3, 3, 2, 5], [2, 1, 5, 7], [3, 4, 6, 6], [1, 2, 3], [5, 3, 9, 8], [1])</code> should contain only eight elements.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function sym(args) {
|
||||
return args;
|
||||
}
|
||||
|
||||
sym([1, 2, 3], [5, 2, 1, 4]);
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
function sym() {
|
||||
var arrays = [].slice.call(arguments);
|
||||
return arrays.reduce(function (symDiff, arr) {
|
||||
return symDiff.concat(arr).filter(function (val, idx, theArr) {
|
||||
return theArr.indexOf(val) === idx
|
||||
&& (symDiff.indexOf(val) === -1 || arr.indexOf(val) === -1);
|
||||
});
|
||||
});
|
||||
}
|
||||
sym([1, 2, 3], [5, 2, 1, 4]);
|
||||
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,77 @@
|
||||
---
|
||||
id: 8d5123c8c441eddfaeb5bdef
|
||||
title: Implement Bubble Sort
|
||||
localeTitle: Implementar Bubble Sort
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Este es el primero de varios desafíos en la clasificación de algoritmos. Dada una matriz de elementos sin clasificar, queremos poder devolver una matriz ordenada. Veremos varios métodos diferentes para hacer esto y aprenderemos algunas compensaciones entre estos diferentes enfoques. Si bien la mayoría de los lenguajes modernos tienen métodos de clasificación incorporados para operaciones como esta, todavía es importante entender algunos de los enfoques básicos comunes y aprender cómo pueden implementarse.
|
||||
Aquí veremos burbuja ordenada. El método de clasificación de burbujas comienza al principio de una matriz sin ordenar y 'burbujea' valores sin ordenar hacia el final, iterando a través de la matriz hasta que esté completamente ordenada. Lo hace comparando elementos adyacentes e intercambiándolos si están fuera de orden. El método continúa en bucle a través de la matriz hasta que no se produzcan swaps en qué punto se clasifica la matriz.
|
||||
Este método requiere múltiples iteraciones a través de la matriz y, en promedio, en el peor de los casos tiene una complejidad de tiempo cuadrática. Aunque simple, generalmente es poco práctico en la mayoría de las situaciones.
|
||||
<strong>Instrucciones:</strong> Escriba una función <code>bubbleSort</code> que toma una matriz de enteros como entrada y devuelve una matriz de estos enteros en orden ordenado de menor a mayor.
|
||||
<strong>Nota:</strong> <br> Estamos llamando a esta función desde detrás de la escena; La matriz de prueba que estamos utilizando está comentada en el editor. ¡Intente registrar la <code>array</code> para ver su algoritmo de clasificación en acción!
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>bubbleSort</code> es una función.
|
||||
testString: 'assert(typeof bubbleSort == "function", "<code>bubbleSort</code> is a function.");'
|
||||
- text: <code>bubbleSort</code> devuelve una matriz ordenada (de menor a mayor).
|
||||
testString: 'assert(isSorted(bubbleSort([1,4,2,8,345,123,43,32,5643,63,123,43,2,55,1,234,92])), "<code>bubbleSort</code> returns a sorted array (least to greatest).");'
|
||||
- text: <code>bubbleSort</code> devuelve una matriz que no se modifica, excepto para el orden.
|
||||
testString: 'assert.sameMembers(bubbleSort([1,4,2,8,345,123,43,32,5643,63,123,43,2,55,1,234,92]), [1,4,2,8,345,123,43,32,5643,63,123,43,2,55,1,234,92], "<code>bubbleSort</code> returns an array that is unchanged except for order.");'
|
||||
- text: <code>bubbleSort</code> no debe usar el método <code>.sort()</code> .
|
||||
testString: 'assert.strictEqual(code.search(/\.sort\(/), -1, "<code>bubbleSort</code> should not use the built-in <code>.sort()</code> method.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function bubbleSort(array) {
|
||||
// change code below this line
|
||||
|
||||
// change code above this line
|
||||
return array;
|
||||
}
|
||||
|
||||
// test array:
|
||||
// [1, 4, 2, 8, 345, 123, 43, 32, 5643, 63, 123, 43, 2, 55, 1, 234, 92]
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
console.info('after the test');
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,75 @@
|
||||
---
|
||||
id: 587d8259367417b2b2512c86
|
||||
title: Implement Insertion Sort
|
||||
localeTitle: Implementar orden de inserción
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
El siguiente método de clasificación que veremos es la ordenación por inserción. Este método funciona mediante la creación de una matriz ordenada al principio de la lista. Comienza la matriz ordenada con el primer elemento. Luego inspecciona el siguiente elemento y lo intercambia hacia atrás en la matriz ordenada hasta que esté en la posición ordenada. Continúa recorriendo la lista e intercambiando nuevos elementos hacia atrás en la parte ordenada hasta que llega al final. Este algoritmo tiene una complejidad de tiempo cuadrática en los casos promedio y en los peores.
|
||||
<strong>Instrucciones:</strong> Escriba una función <code>insertionSort</code> que toma una matriz de enteros como entrada y devuelve una matriz de estos enteros en orden ordenado de menor a mayor.
|
||||
<strong>Nota:</strong> <br> Estamos llamando a esta función desde detrás de la escena; La matriz de prueba que estamos utilizando está comentada en el editor. ¡Intente registrar la <code>array</code> para ver su algoritmo de clasificación en acción!
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>insertionSort</code> es una función.
|
||||
testString: 'assert(typeof insertionSort == "function", "<code>insertionSort</code> is a function.");'
|
||||
- text: <code>insertionSort</code> devuelve una matriz ordenada (menor a mayor).
|
||||
testString: 'assert(isSorted(insertionSort([1,4,2,8,345,123,43,32,5643,63,123,43,2,55,1,234,92])), "<code>insertionSort</code> returns a sorted array (least to greatest).");'
|
||||
- text: <code>insertionSort</code> devuelve una matriz que no se modifica, excepto para el orden.
|
||||
testString: 'assert.sameMembers(insertionSort([1,4,2,8,345,123,43,32,5643,63,123,43,2,55,1,234,92]), [1,4,2,8,345,123,43,32,5643,63,123,43,2,55,1,234,92], "<code>insertionSort</code> returns an array that is unchanged except for order.");'
|
||||
- text: <code>insertionSort</code> no debe usar el método <code>.sort()</code> .
|
||||
testString: 'assert.strictEqual(code.search(/\.sort\(/), -1, "<code>insertionSort</code> should not use the built-in <code>.sort()</code> method.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function insertionSort(array) {
|
||||
// change code below this line
|
||||
|
||||
// change code above this line
|
||||
return array;
|
||||
}
|
||||
|
||||
// test array:
|
||||
// [1, 4, 2, 8, 345, 123, 43, 32, 5643, 63, 123, 43, 2, 55, 1, 234, 92]
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
console.info('after the test');
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,79 @@
|
||||
---
|
||||
id: 587d825c367417b2b2512c8f
|
||||
title: Implement Merge Sort
|
||||
localeTitle: Implementar Merge Sort
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Otro algoritmo de clasificación intermedio que es muy común es la clasificación por fusión. Al igual que la ordenación rápida, la ordenación combinada también usa una metodología recursiva de dividir y conquistar para ordenar una matriz. Aprovecha el hecho de que es relativamente fácil clasificar dos matrices siempre que cada una esté ordenada en primer lugar. Pero comenzaremos con solo una matriz como entrada, entonces, ¿cómo podemos obtener dos matrices ordenadas de eso? Bueno, podemos dividir recursivamente la entrada original en dos hasta que alcancemos el caso base de una matriz con un elemento. Una matriz de un solo elemento se ordena naturalmente, por lo que podemos comenzar a combinar. Esta combinación desenrollará las llamadas recursivas que dividen la matriz original, produciendo finalmente una matriz ordenada final de todos los elementos. Los pasos de la ordenación de fusión, entonces, son:
|
||||
<strong>1)</strong> Divide recursivamente la matriz de entrada por la mitad hasta que se genere una sub-matriz con solo un elemento.
|
||||
<strong>2)</strong> Fusione cada sub-matriz ordenada para producir la matriz final ordenada.
|
||||
clasificación de mezcla es un método de clasificación eficiente, con una complejidad de tiempo de <i>O (nlog (n))</i> . Este algoritmo es popular porque es eficaz y relativamente fácil de implementar.
|
||||
Como punto de partida, este será el último algoritmo de clasificación que cubrimos aquí. Sin embargo, más adelante en la sección sobre estructuras de datos de árbol, describiremos la ordenación de pilas, otro método de clasificación eficiente que requiere una pila binaria en su implementación.
|
||||
<strong>Instrucciones:</strong> escriba una función <code>mergeSort</code> que tome una matriz de enteros como entrada y devuelva una matriz de estos enteros en orden ordenado de menor a mayor. Una buena manera de implementar esto es escribir una función, por ejemplo, <code>merge</code> , que es responsable de combinar dos matrices ordenadas, y otra función, por ejemplo <code>mergeSort</code> , que es responsable de la recursión que produce matrices de un solo elemento para alimentar la fusión. ¡Buena suerte!
|
||||
<strong>Nota:</strong> <br> Estamos llamando a esta función desde detrás de la escena; La matriz de prueba que estamos utilizando está comentada en el editor. ¡Intente registrar la <code>array</code> para ver su algoritmo de clasificación en acción!
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>mergeSort</code> es una función.
|
||||
testString: 'assert(typeof mergeSort == "function", "<code>mergeSort</code> is a function.");'
|
||||
- text: <code>mergeSort</code> devuelve una matriz ordenada (menor a mayor).
|
||||
testString: 'assert(isSorted(mergeSort([1,4,2,8,345,123,43,32,5643,63,123,43,2,55,1,234,92])), "<code>mergeSort</code> returns a sorted array (least to greatest).");'
|
||||
- text: <code>mergeSort</code> devuelve una matriz que no se modifica, excepto para el orden.
|
||||
testString: 'assert.sameMembers(mergeSort([1,4,2,8,345,123,43,32,5643,63,123,43,2,55,1,234,92]), [1,4,2,8,345,123,43,32,5643,63,123,43,2,55,1,234,92], "<code>mergeSort</code> returns an array that is unchanged except for order.");'
|
||||
- text: <code>mergeSort</code> no debe usar el método <code>.sort()</code> .
|
||||
testString: 'assert.strictEqual(code.search(/\.sort\(/), -1, "<code>mergeSort</code> should not use the built-in <code>.sort()</code> method.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function mergeSort(array) {
|
||||
// change code below this line
|
||||
|
||||
// change code above this line
|
||||
return array;
|
||||
}
|
||||
|
||||
// test array:
|
||||
// [1, 4, 2, 8, 345, 123, 43, 32, 5643, 63, 123, 43, 2, 55, 1, 234, 92]
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
console.info('after the test');
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,76 @@
|
||||
---
|
||||
id: 587d825a367417b2b2512c89
|
||||
title: Implement Quick Sort
|
||||
localeTitle: Implementar ordenación rápida
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Aquí pasaremos a un algoritmo de clasificación intermedio: ordenación rápida. La clasificación rápida es un método eficiente y recursivo de dividir y conquistar para clasificar una matriz. En este método, se elige un valor pivote en la matriz original. La matriz se divide en dos subgrupos de valores menores y mayores que el valor de pivote. Luego combinamos el resultado de llamar recursivamente el algoritmo de ordenamiento rápido en ambos subarreglos. Esto continúa hasta que se alcanza el caso base de una matriz vacía o de un solo elemento, que devolvemos. El desenrollamiento de las llamadas recursivas nos devuelve la matriz ordenada.
|
||||
La clasificación rápida es un método de clasificación muy eficiente, que proporciona un rendimiento de <i>O (nlog (n))</i> en promedio. También es relativamente fácil de implementar. Estos atributos lo convierten en un método de clasificación popular y útil.
|
||||
<strong>Instrucciones:</strong> escriba una función <code>quickSort</code> que tome una matriz de enteros como entrada y devuelva una matriz de estos enteros en orden ordenado de menor a mayor. Si bien la elección del valor de pivote es importante, cualquier pivote servirá para nuestros propósitos aquí. Por simplicidad, el primer o último elemento podría ser utilizado.
|
||||
<strong>Nota:</strong> <br> Estamos llamando a esta función desde detrás de la escena; La matriz de prueba que estamos utilizando está comentada en el editor. ¡Intente registrar la <code>array</code> para ver su algoritmo de clasificación en acción!
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>quickSort</code> es una función.
|
||||
testString: 'assert(typeof quickSort == "function", "<code>quickSort</code> is a function.");'
|
||||
- text: <code>quickSort</code> devuelve una matriz ordenada (de menor a mayor).
|
||||
testString: 'assert(isSorted(quickSort([1,4,2,8,345,123,43,32,5643,63,123,43,2,55,1,234,92])), "<code>quickSort</code> returns a sorted array (least to greatest).");'
|
||||
- text: <code>quickSort</code> devuelve una matriz que no se modifica, excepto para el orden.
|
||||
testString: 'assert.sameMembers(quickSort([1,4,2,8,345,123,43,32,5643,63,123,43,2,55,1,234,92]), [1,4,2,8,345,123,43,32,5643,63,123,43,2,55,1,234,92], "<code>quickSort</code> returns an array that is unchanged except for order.");'
|
||||
- text: <code>quickSort</code> no debe usar el método <code>.sort()</code> .
|
||||
testString: 'assert.strictEqual(code.search(/\.sort\(/), -1, "<code>quickSort</code> should not use the built-in <code>.sort()</code> method.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function quickSort(array) {
|
||||
// change code below this line
|
||||
|
||||
// change code above this line
|
||||
return array;
|
||||
}
|
||||
|
||||
// test array:
|
||||
// [1, 4, 2, 8, 345, 123, 43, 32, 5643, 63, 123, 43, 2, 55, 1, 234, 92]
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
console.info('after the test');
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,75 @@
|
||||
---
|
||||
id: 587d8259367417b2b2512c85
|
||||
title: Implement Selection Sort
|
||||
localeTitle: Implementar Selección Ordenar
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Aquí vamos a implementar la selección por selección. El ordenamiento por selección funciona seleccionando el valor mínimo en una lista e intercambiándolo con el primer valor en la lista. Luego comienza en la segunda posición, selecciona el valor más pequeño en la lista restante y lo intercambia con el segundo elemento. Continúa recorriendo la lista e intercambiando elementos hasta que llega al final de la lista. Ahora la lista está ordenada. El ordenamiento de selección tiene una complejidad de tiempo cuadrática en todos los casos.
|
||||
<strong>Instrucciones</strong> : escriba una función <code>selectionSort</code> que toma una matriz de enteros como entrada y devuelve una matriz de estos enteros en orden ordenado de menor a mayor.
|
||||
<strong>Nota:</strong> <br> Estamos llamando a esta función desde detrás de la escena; La matriz de prueba que estamos utilizando está comentada en el editor. ¡Intente registrar la <code>array</code> para ver su algoritmo de clasificación en acción!
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>selectionSort</code> es una función.
|
||||
testString: 'assert(typeof selectionSort == "function", "<code>selectionSort</code> is a function.");'
|
||||
- text: <code>selectionSort</code> devuelve una matriz ordenada (menor a mayor).
|
||||
testString: 'assert(isSorted(selectionSort([1,4,2,8,345,123,43,32,5643,63,123,43,2,55,1,234,92])), "<code>selectionSort</code> returns a sorted array (least to greatest).");'
|
||||
- text: <code>selectionSort</code> devuelve una matriz que no se modifica, excepto para el orden.
|
||||
testString: 'assert.sameMembers(selectionSort([1,4,2,8,345,123,43,32,5643,63,123,43,2,55,1,234,92]), [1,4,2,8,345,123,43,32,5643,63,123,43,2,55,1,234,92], "<code>selectionSort</code> returns an array that is unchanged except for order.");'
|
||||
- text: <code>selectionSort</code> no debe usar el método <code>.sort()</code> .
|
||||
testString: 'assert.strictEqual(code.search(/\.sort\(/), -1, "<code>selectionSort</code> should not use the built-in <code>.sort()</code> method.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function selectionSort(array) {
|
||||
// change code below this line
|
||||
|
||||
// change code above this line
|
||||
return array;
|
||||
}
|
||||
|
||||
// test array:
|
||||
// [1, 4, 2, 8, 345, 123, 43, 32, 5643, 63, 123, 43, 2, 55, 1, 234, 92]
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
console.info('after the test');
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,122 @@
|
||||
---
|
||||
id: a56138aff60341a09ed6c480
|
||||
title: Inventory Update
|
||||
localeTitle: Actualización de inventario
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Compare y actualice el inventario almacenado en una matriz 2D con una segunda matriz 2D de una entrega nueva. Actualice las cantidades de artículos de inventario existentes actuales (en <code>arr1</code> ). Si no se puede encontrar un artículo, agregue el nuevo artículo y la cantidad en la matriz de inventario. La matriz de inventario devuelta debe estar ordenada alfabéticamente por artículo.
|
||||
Recuerda usar <a href='http://forum.freecodecamp.org/t/how-to-get-help-when-you-are-stuck/19514' target='_blank'>Read-Search-Ask</a> si te atascas. Trate de emparejar el programa. Escribe tu propio código.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: La función <code>updateInventory</code> debería devolver una matriz.
|
||||
testString: 'assert.isArray(updateInventory([[21, "Bowling Ball"], [2, "Dirty Sock"], [1, "Hair Pin"], [5, "Microphone"]], [[2, "Hair Pin"], [3, "Half-Eaten Apple"], [67, "Bowling Ball"], [7, "Toothpaste"]]), "The function <code>updateInventory</code> should return an array.");'
|
||||
- text: ' <code>updateInventory([[21, "Bowling Ball"], [2, "Dirty Sock"], [1, "Hair Pin"], [5, "Microphone"]], [[2, "Hair Pin"], [3, "Half-Eaten Apple"], [67, "Bowling Ball"], [7, "Toothpaste"]])</code> debe devolver una matriz con una longitud de 6. '
|
||||
testString: 'assert.equal(updateInventory([[21, "Bowling Ball"], [2, "Dirty Sock"], [1, "Hair Pin"], [5, "Microphone"]], [[2, "Hair Pin"], [3, "Half-Eaten Apple"], [67, "Bowling Ball"], [7, "Toothpaste"]]).length, 6, "<code>updateInventory([[21, "Bowling Ball"], [2, "Dirty Sock"], [1, "Hair Pin"], [5, "Microphone"]], [[2, "Hair Pin"], [3, "Half-Eaten Apple"], [67, "Bowling Ball"], [7, "Toothpaste"]])</code> should return an array with a length of 6.");'
|
||||
- text: ' <code>updateInventory([[21, "Bowling Ball"], [2, "Dirty Sock"], [1, "Hair Pin"], [5, "Microphone"]], [[2, "Hair Pin"], [3, "Half-Eaten Apple"], [67, "Bowling Ball"], [7, "Toothpaste"]])</code> debe devolver <code>[[88, "Bowling Ball"], [2, "Dirty Sock"], [3, "Hair Pin"], [3, "Half-Eaten Apple"], [5, "Microphone"], [7, "Toothpaste"]]</code> . '
|
||||
testString: 'assert.deepEqual(updateInventory([[21, "Bowling Ball"], [2, "Dirty Sock"], [1, "Hair Pin"], [5, "Microphone"]], [[2, "Hair Pin"], [3, "Half-Eaten Apple"], [67, "Bowling Ball"], [7, "Toothpaste"]]), [[88, "Bowling Ball"], [2, "Dirty Sock"], [3, "Hair Pin"], [3, "Half-Eaten Apple"], [5, "Microphone"], [7, "Toothpaste"]], "<code>updateInventory([[21, "Bowling Ball"], [2, "Dirty Sock"], [1, "Hair Pin"], [5, "Microphone"]], [[2, "Hair Pin"], [3, "Half-Eaten Apple"], [67, "Bowling Ball"], [7, "Toothpaste"]])</code> should return <code>[[88, "Bowling Ball"], [2, "Dirty Sock"], [3, "Hair Pin"], [3, "Half-Eaten Apple"], [5, "Microphone"], [7, "Toothpaste"]]</code>.");'
|
||||
- text: ' <code>updateInventory([[21, "Bowling Ball"], [2, "Dirty Sock"], [1, "Hair Pin"], [5, "Microphone"]], [])</code> debe devolver <code>[[21, "Bowling Ball"], [2, "Dirty Sock"], [1, "Hair Pin"], [5, "Microphone"]]</code> . '
|
||||
testString: 'assert.deepEqual(updateInventory([[21, "Bowling Ball"], [2, "Dirty Sock"], [1, "Hair Pin"], [5, "Microphone"]], []), [[21, "Bowling Ball"], [2, "Dirty Sock"], [1, "Hair Pin"], [5, "Microphone"]], "<code>updateInventory([[21, "Bowling Ball"], [2, "Dirty Sock"], [1, "Hair Pin"], [5, "Microphone"]], [])</code> should return <code>[[21, "Bowling Ball"], [2, "Dirty Sock"], [1, "Hair Pin"], [5, "Microphone"]]</code>.");'
|
||||
- text: ' <code>updateInventory([], [[2, "Hair Pin"], [3, "Half-Eaten Apple"], [67, "Bowling Ball"], [7, "Toothpaste"]])</code> debe devolver <code>[[67, "Bowling Ball"], [2, "Hair Pin"], [3, "Half-Eaten Apple"], [7, "Toothpaste"]]</code> . '
|
||||
testString: 'assert.deepEqual(updateInventory([], [[2, "Hair Pin"], [3, "Half-Eaten Apple"], [67, "Bowling Ball"], [7, "Toothpaste"]]), [[67, "Bowling Ball"], [2, "Hair Pin"], [3, "Half-Eaten Apple"], [7, "Toothpaste"]], "<code>updateInventory([], [[2, "Hair Pin"], [3, "Half-Eaten Apple"], [67, "Bowling Ball"], [7, "Toothpaste"]])</code> should return <code>[[67, "Bowling Ball"], [2, "Hair Pin"], [3, "Half-Eaten Apple"], [7, "Toothpaste"]]</code>.");'
|
||||
- text: ' <code>updateInventory([[0, "Bowling Ball"], [0, "Dirty Sock"], [0, "Hair Pin"], [0, "Microphone"]], [[1, "Hair Pin"], [1, "Half-Eaten Apple"], [1, "Bowling Ball"], [1, "Toothpaste"]])</code> debe devolver <code>[[1, "Bowling Ball"], [0, "Dirty Sock"], [1, "Hair Pin"], [1, "Half-Eaten Apple"], [0, "Microphone"], [1, "Toothpaste"]]</code> . '
|
||||
testString: 'assert.deepEqual(updateInventory([[0, "Bowling Ball"], [0, "Dirty Sock"], [0, "Hair Pin"], [0, "Microphone"]], [[1, "Hair Pin"], [1, "Half-Eaten Apple"], [1, "Bowling Ball"], [1, "Toothpaste"]]), [[1, "Bowling Ball"], [0, "Dirty Sock"], [1, "Hair Pin"], [1, "Half-Eaten Apple"], [0, "Microphone"], [1, "Toothpaste"]], "<code>updateInventory([[0, "Bowling Ball"], [0, "Dirty Sock"], [0, "Hair Pin"], [0, "Microphone"]], [[1, "Hair Pin"], [1, "Half-Eaten Apple"], [1, "Bowling Ball"], [1, "Toothpaste"]])</code> should return <code>[[1, "Bowling Ball"], [0, "Dirty Sock"], [1, "Hair Pin"], [1, "Half-Eaten Apple"], [0, "Microphone"], [1, "Toothpaste"]]</code>.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function updateInventory(arr1, arr2) {
|
||||
// All inventory must be accounted for or you're fired!
|
||||
return arr1;
|
||||
}
|
||||
|
||||
// Example inventory lists
|
||||
var curInv = [
|
||||
[21, "Bowling Ball"],
|
||||
[2, "Dirty Sock"],
|
||||
[1, "Hair Pin"],
|
||||
[5, "Microphone"]
|
||||
];
|
||||
|
||||
var newInv = [
|
||||
[2, "Hair Pin"],
|
||||
[3, "Half-Eaten Apple"],
|
||||
[67, "Bowling Ball"],
|
||||
[7, "Toothpaste"]
|
||||
];
|
||||
|
||||
updateInventory(curInv, newInv);
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
function updateInventory(arr1, arr2) {
|
||||
arr2.forEach(function(item) {
|
||||
createOrUpdate(arr1, item);
|
||||
});
|
||||
// All inventory must be accounted for or you're fired!
|
||||
return arr1;
|
||||
}
|
||||
|
||||
function createOrUpdate(arr1, item) {
|
||||
var index = -1;
|
||||
while (++index < arr1.length) {
|
||||
if (arr1[index][1] === item[1]) {
|
||||
arr1[index][0] += item[0];
|
||||
return;
|
||||
}
|
||||
if (arr1[index][1] > item[1]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
arr1.splice(index, 0, item);
|
||||
}
|
||||
|
||||
// Example inventory lists
|
||||
var curInv = [
|
||||
[21, 'Bowling Ball'],
|
||||
[2, 'Dirty Sock'],
|
||||
[1, 'Hair Pin'],
|
||||
[5, 'Microphone']
|
||||
];
|
||||
|
||||
var newInv = [
|
||||
[2, 'Hair Pin'],
|
||||
[3, 'Half-Eaten Apple'],
|
||||
[67, 'Bowling Ball'],
|
||||
[7, 'Toothpaste']
|
||||
];
|
||||
|
||||
updateInventory(curInv, newInv);
|
||||
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,111 @@
|
||||
---
|
||||
id: a7bf700cd123b9a54eef01d5
|
||||
title: No Repeats Please
|
||||
localeTitle: No se repite por favor
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Devuelve el número de permutaciones totales de la cadena proporcionada que no tienen letras consecutivas repetidas. Supongamos que todos los caracteres de la cadena proporcionada son únicos.
|
||||
Por ejemplo, <code>aab</code> debería devolver 2 porque tiene 6 permutaciones totales ( <code>aab</code> , <code>aab</code> , <code>aba</code> , <code>aba</code> , <code>baa</code> , <code>baa</code> ), pero solo 2 de ellas ( <code>aba</code> y <code>aba</code> ) no tienen la misma letra (en este caso, <code>a</code> ) repitiendo.
|
||||
Recuerda usar <a href='http://forum.freecodecamp.org/t/how-to-get-help-when-you-are-stuck/19514' target='_blank'>Read-Search-Ask</a> si te atascas. Trate de emparejar el programa. Escribe tu propio código.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>permAlone("aab")</code> debe devolver un número.
|
||||
testString: 'assert.isNumber(permAlone("aab"), "<code>permAlone("aab")</code> should return a number.");'
|
||||
- text: <code>permAlone("aab")</code> debe devolver 2.
|
||||
testString: 'assert.strictEqual(permAlone("aab"), 2, "<code>permAlone("aab")</code> should return 2.");'
|
||||
- text: <code>permAlone("aaa")</code> debe devolver 0.
|
||||
testString: 'assert.strictEqual(permAlone("aaa"), 0, "<code>permAlone("aaa")</code> should return 0.");'
|
||||
- text: <code>permAlone("aabb")</code> debe devolver 8.
|
||||
testString: 'assert.strictEqual(permAlone("aabb"), 8, "<code>permAlone("aabb")</code> should return 8.");'
|
||||
- text: <code>permAlone("abcdefa")</code> debe devolver 3600.
|
||||
testString: 'assert.strictEqual(permAlone("abcdefa"), 3600, "<code>permAlone("abcdefa")</code> should return 3600.");'
|
||||
- text: <code>permAlone("abfdefa")</code> debe devolver 2640.
|
||||
testString: 'assert.strictEqual(permAlone("abfdefa"), 2640, "<code>permAlone("abfdefa")</code> should return 2640.");'
|
||||
- text: <code>permAlone("zzzzzzzz")</code> debe devolver 0.
|
||||
testString: 'assert.strictEqual(permAlone("zzzzzzzz"), 0, "<code>permAlone("zzzzzzzz")</code> should return 0.");'
|
||||
- text: <code>permAlone("a")</code> debe devolver 1.
|
||||
testString: 'assert.strictEqual(permAlone("a"), 1, "<code>permAlone("a")</code> should return 1.");'
|
||||
- text: <code>permAlone("aaab")</code> debe devolver 0.
|
||||
testString: 'assert.strictEqual(permAlone("aaab"), 0, "<code>permAlone("aaab")</code> should return 0.");'
|
||||
- text: <code>permAlone("aaabb")</code> debe devolver 12.
|
||||
testString: 'assert.strictEqual(permAlone("aaabb"), 12, "<code>permAlone("aaabb")</code> should return 12.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function permAlone(str) {
|
||||
return str;
|
||||
}
|
||||
|
||||
permAlone('aab');
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
function permAlone(str) {
|
||||
return permutor(str).filter(function(perm) {
|
||||
return !perm.match(/(.)\1/g);
|
||||
}).length;
|
||||
}
|
||||
|
||||
function permutor(str) {
|
||||
// http://staff.roguecc.edu/JMiller/JavaScript/permute.html
|
||||
//permArr: Global array which holds the list of permutations
|
||||
//usedChars: Global utility array which holds a list of "currently-in-use" characters
|
||||
var permArr = [], usedChars = [];
|
||||
function permute(input) {
|
||||
//convert input into a char array (one element for each character)
|
||||
var i, ch, chars = input.split("");
|
||||
for (i = 0; i < chars.length; i++) {
|
||||
//get and remove character at index "i" from char array
|
||||
ch = chars.splice(i, 1);
|
||||
//add removed character to the end of used characters
|
||||
usedChars.push(ch);
|
||||
//when there are no more characters left in char array to add, add used chars to list of permutations
|
||||
if (chars.length === 0) permArr[permArr.length] = usedChars.join("");
|
||||
//send characters (minus the removed one from above) from char array to be permuted
|
||||
permute(chars.join(""));
|
||||
//add removed character back into char array in original position
|
||||
chars.splice(i, 0, ch);
|
||||
//remove the last character used off the end of used characters array
|
||||
usedChars.pop();
|
||||
}
|
||||
}
|
||||
permute(str);
|
||||
return permArr;
|
||||
}
|
||||
|
||||
permAlone('aab');
|
||||
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,89 @@
|
||||
---
|
||||
id: a3f503de51cfab748ff001aa
|
||||
title: Pairwise
|
||||
localeTitle: Por pares
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Dado una matriz <code>arr</code> , encuentre pares de elementos cuya suma sea igual al segundo argumento <code>arg</code> y devuelva la suma de sus índices.
|
||||
Puede usar varios pares que tengan los mismos elementos numéricos pero diferentes índices. Cada par debe usar los índices disponibles más bajos posibles. Una vez que se ha utilizado un elemento, no puede reutilizarse para emparejarse con otro elemento. Por ejemplo, por <code>pairwise([1, 1, 2], 3)</code> crea un par <code>[2, 1]</code> usando el 1 en el índice 0 en lugar del 1 en el índice 1, porque 0 + 2 <1 + 2.
|
||||
Por ejemplo, por <code>pairwise([7, 9, 11, 13, 15], 20)</code> devuelve <code>6</code> . Los pares que suman 20 son <code>[7, 13]</code> y <code>[9, 11]</code> . Luego podemos escribir la matriz con sus índices y valores.
|
||||
<table class="table"><tr><th> <strong>Índice</strong> </th><th> 0 </th><th> 1 </th><th> 2 </th><th> 3 </th><th> 4 </th></tr><tr><td> Valor </td><td> 7 </td><td> 9 </td><td> 11 </td><td> 13 </td><td> 15 </td></tr></table>
|
||||
A continuación tomaremos sus índices correspondientes y los añadiremos.
|
||||
7 + 13 = 20 → Índices 0 + 3 = 3 <br> 9 + 11 = 20 → Índices 1 + 2 = 3 <br> 3 + 3 = 6 → Volver <code>6</code>
|
||||
Recuerda usar <a href='http://forum.freecodecamp.org/t/how-to-get-help-when-you-are-stuck/19514' target='_blank'>Read-Search-Ask</a> si te atascas. Trate de emparejar el programa. Escribe tu propio código.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: ' <code>pairwise([1, 4, 2, 3, 0, 5], 7)</code> debe devolver 11.'
|
||||
testString: 'assert.deepEqual(pairwise([1, 4, 2, 3, 0, 5], 7), 11, "<code>pairwise([1, 4, 2, 3, 0, 5], 7)</code> should return 11.");'
|
||||
- text: ' <code>pairwise([1, 3, 2, 4], 4)</code> debe devolver 1.'
|
||||
testString: 'assert.deepEqual(pairwise([1, 3, 2, 4], 4), 1, "<code>pairwise([1, 3, 2, 4], 4)</code> should return 1.");'
|
||||
- text: ' <code>pairwise([1, 1, 1], 2)</code> debe devolver 1.'
|
||||
testString: 'assert.deepEqual(pairwise([1, 1, 1], 2), 1, "<code>pairwise([1, 1, 1], 2)</code> should return 1.");'
|
||||
- text: ' <code>pairwise([0, 0, 0, 0, 1, 1], 1)</code> debe devolver 10.'
|
||||
testString: 'assert.deepEqual(pairwise([0, 0, 0, 0, 1, 1], 1), 10, "<code>pairwise([0, 0, 0, 0, 1, 1], 1)</code> should return 10.");'
|
||||
- text: ' <code>pairwise([], 100)</code> debe devolver 0.'
|
||||
testString: 'assert.deepEqual(pairwise([], 100), 0, "<code>pairwise([], 100)</code> should return 0.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function pairwise(arr, arg) {
|
||||
return arg;
|
||||
}
|
||||
|
||||
pairwise([1,4,2,3,0,5], 7);
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
function pairwise(arr, arg) {
|
||||
var sum = 0;
|
||||
arr.forEach(function(e, i, a) {
|
||||
if (e != null) {
|
||||
var diff = arg-e;
|
||||
a[i] = null;
|
||||
var dix = a.indexOf(diff);
|
||||
if (dix !== -1) {
|
||||
sum += dix;
|
||||
sum += i;
|
||||
a[dix] = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
return sum;
|
||||
}
|
||||
|
||||
pairwise([1,4,2,3,0,5], 7);
|
||||
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,114 @@
|
||||
---
|
||||
id: 587d8257367417b2b2512c7b
|
||||
title: Add a New Element to a Binary Search Tree
|
||||
localeTitle: Agregar un nuevo elemento a un árbol de búsqueda binario
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Ahora que tenemos una idea de lo básico, escribamos un método más complejo.
|
||||
En este desafío, crearemos un método para agregar nuevos valores a nuestro árbol de búsqueda binario. El método debe llamarse <code>add</code> y debe aceptar un valor entero para agregarlo al árbol. Tenga cuidado de mantener el invariante de un árbol de búsqueda binario: el valor en cada elemento secundario izquierdo debe ser menor o igual que el valor principal, y el valor en cada elemento secundario derecho debe ser mayor o igual que el valor principal. Aquí, hagamos que nuestro árbol no pueda contener valores duplicados. Si intentamos agregar un valor que ya existe, el método debe devolver <code>null</code> . De lo contrario, si la adición es exitosa, se debe devolver <code>undefined</code> .
|
||||
Sugerencia: ¡los árboles son naturalmente estructuras de datos recursivas!
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: La estructura de datos <code>BinarySearchTree</code> existe.
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() }; return (typeof test == "object")})(), "The <code>BinarySearchTree</code> data structure exists.");'
|
||||
- text: El árbol de búsqueda binario tiene un método llamado <code>add</code> .
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; return (typeof test.add == "function")})(), "The binary search tree has a method called <code>add</code>.");'
|
||||
- text: El método add agrega elementos de acuerdo con las reglas del árbol de búsqueda binario.
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; if (typeof test.add !== "function") { return false; }; test.add(4); test.add(1); test.add(7); test.add(87); test.add(34); test.add(45); test.add(73); test.add(8); const expectedResult = [ 1, 4, 7, 8, 34, 45, 73, 87 ]; const result = test.inOrder(); return (expectedResult.toString() === result.toString()); })(), "The add method adds elements according to the binary search tree rules.");'
|
||||
- text: Añadiendo un elemento que ya existe devuelve <code>null</code>
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; if (typeof test.add !== "function") { return false; }; test.add(4); return test.add(4) == null; })(), "Adding an element that already exists returns <code>null</code>");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
var displayTree = (tree) => console.log(JSON.stringify(tree, null, 2));
|
||||
function Node(value) {
|
||||
this.value = value;
|
||||
this.left = null;
|
||||
this.right = null;
|
||||
}
|
||||
function BinarySearchTree() {
|
||||
this.root = null;
|
||||
// change code below this line
|
||||
// change code above this line
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
console.info('after the test');
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
function Node(value) {
|
||||
this.value = value;
|
||||
this.left = null;
|
||||
this.right = null;
|
||||
}
|
||||
function BinarySearchTree() {
|
||||
this.root = null;
|
||||
this.add = function (element) {
|
||||
let current = this.root;
|
||||
if (!current) {
|
||||
this.root = new Node(element)
|
||||
return;
|
||||
} else {
|
||||
const searchTree = function (current) {
|
||||
if (current.value > element) {
|
||||
if (current.left) { //si existe
|
||||
return searchTree(current.left)
|
||||
} else {
|
||||
current.left = new Node(element);
|
||||
return;
|
||||
}
|
||||
} else if (current.value < element) {
|
||||
if (current.right) {
|
||||
return searchTree(current.right)
|
||||
} else {
|
||||
current.right = new Node(element)
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return searchTree(current);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,99 @@
|
||||
---
|
||||
id: 587d8252367417b2b2512c67
|
||||
title: Add Elements at a Specific Index in a Linked List
|
||||
localeTitle: Agregar elementos a un índice específico en una lista enlazada
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Vamos a crear un método addAt (índice, elemento) que agregue un elemento a un índice dado.
|
||||
Al igual que con la forma en que eliminamos los elementos en un índice determinado, debemos realizar un seguimiento del índice actual mientras recorremos la lista enlazada. Cuando el currentIndex coincida con el índice dado, deberíamos reasignar la siguiente propiedad del nodo anterior para hacer referencia al nuevo nodo agregado. Y el nuevo nodo debe hacer referencia al siguiente nodo en el currentIndex.
|
||||
Volviendo al ejemplo de la línea de conga, una nueva persona quiere unirse a la línea, pero quiere unirse en el medio. Estás en el medio de la línea, así que quitas las manos de la persona que está delante de ti. La nueva persona se acerca y pone sus manos sobre la persona que una vez tuvo, y ahora tiene las manos sobre la nueva persona.
|
||||
Instrucciones
|
||||
Crea un método addAt (índice, elemento) que agregue un elemento a un índice determinado. Devuelve false si un elemento no se pudo agregar.
|
||||
Nota
|
||||
Recuerde verificar si el índice dado es negativo o más largo que la longitud de la lista enlazada.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: Su método <code>addAt</code> debe reasignar la <code>head</code> al nuevo nodo cuando el índice dado sea 0.
|
||||
testString: 'assert((function(){var test = new LinkedList(); test.add("cat"); test.add("dog"); test.addAt(0,"cat"); return test.head().element === "cat"}()), "Your <code>addAt</code> method should reassign <code>head</code> to the new node when the given index is 0.");'
|
||||
- text: Su método <code>addAt</code> debe aumentar la longitud de la lista vinculada en uno por cada nuevo nodo agregado a la lista vinculada.
|
||||
testString: 'assert((function(){var test = new LinkedList(); test.add("cat"); test.add("dog"); test.addAt(0,"cat"); return test.size() === 3}()), "Your <code>addAt</code> method should increase the length of the linked list by one for each new node added to the linked list.");'
|
||||
- text: Su método <code>addAt</code> debería devolver <code>false</code> si no se pudo agregar un nodo.
|
||||
testString: 'assert((function(){var test = new LinkedList(); test.add("cat"); test.add("dog"); return (test.addAt(4,"cat") === false); }()), "Your <code>addAt</code> method should return <code>false</code> if a node was unable to be added.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function LinkedList() {
|
||||
var length = 0;
|
||||
var head = null;
|
||||
|
||||
var Node = function(element){
|
||||
this.element = element;
|
||||
this.next = null;
|
||||
};
|
||||
|
||||
this.size = function(){
|
||||
return length;
|
||||
};
|
||||
|
||||
this.head = function(){
|
||||
return head;
|
||||
};
|
||||
|
||||
this.add = function(element){
|
||||
var node = new Node(element);
|
||||
if(head === null){
|
||||
head = node;
|
||||
} else {
|
||||
currentNode = head;
|
||||
|
||||
while(currentNode.next){
|
||||
currentNode = currentNode.next;
|
||||
}
|
||||
|
||||
currentNode.next = node;
|
||||
}
|
||||
|
||||
length++;
|
||||
};
|
||||
|
||||
// Only change code below this line
|
||||
|
||||
// Only change code above this line
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,70 @@
|
||||
---
|
||||
id: 587d8256367417b2b2512c77
|
||||
title: Adjacency List
|
||||
localeTitle: Lista de adyacencia
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
gráficas se pueden representar de diferentes maneras. Aquí describimos una forma, que se llama una <dfn>lista de adyacencia</dfn> .
|
||||
Una lista de adyacencia es esencialmente una lista con viñetas donde el lado izquierdo es el nodo y el lado derecho enumera todos los otros nodos a los que está conectado. A continuación se muestra una representación de una lista de adyacencia.
|
||||
<blockquote>Node1: Node2, Node3<br>Node2: Node1<br>Node3: Node1</blockquote>
|
||||
Arriba hay un gráfico no dirigido porque <code>Node1</code> está conectado a <code>Node2</code> y <code>Node3</code> , y esa información es consistente con las conexiones que muestran <code>Node2</code> y <code>Node3</code> . Una lista de adyacencia para un gráfico dirigido significaría que cada fila de la lista muestra la dirección. Si se dirigió lo anterior, entonces <code>Node2: Node1</code> significaría que el borde dirigido apunta desde <code>Node2</code> hacia <code>Node1</code> .
|
||||
Podemos representar el gráfico no dirigido arriba como una lista de adyacencia colocándolo dentro de un objeto de JavaScript.
|
||||
<blockquote>var undirectedG = {<br> Node1: ["Node2", "Node3"],<br> Node2: ["Node1"],<br> Node3: ["Node1"]<br>};</blockquote>
|
||||
Esto también puede representarse más simplemente como una matriz donde los nodos solo tienen números en lugar de etiquetas de cadena.
|
||||
<blockquote>var undirectedGArr = [<br> [1, 2], # Node1<br> [0], # Node2<br> [0] # Node3<br>];</blockquote>
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
Cree una red social como un gráfico no dirigido con 4 nodos / personas llamadas <code>James</code> , <code>Jill</code> , <code>Jenny</code> y <code>Jeff</code> . Hay bordes / relaciones entre James y Jeff, Jill y Jenny, y Jeff y Jenny.
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>undirectedAdjList</code> solo debe contener cuatro nodos.
|
||||
testString: 'assert(Object.keys(undirectedAdjList).length === 4, "<code>undirectedAdjList</code> should only contain four nodes.");'
|
||||
- text: Debería haber una ventaja entre <code>Jeff</code> y <code>James</code> .
|
||||
testString: 'assert(undirectedAdjList.James.indexOf("Jeff") !== -1 && undirectedAdjList.Jeff.indexOf("James") !== -1, "There should be an edge between <code>Jeff</code> and <code>James</code>.");'
|
||||
- text: Debe haber una ventaja entre <code>Jill</code> y <code>Jenny</code> .
|
||||
testString: 'assert(undirectedAdjList.Jill.indexOf("Jenny") !== -1 && undirectedAdjList.Jill.indexOf("Jenny") !== -1, "There should be an edge between <code>Jill</code> and <code>Jenny</code>.");'
|
||||
- text: Debería haber una ventaja entre <code>Jeff</code> y <code>Jenny</code> .
|
||||
testString: 'assert(undirectedAdjList.Jeff.indexOf("Jenny") !== -1 && undirectedAdjList.Jenny.indexOf("Jeff") !== -1, "There should be an edge between <code>Jeff</code> and <code>Jenny</code>.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
var undirectedAdjList = {
|
||||
};
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
var undirectedAdjList = {
|
||||
"James": ["Jeff"],"Jill": ["Jenny"],"Jenny": ["Jill", "Jeff"],
|
||||
"Jeff": ["James", "Jenny"]
|
||||
};
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,71 @@
|
||||
---
|
||||
id: 587d8256367417b2b2512c78
|
||||
title: Adjacency Matrix
|
||||
localeTitle: Matriz de adyacencia
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Otra forma de representar una gráfica es ponerla en una <dfn>matriz de adyacencia</dfn> .
|
||||
Una <dfn>matriz de adyacencia</dfn> es una <dfn>matriz</dfn> bidimensional (2D) donde cada matriz anidada tiene el mismo número de elementos que la matriz externa. En otras palabras, es una matriz o cuadrícula de números, donde los números representan los bordes. Los ceros significan que no hay ventaja o relación.
|
||||
<blockquote> 1 2 3<br> ------<br>1 | 0 1 1<br>2 | 1 0 0<br>3 | 1 0 0</blockquote>
|
||||
Arriba hay un gráfico muy simple, no dirigido, donde tiene tres nodos, donde el primer nodo está conectado al segundo y tercer nodo. <strong>Nota</strong> : Los números en la parte superior e izquierda de la matriz son solo etiquetas para los nodos.
|
||||
A continuación se muestra una implementación de JavaScript de la misma cosa.
|
||||
<blockquote>var adjMat = [<br> [0, 1, 1],<br> [1, 0, 0],<br> [1, 0, 0]<br>];</blockquote>
|
||||
A diferencia de una lista de adyacencia, cada "fila" de la matriz debe tener el mismo número de elementos que los nodos en el gráfico. Aquí tenemos una matriz de tres por tres, lo que significa que tenemos tres nodos en nuestro gráfico.
|
||||
Una gráfica dirigida se vería similar. A continuación se muestra un gráfico donde el primer nodo tiene un borde que apunta hacia el segundo nodo, y luego el segundo nodo tiene un borde que apunta al tercer nodo.
|
||||
<blockquote>var adjMatDirected = [<br> [0, 1, 0],<br> [0, 0, 1],<br> [0, 0, 0]<br>];</blockquote>
|
||||
gráficos también pueden tener <dfn>pesos</dfn> en sus bordes. Hasta ahora, tenemos bordes <dfn>no ponderados</dfn> donde solo la presencia y la falta de borde es binaria ( <code>0</code> o <code>1</code> ). Puede tener diferentes pesos dependiendo de su aplicación.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
Cree una matriz de adyacencia de un gráfico no dirigido con cinco nodos. Esta matriz debe estar en una matriz multidimensional. Estos cinco nodos tienen relaciones entre el primer y cuarto nodo, el primer y tercer nodo, el tercer y quinto nodo y el cuarto y quinto nodo. Todos los pesos de los bordes son uno.
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>undirectedAdjList</code> solo debe contener cinco nodos.
|
||||
testString: 'assert((adjMatUndirected.length === 5) && adjMatUndirected.map(function(x) { return x.length === 5 }).reduce(function(a, b) { return a && b }) , "<code>undirectedAdjList</code> should only contain five nodes.");'
|
||||
- text: Debe haber un borde entre el primer y cuarto nodo.
|
||||
testString: 'assert((adjMatUndirected[0][3] === 1) && (adjMatUndirected[3][0] === 1), "There should be an edge between the first and fourth node.");'
|
||||
- text: Debe haber un borde entre el primer y tercer nodo.
|
||||
testString: 'assert((adjMatUndirected[0][2] === 1) && (adjMatUndirected[2][0] === 1), "There should be an edge between the first and third node.");'
|
||||
- text: Debe haber un borde entre el tercer y quinto nodo.
|
||||
testString: 'assert((adjMatUndirected[2][4] === 1) && (adjMatUndirected[4][2] === 1), "There should be an edge between the third and fifth node.");'
|
||||
- text: Debe haber un borde entre el cuarto y quinto nodo.
|
||||
testString: 'assert((adjMatUndirected[3][4] === 1) && (adjMatUndirected[4][3] === 1), "There should be an edge between the fourth and fifth node.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
var adjMatUndirected = [
|
||||
];
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
var adjMatUndirected = [[0, 0, 1, 1, 0],[0, 0, 0, 0, 0],[1, 0, 0, 0, 1],[1, 0, 0, 0, 1],[0, 0, 1, 1, 0]];
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,119 @@
|
||||
---
|
||||
id: 587d825c367417b2b2512c90
|
||||
title: Breadth-First Search
|
||||
localeTitle: Búsqueda de amplitud
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Hasta ahora, hemos aprendido diferentes formas de crear representaciones de gráficos. ¿Ahora que? Una pregunta natural que se debe tener es ¿cuáles son las distancias entre dos nodos en el gráfico? Introduzca los <dfn>algoritmos de recorrido del gráfico</dfn> .
|
||||
<dfn>algoritmos de recorrido</dfn> son algoritmos para atravesar o visitar los nodos en un gráfico. Un tipo de algoritmo de recorrido es el primer algoritmo de búsqueda.
|
||||
Este algoritmo comienza en un nodo, primero visita a todos sus vecinos que están a un borde de distancia, luego continúa visitando a cada uno de sus vecinos.
|
||||
Visualmente, esto es lo que hace el algoritmo.
|
||||
<img class='img-responsive' src='https://camo.githubusercontent.com/2f57e6239884a1a03402912f13c49555dec76d06/68747470733a2f2f75706c6f61642e77696b696d656469612e6f72672f77696b6970656469612f636f6d6d6f6e732f342f34362f416e696d617465645f4246532e676966'>
|
||||
Para implementar este algoritmo, deberá ingresar una estructura de gráfico y un nodo en el que desee comenzar.
|
||||
Primero, querrá estar al tanto de las distancias desde el nodo de inicio. Esto querrá comenzar todas sus distancias, inicialmente un número grande, como <code>Infinity</code> . Esto proporciona una referencia para el caso en el que no se puede acceder a un nodo desde su nodo de inicio.
|
||||
A continuación, querrá ir desde el nodo de inicio a sus vecinos. Estos vecinos están a un borde de distancia y en este punto debes agregar una unidad de distancia a las distancias que estás siguiendo.
|
||||
último, la cola es una estructura de datos importante que ayudará a implementar el primer algoritmo de búsqueda. Esta es una matriz donde puede agregar elementos a un extremo y eliminar elementos del otro extremo. Esto también se conoce como estructura de datos <dfn>FIFO</dfn> o <dfn>primero en entrar, primero en salir</dfn> .
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
Escriba una función <code>bfs()</code> que tome un gráfico de matriz de adyacencia (una matriz bidimensional) y una raíz de etiqueta de nodo como parámetros. La etiqueta del nodo solo será el valor entero del nodo entre <code>0</code> y <code>n - 1</code> , donde <code>n</code> es el número total de nodos en el gráfico.
|
||||
Su función dará salida a un objeto JavaScript pares de clave-valor con el nodo y su distancia desde la raíz. Si no se pudo alcanzar el nodo, debería tener una distancia de <code>Infinity</code> .
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: 'El gráfico de entrada <code>[[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 1], [0, 0, 1, 0]]</code> con un nodo de inicio de <code>1</code> debe devolver <code>{0: 1, 1: 0, 2: 1, 3: 2}</code> '
|
||||
testString: 'assert((function() { var graph = [[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 1], [0, 0, 1, 0]]; var results = bfs(graph, 1); return isEquivalent(results, {0: 1, 1: 0, 2: 1, 3: 2})})(), "The input graph <code>[[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 1], [0, 0, 1, 0]]</code> with a start node of <code>1</code> should return <code>{0: 1, 1: 0, 2: 1, 3: 2}</code>");'
|
||||
- text: 'El gráfico de entrada <code>[[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 0]]</code> con un nodo de inicio de <code>1</code> debería devolver <code>{0: 1, 1: 0, 2: 1, 3: Infinity}</code> '
|
||||
testString: 'assert((function() { var graph = [[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 0]]; var results = bfs(graph, 1); return isEquivalent(results, {0: 1, 1: 0, 2: 1, 3: Infinity})})(), "The input graph <code>[[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 0]]</code> with a start node of <code>1</code> should return <code>{0: 1, 1: 0, 2: 1, 3: Infinity}</code>");'
|
||||
- text: 'El gráfico de entrada <code>[[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 1], [0, 0, 1, 0]]</code> con un nodo de inicio de <code>0</code> debe devolver <code>{0: 0, 1: 1, 2: 2, 3: 3}</code> '
|
||||
testString: 'assert((function() { var graph = [[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 1], [0, 0, 1, 0]]; var results = bfs(graph, 0); return isEquivalent(results, {0: 0, 1: 1, 2: 2, 3: 3})})(), "The input graph <code>[[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 1], [0, 0, 1, 0]]</code> with a start node of <code>0</code> should return <code>{0: 0, 1: 1, 2: 2, 3: 3}</code>");'
|
||||
- text: 'El gráfico de entrada <code>[[0, 1], [1, 0]]</code> con un nodo de inicio de <code>0</code> debe devolver <code>{0: 0, 1: 1}</code> '
|
||||
testString: 'assert((function() { var graph = [[0, 1], [1, 0]]; var results = bfs(graph, 0); return isEquivalent(results, {0: 0, 1: 1})})(), "The input graph <code>[[0, 1], [1, 0]]</code> with a start node of <code>0</code> should return <code>{0: 0, 1: 1}</code>");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function bfs(graph, root) {
|
||||
// Distance object returned
|
||||
var nodesLen = {};
|
||||
|
||||
return nodesLen;
|
||||
};
|
||||
|
||||
var exBFSGraph = [
|
||||
[0, 1, 0, 0],
|
||||
[1, 0, 1, 0],
|
||||
[0, 1, 0, 1],
|
||||
[0, 0, 1, 0]
|
||||
];
|
||||
console.log(bfs(exBFSGraph, 3));
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
console.info('after the test');
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
function bfs(graph, root) {
|
||||
// Distance object returned
|
||||
var nodesLen = {};
|
||||
// Set all distances to infinity
|
||||
for (var i = 0; i < graph.length; i++) {
|
||||
nodesLen[i] = Infinity;
|
||||
}
|
||||
nodesLen[root] = 0; // ...except root node
|
||||
var queue = [root]; // Keep track of nodes to visit
|
||||
var current; // Current node traversing
|
||||
// Keep on going until no more nodes to traverse
|
||||
while (queue.length !== 0) {
|
||||
current = queue.shift();
|
||||
// Get adjacent nodes from current node
|
||||
var curConnected = graph[current]; // Get layer of edges from current
|
||||
var neighborIdx = []; // List of nodes with edges
|
||||
var idx = curConnected.indexOf(1); // Get first edge connection
|
||||
while (idx !== -1) {
|
||||
neighborIdx.push(idx); // Add to list of neighbors
|
||||
idx = curConnected.indexOf(1, idx + 1); // Keep on searching
|
||||
}
|
||||
// Loop through neighbors and get lengths
|
||||
for (var j = 0; j < neighborIdx.length; j++) {
|
||||
// Increment distance for nodes traversed
|
||||
if (nodesLen[neighborIdx[j]] === Infinity) {
|
||||
nodesLen[neighborIdx[j]] = nodesLen[current] + 1;
|
||||
queue.push(neighborIdx[j]); // Add new neighbors to queue
|
||||
}
|
||||
}
|
||||
}
|
||||
return nodesLen;}
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,77 @@
|
||||
---
|
||||
id: 587d8257367417b2b2512c7c
|
||||
title: Check if an Element is Present in a Binary Search Tree
|
||||
localeTitle: Compruebe si un elemento está presente en un árbol de búsqueda binario
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Ahora que tenemos una idea general de lo que es un árbol de búsqueda binario, hablemos de ello con un poco más de detalle. Los árboles de búsqueda binarios proporcionan tiempo logarítmico para las operaciones comunes de búsqueda, inserción y eliminación en el caso promedio, y el tiempo lineal en el peor de los casos. ¿Por qué es esto? Cada una de esas operaciones básicas nos obliga a encontrar un elemento en el árbol (o en el caso de la inserción para encontrar dónde debe ir) y debido a la estructura de árbol en cada nodo principal, estamos bifurcando a la izquierda o la derecha y excluyendo efectivamente la mitad del tamaño del árbol restante. Esto hace que la búsqueda sea proporcional al logaritmo del número de nodos en el árbol, lo que crea el tiempo logarítmico para estas operaciones en el caso promedio.
|
||||
Ok, pero ¿qué pasa con el peor de los casos? Bueno, considere construir un árbol a partir de los siguientes valores, agregándolos de izquierda a derecha: <code>10</code> , <code>12</code> , <code>17</code> , <code>25</code> . Siguiendo nuestras reglas para un árbol de búsqueda binario, agregaremos <code>12</code> a la derecha de <code>10</code> , <code>17</code> a la derecha de este, y <code>25</code> a la derecha de este. Ahora nuestro árbol se asemeja a una lista enlazada y recorrerla para encontrar <code>25</code> requeriría que recorriéramos todos los elementos de manera lineal. Por lo tanto, el tiempo lineal en el peor de los casos. El problema aquí es que el árbol está desequilibrado. Veremos un poco más sobre lo que esto significa en los siguientes desafíos.
|
||||
Instrucciones: En este desafío, crearemos una utilidad para nuestro árbol. Escriba un método <code>isPresent</code> que toma un valor entero como entrada y devuelve un valor booleano para la presencia o ausencia de ese valor en el árbol de búsqueda binario.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: La estructura de datos <code>BinarySearchTree</code> existe.
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() }; return (typeof test == "object")})(), "The <code>BinarySearchTree</code> data structure exists.");'
|
||||
- text: El árbol de búsqueda binario tiene un método llamado <code>isPresent</code> .
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; return (typeof test.isPresent == "function")})(), "The binary search tree has a method called <code>isPresent</code>.");'
|
||||
- text: El método <code>isPresent</code> verifica correctamente la presencia o ausencia de elementos agregados al árbol.
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; if (typeof test.isPresent !== "function") { return false; }; test.add(4); test.add(7); test.add(411); test.add(452); return ( test.isPresent(452) && test.isPresent(411) && test.isPresent(7) && !test.isPresent(100) ); })(), "The <code>isPresent</code> method correctly checks for the presence or absence of elements added to the tree.");'
|
||||
- text: <code>isPresent</code> maneja casos donde el árbol está vacío.
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; if (typeof test.isPresent !== "function") { return false; }; return test.isPresent(5) == false; })(), "<code>isPresent</code> handles cases where the tree is empty.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
var displayTree = (tree) => console.log(JSON.stringify(tree, null, 2));
|
||||
function Node(value) {
|
||||
this.value = value;
|
||||
this.left = null;
|
||||
this.right = null;
|
||||
}
|
||||
function BinarySearchTree() {
|
||||
this.root = null;
|
||||
// change code below this line
|
||||
// change code above this line
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
console.info('after the test');
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,144 @@
|
||||
---
|
||||
id: 587d8255367417b2b2512c75
|
||||
title: Create a Circular Queue
|
||||
localeTitle: Crear una cola circular
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
En este desafío estarás creando una Cola Circular. Una cola circular es básicamente una cola que se escribe al final de una colección y luego comienza a escribirse al principio de la colección. Este es un tipo de estructura de datos que tiene algunas aplicaciones útiles en ciertas situaciones. Por ejemplo, una cola circular se puede utilizar para transmitir medios. Una vez que la cola está llena, los nuevos datos de medios simplemente comienzan a sobrescribir los datos antiguos.
|
||||
Una buena manera de ilustrar este concepto es con una matriz:
|
||||
<blockquote>[1, 2, 3, 4, 5]<br> ^Read @ 0<br> ^Write @ 0</blockquote>
|
||||
Aquí tanto la lectura como la escritura están en la posición <code>0</code> . Ahora la cola obtiene 3 nuevos registros <code>a</code> , <code>b</code> , y <code>c</code> . Nuestra cola ahora se ve como:
|
||||
<blockquote>[a, b, c, 4, 5]<br> ^Read @ 0<br> ^Write @ 3</blockquote>
|
||||
Mientras la cabeza de lectura lee, puede eliminar valores o mantenerlos:
|
||||
<blockquote>[null, null, null, 4, 5]<br> ^Read @ 3<br> ^Write @ 3</blockquote>
|
||||
Una vez que la escritura llega al final de la matriz, vuelve al principio:
|
||||
<blockquote>[f, null, null, d, e]<br> ^Read @ 3<br> ^Write @ 1</blockquote>
|
||||
Este enfoque requiere una cantidad constante de memoria, pero permite procesar archivos de un tamaño mucho mayor.
|
||||
Instrucciones:
|
||||
En este desafío implementaremos una cola circular. La cola circular debe proporcionar métodos de <code>dequeue</code> <code>enqueue</code> y <code>dequeue</code> <code>enqueue</code> que le permitan leer y escribir en la cola. La clase en sí también debe aceptar un número entero que puede usar para especificar el tamaño de la cola cuando la cree. Hemos escrito la versión inicial de esta clase para usted en el editor de código. Cuando pone en cola elementos en la cola, el puntero de escritura debe avanzar y volver al principio una vez que llega al final de la cola. Del mismo modo, el puntero de lectura debe avanzar hacia adelante a medida que se retiran de la cola los elementos. No se debe permitir que el puntero de escritura se mueva más allá del puntero de lectura (nuestra clase no le permitirá sobrescribir datos que aún no ha leído) y el puntero de lectura no debe poder avanzar los datos pasados que haya escrito.
|
||||
Además, el método de <code>enqueue</code> debe devolver el elemento que ha puesto en <code>enqueue</code> si tiene éxito y, de lo contrario, devolver el <code>null</code> . De manera similar, cuando saca de la cola un artículo, debe devolverse y, si no puede sacar la cola, debe devolver un <code>null</code> .
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: El método de <code>enqueue</code> agrega elementos a la cola circular.
|
||||
testString: 'assert((function(){ var test = new CircularQueue(3); test.enqueue(17); test.enqueue(32); test.enqueue(591); var print = test.print(); return print[0] === 17 && print[1] === 32 && print[2] === 591; })(), "The <code>enqueue</code> method adds items to the circular queue.");'
|
||||
- text: No puede poner en cola elementos más allá del puntero de lectura.
|
||||
testString: 'assert((function(){ var test = new CircularQueue(3); test.enqueue(17); test.enqueue(32); test.enqueue(591); test.enqueue(13); test.enqueue(25); test.enqueue(59); var print = test.print(); return print[0] === 17 && print[1] === 32 && print[2] === 591; })(), "You cannot enqueue items past the read pointer.");'
|
||||
- text: La <code>dequeue</code> método de Retiros de cola elementos de la cola.
|
||||
testString: 'assert((function(){ var test = new CircularQueue(3); test.enqueue(17); test.enqueue(32); test.enqueue(591); return test.dequeue() === 17 && test.dequeue() === 32 && test.dequeue() === 591; })(), "The <code>dequeue</code> method dequeues items from the queue.");'
|
||||
- text: Después de que un elemento se haya retirado de su posición en la cola, se debe restablecer en <code>null</code> .
|
||||
testString: 'assert((function(){ var test = new CircularQueue(3); test.enqueue(17); test.enqueue(32); test.enqueue(672); test.dequeue(); test.dequeue(); var print = test.print(); return print[0] === null && print[1] === null && print[2] === 672; })(), "After an item is dequeued its position in the queue should be reset to <code>null</code>.");'
|
||||
- text: Intentar sacar de la cola más allá del puntero de escritura devuelve un <code>null</code> y no avanza el puntero de escritura.
|
||||
testString: 'assert((function(){ var test = new CircularQueue(3); test.enqueue(17); test.enqueue(32); test.enqueue(591); return test.dequeue() === 17 && test.dequeue() === 32 && test.dequeue() === 591 && test.dequeue() === null && test.dequeue() === null && test.dequeue() === null && test.dequeue() === null && test.enqueue(100) === 100 && test.dequeue() === 100; })(), "Trying to dequeue past the write pointer returns <code>null</code> and does not advance the write pointer.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
class CircularQueue {
|
||||
constructor(size) {
|
||||
|
||||
this.queue = [];
|
||||
this.read = 0;
|
||||
this.write = 0;
|
||||
this.max = size - 1;
|
||||
|
||||
while (size > 0) {
|
||||
this.queue.push(null);
|
||||
size--;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
print() {
|
||||
return this.queue;
|
||||
}
|
||||
|
||||
|
||||
enqueue(item) {
|
||||
// Only change code below this line
|
||||
|
||||
// Only change code above this line
|
||||
}
|
||||
|
||||
dequeue() {
|
||||
// Only change code below this line
|
||||
|
||||
// Only change code above this line
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
class CircularQueue {
|
||||
constructor(size) {
|
||||
this.queue = [];
|
||||
this.read = 0;
|
||||
this.write = 0;
|
||||
this.max = size - 1;
|
||||
while (size > 0) {
|
||||
this.queue.push(null);
|
||||
size--;
|
||||
}
|
||||
}
|
||||
print() {
|
||||
return this.queue;
|
||||
}
|
||||
enqueue(item) {
|
||||
if (this.queue[this.write] === null) {
|
||||
this.queue[this.write] = item;
|
||||
if (this.write === this.max) {
|
||||
this.write = 0;
|
||||
} else {
|
||||
this.write++;
|
||||
}
|
||||
return item;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
dequeue() {
|
||||
if (this.queue[this.read] !== null) {
|
||||
var item = this.queue[this.read];
|
||||
this.queue[this.read] = null;
|
||||
if (this.read === this.max) {
|
||||
this.read = 0;
|
||||
} else {
|
||||
this.read++;
|
||||
}
|
||||
return item;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,85 @@
|
||||
---
|
||||
id: 587d825a367417b2b2512c87
|
||||
title: Create a Doubly Linked List
|
||||
localeTitle: Crear una lista doblemente vinculada
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Todas las listas enlazadas que hemos creado hasta ahora son listas enlazadas individualmente. Aquí, crearemos una <dfn>lista doblemente vinculada</dfn> . Como su nombre lo indica, los nodos en una lista doblemente enlazada tienen referencias al nodo siguiente y anterior en la lista.
|
||||
Esto nos permite recorrer la lista en ambas direcciones, pero también requiere que se use más memoria porque cada nodo debe contener una referencia adicional al nodo anterior en la lista.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
Proporcionamos un objeto <code>Node</code> y comenzamos nuestra <code>DoublyLinkedList</code> . Agreguemos dos métodos a nuestra lista doblemente enlazada llamada <code>add</code> y <code>remove</code> . El <code>add</code> método debe añadir el elemento dado de la lista, mientras que el <code>remove</code> método debe eliminar todas las ocurrencias de un elemento dado en la lista.
|
||||
Tenga cuidado de manejar cualquier posible caso de borde al escribir estos métodos, como eliminaciones del primer o último elemento. Además, eliminar cualquier elemento de una lista vacía debe devolver <code>null</code> .
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: La estructura de datos DoublyLinkedList existe.
|
||||
testString: 'assert((function() { var test = false; if (typeof DoublyLinkedList !== "undefined") { test = new DoublyLinkedList() }; return (typeof test == "object")})(), "The DoublyLinkedList data structure exists.");'
|
||||
- text: DoublyLinkedList tiene un método llamado agregar.
|
||||
testString: 'assert((function() { var test = false; if (typeof DoublyLinkedList !== "undefined") { test = new DoublyLinkedList() }; if (test.add == undefined) { return false; }; return (typeof test.add == "function")})(), "The DoublyLinkedList has a method called add.");'
|
||||
- text: DoublyLinkedList tiene un método llamado eliminar.
|
||||
testString: 'assert((function() { var test = false; if (typeof DoublyLinkedList !== "undefined") { test = new DoublyLinkedList() }; if (test.remove == undefined) { return false; }; return (typeof test.remove == "function")})(), "The DoublyLinkedList has a method called remove.");'
|
||||
- text: Al eliminar un elemento de una lista vacía, se devuelve un valor nulo.
|
||||
testString: 'assert((function() { var test = false; if (typeof DoublyLinkedList !== "undefined") { test = new DoublyLinkedList() }; return (test.remove(100) == null); })(), "Removing an item from an empty list returns null.");'
|
||||
- text: El método add agrega elementos a la lista.
|
||||
testString: 'assert((function() { var test = false; if (typeof DoublyLinkedList !== "undefined") { test = new DoublyLinkedList() }; test.add(5); test.add(6); test.add(723); return (test.print().join("") == "56723"); })(), "The add method adds items to the list.");'
|
||||
- text: Cada nodo realiza un seguimiento del nodo anterior.
|
||||
testString: 'assert((function() { var test = false; if (typeof DoublyLinkedList !== "undefined") { test = new DoublyLinkedList() }; test.add(50); test.add(68); test.add(73); return (test.printReverse().join("") == "736850"); })(), "Each node keeps track of the previous node.");'
|
||||
- text: El primer elemento puede ser eliminado de la lista.
|
||||
testString: 'assert((function() { var test = false; if (typeof DoublyLinkedList !== "undefined") { test = new DoublyLinkedList() }; test.add(25); test.add(35); test.add(60); test.remove(25); return ( test.print().join("") == "3560" ) })(), "The first item can be removed from the list.");'
|
||||
- text: El último elemento puede ser eliminado de la lista.
|
||||
testString: 'assert((function() { var test = false; if (typeof DoublyLinkedList !== "undefined") { test = new DoublyLinkedList() }; test.add(25); test.add(35); test.add(60); test.remove(60); return ( test.print().join("") == "2535" ) })(), "The last item can be removed from the list.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
var Node = function(data, prev) {
|
||||
this.data = data;
|
||||
this.prev = prev;
|
||||
this.next = null;
|
||||
};
|
||||
var DoublyLinkedList = function() {
|
||||
this.head = null;
|
||||
this.tail = null;
|
||||
// change code below this line
|
||||
// change code above this line
|
||||
};
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
console.info('after the test');
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,94 @@
|
||||
---
|
||||
id: 587d825b367417b2b2512c8e
|
||||
title: Create a Hash Table
|
||||
localeTitle: Crear una tabla de hash
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
En este desafío aprenderemos sobre tablas hash. Se utiliza una tabla Hash para implementar matrices asociativas, o asignaciones de pares clave-valor, como los objetos y los mapas que acabamos de estudiar. Un objeto JavaScript podría implementarse como una tabla hash, por ejemplo (su implementación real dependerá del entorno en el que se esté ejecutando). La forma en que funciona una tabla hash es que toma una entrada clave y hace un hash de esta clave de manera determinista a algún valor numérico. Este valor numérico se utiliza como la clave real por la que se almacena el valor asociado. Luego, si intenta acceder a la misma clave nuevamente, la función de hashing procesará la clave y devolverá el mismo resultado numérico, que luego se usará para buscar el valor asociado. Esto proporciona un tiempo de búsqueda O (n) muy eficiente en promedio.
|
||||
Las tablas hash se pueden implementar como matrices con funciones hash que producen índices de matriz dentro de un rango específico. En este método, la elección del tamaño del arreglo es importante, como lo es la función de hashing. Por ejemplo, ¿qué pasa si la función de hashing produce el mismo valor para dos claves diferentes? Esto se llama una colisión. Una forma de manejar las colisiones es simplemente almacenar ambos pares clave-valor en ese índice. Luego, al buscar cualquiera de los dos, tendría que recorrer el conjunto de elementos para encontrar la clave que está buscando. Una buena función de hash minimizará las colisiones para mantener un tiempo de búsqueda eficiente.
|
||||
Aquí, no nos preocuparemos por los detalles de hashing o la implementación de tablas hash, solo intentaremos tener una idea general de cómo funcionan.
|
||||
Instrucciones: Vamos a crear la funcionalidad básica de una tabla hash. Hemos creado una función de hash ingenua para que la uses. Puede pasar un valor de cadena al hash de función y devolverá un valor hash que puede usar como clave para el almacenamiento. Almacene artículos basados en este valor hash en el objeto this.collection. Crea estos tres métodos: agregar, eliminar y buscar. El primero debe aceptar un par de valores clave para agregar a la tabla hash. El segundo debe eliminar un par clave-valor cuando se pasa una clave. El tercero debe aceptar una clave y devolver el valor asociado o nulo si la clave no está presente.
|
||||
Asegúrese de escribir su código para tener en cuenta las colisiones!
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: La estructura de datos HashTable existe.
|
||||
testString: 'assert((function() { var test = false; if (typeof HashTable !== "undefined") { test = new HashTable() }; return (typeof test === "object")})(), "The HashTable data structure exists.");'
|
||||
- text: La tabla hash tiene un método de adición.
|
||||
testString: 'assert((function() { var test = false; if (typeof HashTable !== "undefined") { test = new HashTable() }; return ((typeof test.add) === "function")})(), "The HashTable has an add method.");'
|
||||
- text: La tabla hash tiene un método de eliminación.
|
||||
testString: 'assert((function() { var test = false; if (typeof HashTable !== "undefined") { test = new HashTable() }; return ((typeof test.remove) === "function")})(), "The HashTable has an remove method.");'
|
||||
- text: El HashTable tiene un método de búsqueda.
|
||||
testString: 'assert((function() { var test = false; if (typeof HashTable !== "undefined") { test = new HashTable() }; return ((typeof test.lookup) === "function")})(), "The HashTable has an lookup method.");'
|
||||
- text: El método de agregar agrega pares de valores clave y el método de búsqueda devuelve los valores asociados con una clave dada.
|
||||
testString: 'assert((function() { var test = false; if (typeof HashTable !== "undefined") { test = new HashTable() }; test.add("key", "value"); return (test.lookup("key") === "value")})(), "The add method adds key value pairs and the lookup method returns the values associated with a given key.");'
|
||||
- text: El método de eliminación acepta una clave como entrada y elimina el par de valores de clave asociado.
|
||||
testString: 'assert((function() { var test = false; if (typeof HashTable !== "undefined") { test = new HashTable() }; test.add("key", "value"); test.remove("key"); return (test.lookup("key") === null)})(), "The remove method accepts a key as input and removes the associated key value pair.");'
|
||||
- text: Los elementos se añaden utilizando la función hash.
|
||||
testString: 'assert((function() { var test = false; if (typeof HashTable !== "undefined") { test = new HashTable() }; called = 0; test.add("key1","value1"); test.add("key2","value2"); test.add("key3","value3"); return (called === 3)})(), "Items are added using the hash function.");'
|
||||
- text: La tabla hash maneja las colisiones.
|
||||
testString: 'assert((function() { var test = false; if (typeof HashTable !== "undefined") { test = new HashTable() }; called = 0; test.add("key1","value1"); test.add("1key","value2"); test.add("ke1y","value3"); return (test.lookup("key1") === "value1" && test.lookup("1key") == "value2" && test.lookup("ke1y") == "value3")})(), "The hash table handles collisions.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
var called = 0;
|
||||
var hash = (string) => {
|
||||
called++;
|
||||
var hash = 0;
|
||||
for (var i = 0; i < string.length; i++) { hash += string.charCodeAt(i); }
|
||||
return hash;
|
||||
};
|
||||
var HashTable = function() {
|
||||
this.collection = {};
|
||||
// change code below this line
|
||||
// change code above this line
|
||||
};
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
### Before Test
|
||||
<div id='js-setup'>
|
||||
|
||||
```js
|
||||
var called = 0;
|
||||
var hash = (string) => {
|
||||
called++;
|
||||
var hash = 0;
|
||||
for (var i = 0; i < string.length; i++) { hash += string.charCodeAt(i); };
|
||||
return hash;
|
||||
};
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,84 @@
|
||||
---
|
||||
id: 587d8251367417b2b2512c62
|
||||
title: Create a Linked List Class
|
||||
localeTitle: Crear una clase de lista enlazada
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Vamos a crear una clase de <code>linked list</code> . Cada lista vinculada debe comenzar con unas pocas propiedades básicas: una <code>head</code> (el primer elemento de su lista) y una <code>length</code> (número de elementos en su lista). A veces, verás implementaciones de listas vinculadas que incorporan una <code>tail</code> para el último elemento de la lista, pero por ahora solo nos quedaremos con estos dos. Cada vez que agregamos un elemento a la lista vinculada, nuestra propiedad de <code>length</code> debe incrementarse en uno.
|
||||
Queremos tener una forma de agregar elementos a nuestra lista vinculada, por lo que el primer método que querremos crear es el método de <code>add</code> .
|
||||
Si nuestra lista está vacía, agregar un elemento a nuestra lista vinculada es lo suficientemente simple: simplemente envolvemos ese elemento en una clase de <code>Node</code> , y asignamos ese nodo al <code>head</code> de nuestra lista vinculada.
|
||||
¿Pero qué pasa si nuestra lista ya tiene uno o más miembros? ¿Cómo agregamos un elemento a la lista? Recuerde que cada nodo en una lista vinculada tiene una propiedad <code>next</code> . Para agregar un nodo a la lista, busque el último nodo en la lista y apunte la <code>next</code> propiedad del último nodo a nuestro nuevo nodo. (Sugerencia: sabe que ha llegado al final de una lista enlazada cuando la <code>next</code> propiedad de un nodo es <code>null</code> ).
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
Escriba un método de adición que asigne el primer nodo que empuja a la lista vinculada al <code>head</code> ; después de eso, cada vez que agregue un nodo, cada nodo debe ser referenciado por la <code>next</code> propiedad del nodo anterior.
|
||||
Nota
|
||||
La <code>length</code> su lista debe aumentar en uno cada vez que se agregue un elemento a la lista vinculada.
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: Su clase <code>LinkedList</code> debe tener un método de <code>add</code> .
|
||||
testString: 'assert((function(){var test = new LinkedList(); return (typeof test.add === "function")}()), "Your <code>LinkedList</code> class should have a <code>add</code> method.");'
|
||||
- text: Su clase <code>LinkedList</code> debe asignar <code>head</code> al primer nodo agregado.
|
||||
testString: 'assert((function(){var test = new LinkedList(); test.add("cat"); return test.head().element === "cat"}()), "Your <code>LinkedList</code> class should assign <code>head</code> to the first node added.");'
|
||||
- text: El <code>node</code> anterior en su clase <code>LinkedList</code> debe tener referencia al nodo más reciente creado.
|
||||
testString: 'assert((function(){var test = new LinkedList(); test.add("cat"); test.add("dog"); return test.head().next.element === "dog"}()), "The previous <code>node</code> in your <code>LinkedList</code> class should have reference to the newest node created.");'
|
||||
- text: El <code>size</code> de su clase <code>LinkedList</code> debe ser igual a la cantidad de nodos en la lista vinculada.
|
||||
testString: 'assert((function(){var test = new LinkedList(); test.add("cat"); test.add("dog"); return test.size() === 2}()), "The <code>size</code> of your <code>LinkedList</code> class should equal the amount of nodes in the linked list.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function LinkedList() {
|
||||
var length = 0;
|
||||
var head = null;
|
||||
|
||||
var Node = function(element){
|
||||
this.element = element;
|
||||
this.next = null;
|
||||
};
|
||||
|
||||
this.head = function(){
|
||||
return head;
|
||||
};
|
||||
|
||||
this.size = function(){
|
||||
return length;
|
||||
};
|
||||
|
||||
this.add = function(element){
|
||||
// Only change code below this line
|
||||
|
||||
// Only change code above this line
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,78 @@
|
||||
---
|
||||
id: 8d5823c8c441eddfaeb5bdef
|
||||
title: Create a Map Data Structure
|
||||
localeTitle: Crear una estructura de datos de mapas
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Los próximos desafíos cubrirán mapas y tablas hash. Los mapas son estructuras de datos que almacenan pares clave-valor. En JavaScript, estos están disponibles para nosotros como objetos. Los mapas proporcionan una búsqueda rápida de elementos almacenados en función de valores clave y son estructuras de datos muy comunes y útiles.
|
||||
Instrucciones: Hagamos algo de práctica creando nuestro propio mapa. Debido a que los objetos de JavaScript proporcionan una estructura de mapa mucho más eficiente que cualquier otra que podamos escribir aquí, esto está pensado principalmente como un ejercicio de aprendizaje. Sin embargo, los objetos de JavaScript solo nos proporcionan ciertas operaciones. ¿Y si quisiéramos definir operaciones personalizadas?
|
||||
Utilice el objeto <code>Map</code> que se proporciona aquí como una envoltura alrededor de un <code>object</code> JavaScript. Cree los siguientes métodos y operaciones en el objeto Mapa:
|
||||
<ul>
|
||||
<li> <code>add</code> acepta una <code>key, value</code> par de <code>key, value</code> para agregar al mapa. </li>
|
||||
<li> <code>remove</code> acepta una clave y elimina la <code>key, value</code> asociada <code>key, value</code> par de <code>key, value</code> </li>
|
||||
<li> <code>get</code> acepta una <code>key</code> y devuelve el <code>value</code> almacenado </li>
|
||||
<li> <code>has</code> acepta una <code>key</code> y devuelve <dfn>verdadero</dfn> si existe la clave o <dfn>falso</dfn> si no lo hace. </li>
|
||||
<li> <code>values</code> devuelve una matriz de todos los valores en el mapa </li>
|
||||
<li> <code>size</code> devuelve el número de elementos en el mapa </li>
|
||||
<li> <code>clear</code> vacía el mapa </li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: La estructura de datos del mapa existe.
|
||||
testString: 'assert((function() { var test = false; if (typeof Map !== "undefined") { test = new Map() }; return (typeof test == "object")})(), "The Map data structure exists.");'
|
||||
- text: 'El objeto Mapa tiene los siguientes métodos: agregar, eliminar, obtener, tiene, valores, borrar y tamaño'.
|
||||
testString: 'assert((function() { var test = false; if (typeof Map !== "undefined") { test = new Map() }; return (typeof test.add == "function" && typeof test.remove == "function" && typeof test.get == "function" && typeof test.has == "function" && typeof test.values == "function" && typeof test.clear == "function" && typeof test.size == "function")})(), "The Map object has the following methods: add, remove, get, has, values, clear, and size.");'
|
||||
- text: El método add agrega elementos al mapa.
|
||||
testString: 'assert((function() { var test = false; if (typeof Map !== "undefined") { test = new Map() }; test.add(5,6); test.add(2,3); test.add(2,5); return (test.size() == 2)})(), "The add method adds items to the map.");'
|
||||
- text: El método has devuelve true para los elementos agregados y false para los elementos ausentes.
|
||||
testString: 'assert((function() { var test = false; if (typeof Map !== "undefined") { test = new Map() }; test.add("test","value"); return (test.has("test") && !test.has("false"))})(), "The has method returns true for added items and false for absent items.");'
|
||||
- text: El método get acepta las claves como entrada y devuelve los valores asociados.
|
||||
testString: 'assert((function() { var test = false; if (typeof Map !== "undefined") { test = new Map() }; test.add("abc","def"); return (test.get("abc") == "def")})(), "The get method accepts keys as input and returns the associated values.");'
|
||||
- text: El método de valores devuelve todos los valores almacenados en el mapa como cadenas en una matriz.
|
||||
testString: 'assert((function() { var test = false; if (typeof Map !== "undefined") { test = new Map() }; test.add("a","b"); test.add("c","d"); test.add("e","f"); var vals = test.values(); return (vals.indexOf("b") != -1 && vals.indexOf("d") != -1 && vals.indexOf("f") != -1)})(), "The values method returns all the values stored in the map as strings in an array.");'
|
||||
- text: El método claro vacía el mapa y el método de tamaño devuelve el número de elementos presentes en el mapa.
|
||||
testString: 'assert((function() { var test = false; if (typeof Map !== "undefined") { test = new Map() }; test.add("b","b"); test.add("c","d"); test.remove("asdfas"); var init = test.size(); test.clear(); return (init == 2 && test.size() == 0)})(), "The clear method empties the map and the size method returns the number of items present in the map.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
var Map = function() {
|
||||
this.collection = {};
|
||||
// change code below this line
|
||||
// change code above this line
|
||||
};
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,113 @@
|
||||
---
|
||||
id: 587d8255367417b2b2512c74
|
||||
title: Create a Priority Queue Class
|
||||
localeTitle: Crear una clase de cola de prioridad
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
En este desafío crearás una cola de prioridad. Una cola de prioridad es un tipo especial de cola en la que los elementos pueden tener información adicional que especifica su prioridad. Esto podría ser representado simplemente con un número entero. La prioridad de los elementos anulará el orden de colocación para determinar si los elementos de la secuencia se eliminan. Si un elemento con una prioridad más alta se pone en cola después de los elementos con una prioridad más baja, el elemento de mayor prioridad se eliminará de la cola antes que todos los demás.
|
||||
Por ejemplo, imaginemos que tenemos una cola de prioridad con tres elementos:
|
||||
<code>[['kitten', 2], ['dog', 2], ['rabbit', 2]]</code>
|
||||
Aquí el segundo valor (un entero) representa la prioridad del elemento. Si ponemos en cola <code>['human', 1]</code> con una prioridad de <code>1</code> (suponiendo que se da prioridad a las prioridades más bajas) sería el primer elemento que se eliminará de la cola. A la colección le gustaría esto:
|
||||
<code>[['human', 1], ['kitten', 2], ['dog', 2], ['rabbit', 2]]</code> .
|
||||
Hemos empezado a escribir un <code>PriorityQueue</code> en el editor de código. Necesitará agregar un método de <code>enqueue</code> en <code>enqueue</code> para agregar elementos con una prioridad, un método de <code>dequeue</code> para eliminar elementos, un método de <code>size</code> para devolver el número de elementos en la cola, un método <code>front</code> para devolver el elemento al frente de la cola y finalmente, un método <code>isEmpty</code> que devolverá <code>true</code> si la cola está vacía o <code>false</code> si no lo está.
|
||||
La <code>enqueue</code> debe aceptar elementos con el formato que se muestra arriba ( <code>['human', 1]</code> ) donde <code>1</code> representa la prioridad. La <code>dequeue</code> debe devolver solo el elemento actual, no su prioridad.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: Su clase de <code>Queue</code> debe tener un método de <code>enqueue</code> en <code>enqueue</code> .
|
||||
testString: 'assert((function(){var test = new PriorityQueue(); return (typeof test.enqueue === "function")}()), "Your <code>Queue</code> class should have a <code>enqueue</code> method.");'
|
||||
- text: Tu clase de <code>Queue</code> debe tener un método de <code>dequeue</code> .
|
||||
testString: 'assert((function(){var test = new PriorityQueue(); return (typeof test.dequeue === "function")}()), "Your <code>Queue</code> class should have a <code>dequeue</code> method.");'
|
||||
- text: Tu clase de <code>Queue</code> debe tener un método de <code>size</code> .
|
||||
testString: 'assert((function(){var test = new PriorityQueue(); return (typeof test.size === "function")}()), "Your <code>Queue</code> class should have a <code>size</code> method.");'
|
||||
- text: Tu clase de <code>Queue</code> debe tener un método <code>isEmpty</code> .
|
||||
testString: 'assert((function(){var test = new PriorityQueue(); return (typeof test.isEmpty === "function")}()), "Your <code>Queue</code> class should have an <code>isEmpty</code> method.");'
|
||||
- text: Su PriorityQueue debe realizar un seguimiento correcto del número actual de elementos utilizando el método de <code>size</code> , ya que los elementos se ponen en cola y se eliminan de la cola.
|
||||
testString: 'assert((function(){var test = new PriorityQueue(); test.enqueue(["David Brown", 2]); test.enqueue(["Jon Snow", 1]); var size1 = test.size(); test.dequeue(); var size2 = test.size(); test.enqueue(["A", 3]); test.enqueue(["B", 3]); test.enqueue(["C", 3]); return (size1 === 2 && size2 === 1 && test.size() === 4)}()), "Your PriorityQueue should correctly keep track of the current number of items using the <code>size</code> method as items are enqueued and dequeued.");'
|
||||
- text: El método <code>isEmpty</code> debería devolver <code>true</code> cuando la cola está vacía.
|
||||
testString: 'assert((function(){var test = new PriorityQueue(); test.enqueue(["A", 1]); test.enqueue(["B", 1]); test.dequeue(); var first = test.isEmpty(); test.dequeue(); return (!first && test.isEmpty()); }()), "The <code>isEmpty</code> method should return <code>true</code> when the queue is empty.");'
|
||||
- text: La cola de prioridad debe devolver los elementos con una prioridad más alta antes de los elementos con una prioridad más baja y devolver los elementos en el orden de primero en entrar, primero en salir, de lo contrario
|
||||
testString: 'assert((function(){var test = new PriorityQueue(); test.enqueue(["A", 5]); test.enqueue(["B", 5]); test.enqueue(["C", 5]); test.enqueue(["D", 3]); test.enqueue(["E", 1]); test.enqueue(["F", 7]); var result = []; result.push(test.dequeue()); result.push(test.dequeue()); result.push(test.dequeue()); result.push(test.dequeue()); result.push(test.dequeue()); result.push(test.dequeue()); return result.join("") === "EDABCF";}()), "The priority queue should return items with a higher priority before items with a lower priority and return items in first-in-first-out order otherwise.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function PriorityQueue () {
|
||||
this.collection = [];
|
||||
this.printCollection = function() {
|
||||
console.log(this.collection);
|
||||
};
|
||||
// Only change code below this line
|
||||
|
||||
// Only change code above this line
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
function PriorityQueue () {
|
||||
this.collection = [];
|
||||
this.printCollection = function(){
|
||||
console.log(this.collection);
|
||||
};
|
||||
this.size = function() {
|
||||
return this.collection.length;
|
||||
};
|
||||
this.isEmpty = function() {
|
||||
return this.size() > 0 ? false : true;
|
||||
};
|
||||
this.enqueue = function (newitem) {
|
||||
if (this.isEmpty()) {
|
||||
return this.collection.push(newitem);
|
||||
}
|
||||
|
||||
this.collection = this.collection.reverse();
|
||||
var found_index = this.collection.findIndex(function (item) {
|
||||
return newitem[1] >= item[1];
|
||||
});
|
||||
if (found_index === -1) {
|
||||
this.collection.push(newitem);
|
||||
} else {
|
||||
this.collection.splice(found_index, 0, newitem);
|
||||
}
|
||||
this.collection = this.collection.reverse();
|
||||
};
|
||||
this.dequeue = function() {
|
||||
if (!this.isEmpty()) {
|
||||
return this.collection.shift()[0];
|
||||
} else {
|
||||
return 'The queue is empty.'
|
||||
}
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,79 @@
|
||||
---
|
||||
id: 587d8250367417b2b2512c60
|
||||
title: Create a Queue Class
|
||||
localeTitle: Crear una clase de cola
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Al igual que las pilas, las colas son una colección de elementos. Pero a diferencia de las pilas, las colas siguen el principio FIFO (primero en entrar, primero en salir). Los elementos agregados a una cola se empujan a la cola, o al final, de la cola, y solo se permite eliminar el elemento en la parte delantera de la cola.
|
||||
Podríamos usar una matriz para representar una cola, pero al igual que las pilas, queremos limitar la cantidad de control que tenemos sobre nuestras colas.
|
||||
Los dos métodos principales de una clase de cola son la puesta en cola y el método de salida. El método de puesta en cola empuja un elemento a la cola de la cola, y el método de salida de cola elimina y devuelve el elemento al frente de la cola. Otros métodos útiles son los métodos de frente, tamaño e isEmpty.
|
||||
Instrucciones
|
||||
Escriba un método de puesta en cola que empuja un elemento a la cola de la cola, un método de salida de cola que elimina y devuelve el elemento frontal, un método frontal que nos permite ver el elemento frontal, un método de tamaño que muestra la longitud y una Método isEmpty para verificar si la cola está vacía.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: Su clase de <code>Queue</code> debe tener un método de <code>enqueue</code> en <code>enqueue</code> .
|
||||
testString: 'assert((function(){var test = new Queue(); return (typeof test.enqueue === "function")}()), "Your <code>Queue</code> class should have a <code>enqueue</code> method.");'
|
||||
- text: Tu clase de <code>Queue</code> debe tener un método de <code>dequeue</code> .
|
||||
testString: 'assert((function(){var test = new Queue(); return (typeof test.dequeue === "function")}()), "Your <code>Queue</code> class should have a <code>dequeue</code> method.");'
|
||||
- text: Tu clase de <code>Queue</code> debe tener un método <code>front</code> .
|
||||
testString: 'assert((function(){var test = new Queue(); return (typeof test.front === "function")}()), "Your <code>Queue</code> class should have a <code>front</code> method.");'
|
||||
- text: Tu clase de <code>Queue</code> debe tener un método de <code>size</code> .
|
||||
testString: 'assert((function(){var test = new Queue(); return (typeof test.size === "function")}()), "Your <code>Queue</code> class should have a <code>size</code> method.");'
|
||||
- text: Tu clase de <code>Queue</code> debe tener un método <code>isEmpty</code> .
|
||||
testString: 'assert((function(){var test = new Queue(); return (typeof test.isEmpty === "function")}()), "Your <code>Queue</code> class should have an <code>isEmpty</code> method.");'
|
||||
- text: El método de <code>dequeue</code> debe eliminar y devolver el elemento frontal de la cola
|
||||
testString: 'assert((function(){var test = new Queue(); test.enqueue("Smith"); return (test.dequeue() === "Smith")}()), "The <code>dequeue</code> method should remove and return the front element of the queue");'
|
||||
- text: El método <code>front</code> debe devolver el valor del elemento frontal de la cola
|
||||
testString: 'assert((function(){var test = new Queue(); test.enqueue("Smith"); test.enqueue("John"); return (test.front() === "Smith")}()), "The <code>front</code> method should return value of the front element of the queue");'
|
||||
- text: El método de <code>size</code> debe devolver la longitud de la cola
|
||||
testString: 'assert((function(){var test = new Queue(); test.enqueue("Smith"); return (test.size() === 1)}()), "The <code>size</code> method should return the length of the queue");'
|
||||
- text: El método <code>isEmpty</code> debería devolver <code>false</code> si hay elementos en la cola
|
||||
testString: 'assert((function(){var test = new Queue(); test.enqueue("Smith"); return !(test.isEmpty())}()), "The <code>isEmpty</code> method should return <code>false</code> if there are elements in the queue");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function Queue () {
|
||||
var collection = [];
|
||||
this.print = function() {
|
||||
console.log(collection);
|
||||
};
|
||||
// Only change code below this line
|
||||
|
||||
// Only change code above this line
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,77 @@
|
||||
---
|
||||
id: 8d1323c8c441eddfaeb5bdef
|
||||
title: Create a Set Class
|
||||
localeTitle: Crear una clase de conjunto
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
En los próximos ejercicios, vamos a crear una función para emular una estructura de datos llamada "Conjunto". Un conjunto es como una matriz, pero no puede contener valores duplicados. El uso típico de un Conjunto es simplemente verificar la presencia de un elemento. Esto se puede implementar con un objeto, por ejemplo:
|
||||
<blockquote>var set = new Object();<br>set.foo = true;<br>// See if foo exists in our set:<br>console.log(set.foo) // true</blockquote>
|
||||
En los próximos ejercicios, construiremos un conjunto completo desde cero.
|
||||
Para este ejercicio, cree una función que agregue un valor a nuestra colección de conjuntos siempre que el valor no exista en el conjunto. Por ejemplo:
|
||||
<blockquote>this.add = function(element) {<br> //some code to add value to the set<br>}</blockquote>
|
||||
La función debe devolver <code>true</code> si el valor se agrega exitosamente y <code>false</code> contrario.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: Tu clase <code>Set</code> debería tener un método <code>add</code> .
|
||||
testString: 'assert((function(){var test = new Set(); return (typeof test.add === "function")}()), "Your <code>Set</code> class should have an <code>add</code> method.");'
|
||||
- text: Su método de <code>add</code> no debe agregar valores duplicados.
|
||||
testString: 'assert((function(){var test = new Set(); test.add("a"); test.add("b"); test.add("a"); var vals = test.values(); return (vals[0] === "a" && vals[1] === "b" && vals.length === 2)}()), "Your <code>add</code> method should not add duplicate values.");'
|
||||
- text: Su método de <code>add</code> debe devolver <code>true</code> cuando un valor ha sido agregado exitosamente.
|
||||
testString: 'assert((function(){var test = new Set(); var result = test.add("a"); return (result != undefined) && (result === true);}()), "Your <code>add</code> method should return <code>true</code> when a value has been successfully added.");'
|
||||
- text: Su método de <code>add</code> debe devolver <code>false</code> cuando se agrega un valor duplicado.
|
||||
testString: 'assert((function(){var test = new Set(); test.add("a"); var result = test.add("a"); return (result != undefined) && (result === false);}()), "Your <code>add</code> method should return <code>false</code> when a duplicate value is added.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function Set() {
|
||||
// the var collection will hold our set
|
||||
var collection = [];
|
||||
// this method will check for the presence of an element and return true or false
|
||||
this.has = function(element) {
|
||||
return (collection.indexOf(element) !== -1);
|
||||
};
|
||||
// this method will return all the values in the set
|
||||
this.values = function() {
|
||||
return collection;
|
||||
};
|
||||
// change code below this line
|
||||
// change code above this line
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
function Set() {var collection = []; this.has = function(e){return(collection.indexOf(e) !== -1);};this.values = function() {return collection;};this.add = function(element) {if (!this.has(element)) {collection.push(element);return true;} else {return false;}};}
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,80 @@
|
||||
---
|
||||
id: 587d8250367417b2b2512c5f
|
||||
title: Create a Stack Class
|
||||
localeTitle: Crear una clase de pila
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
En la sección anterior, hablamos sobre qué es una pila y cómo podemos usar una matriz para representar una pila. En esta sección, crearemos nuestra propia clase de pila.
|
||||
Aunque puede usar matrices para crear pilas, a veces es mejor limitar la cantidad de control que tenemos con nuestras pilas.
|
||||
Aparte del método <code>push</code> y <code>pop</code> , las pilas tienen otros métodos útiles. <code>isEmpty</code> <code>clear</code> método <code>peek</code> , <code>isEmpty</code> y <code>clear</code> a nuestra clase de pila.
|
||||
Instrucciones
|
||||
Escribe un método de <code>push</code> que empuja un elemento a la parte superior de la pila, un método <code>pop</code> que elimina el elemento de la parte superior de la pila, un método de <code>peek</code> que mira el primer elemento de la pila, un método <code>isEmpty</code> que verifica si la pila está vacía, y un método <code>clear</code> que elimina todos los elementos de la pila.
|
||||
Normalmente las pilas no tienen esto, pero hemos agregado un método de ayuda de <code>print</code> que la consola registra la colección.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: Tu clase de <code>Stack</code> debería tener un método <code>push</code> .
|
||||
testString: 'assert((function(){var test = new Stack(); return (typeof test.push === "function")}()), "Your <code>Stack</code> class should have a <code>push</code> method.");'
|
||||
- text: Tu clase de <code>Stack</code> debería tener un método <code>pop</code> .
|
||||
testString: 'assert((function(){var test = new Stack(); return (typeof test.pop === "function")}()), "Your <code>Stack</code> class should have a <code>pop</code> method.");'
|
||||
- text: Tu clase de <code>Stack</code> debería tener un método de <code>peek</code> .
|
||||
testString: 'assert((function(){var test = new Stack(); return (typeof test.peek === "function")}()), "Your <code>Stack</code> class should have a <code>peek</code> method.");'
|
||||
- text: Tu clase de <code>Stack</code> debería tener un método <code>isEmpty</code> .
|
||||
testString: 'assert((function(){var test = new Stack(); return (typeof test.isEmpty === "function")}()), "Your <code>Stack</code> class should have a <code>isEmpty</code> method.");'
|
||||
- text: Tu clase de <code>Stack</code> debería tener un método <code>clear</code> .
|
||||
testString: 'assert((function(){var test = new Stack(); return (typeof test.clear === "function")}()), "Your <code>Stack</code> class should have a <code>clear</code> method.");'
|
||||
- text: El método <code>peek</code> debería devolver el elemento superior de la pila.
|
||||
testString: 'assert((function(){var test = new Stack(); test.push("CS50"); return (test.peek() === "CS50")}()), "The <code>peek</code> method should return the top element of the stack");'
|
||||
- text: El método <code>pop</code> debería eliminar y devolver el elemento superior de la pila.
|
||||
testString: 'assert((function(){var test = new Stack(); test.push("CS50"); return (test.pop() === "CS50");}()), "The <code>pop</code> method should remove and return the top element of the stack");'
|
||||
- text: El método <code>isEmpty</code> debería devolver verdadero si una pila no contiene ningún elemento
|
||||
testString: 'assert((function(){var test = new Stack(); return test.isEmpty()}()), "The <code>isEmpty</code> method should return true if a stack does not contain any elements");'
|
||||
- text: El método <code>clear</code> debe eliminar todos los elementos de la pila.
|
||||
testString: 'assert((function(){var test = new Stack(); test.push("CS50"); test.clear(); return (test.isEmpty())}()), "The <code>clear</code> method should remove all element from the stack");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function Stack() {
|
||||
var collection = [];
|
||||
this.print = function() {
|
||||
console.log(collection);
|
||||
};
|
||||
// Only change code below this line
|
||||
|
||||
// Only change code above this line
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,77 @@
|
||||
---
|
||||
id: 587d8259367417b2b2512c84
|
||||
title: Create a Trie Search Tree
|
||||
localeTitle: Crear un árbol de búsqueda Trie
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Aquí pasaremos de los árboles de búsqueda binarios y echaremos un vistazo a otro tipo de estructura de árbol llamada trie. Un trie es un árbol de búsqueda ordenada que se usa comúnmente para contener cadenas, o matrices asociativas más genéricamente o conjuntos de datos dinámicos en los que las claves son cadenas. Son muy buenos para almacenar conjuntos de datos cuando muchas claves tienen prefijos que se superponen, por ejemplo, todas las palabras en un diccionario.
|
||||
A diferencia de un árbol binario, los nodos no están asociados con valores reales. En su lugar, la ruta a un nodo representa una clave específica. Por ejemplo, si quisiéramos almacenar el código de cadena en un trío, tendríamos cuatro nodos, uno para cada letra: c - o - d - e. Seguir esa ruta a través de todos estos nodos creará un código como una cadena, esa es la clave que almacenamos. Luego, si quisiéramos agregar la codificación de cadena, compartiría los primeros tres nodos de código antes de bifurcarse después de la d. De esta manera, los grandes conjuntos de datos se pueden almacenar de forma muy compacta. Además, la búsqueda puede ser muy rápida porque se limita efectivamente a la longitud de la cadena que está almacenando. Además, a diferencia de los árboles binarios, un nodo puede almacenar cualquier número de nodos secundarios.
|
||||
Como puede haber adivinado en el ejemplo anterior, algunos metadatos se almacenan comúnmente en los nodos que contienen el final de una clave, de modo que en los recorridos posteriores se puede recuperar esa clave. Por ejemplo, si agregamos códigos en nuestro ejemplo anterior, necesitaríamos alguna forma de saber que la e en el código representa el final de una clave que se ingresó anteriormente. De lo contrario, esta información se perdería efectivamente al agregar códigos.
|
||||
Instrucciones: Vamos a crear un trie para almacenar palabras. Aceptará palabras a través de un método de adición y las almacenará en una estructura de datos trie. También nos permitirá consultar si una cadena dada es una palabra con un método isWord, y recuperar todas las palabras ingresadas en el texto con un método de impresión. isWord debería devolver un valor booleano e imprimir debería devolver una matriz de todas estas palabras como valores de cadena.
|
||||
Para que podamos verificar que esta estructura de datos se implementa correctamente, proporcionamos una estructura de Nodo para cada nodo en el árbol. Cada nodo será un objeto con una propiedad de claves que es un objeto de mapa de JavaScript. Esto mantendrá las letras individuales que son claves válidas de cada nodo. También hemos creado una propiedad final en los nodos que se pueden establecer en verdadero si el nodo representa la terminación de una palabra.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: El Trie tiene un método de añadir.
|
||||
testString: 'assert((function testTrie() { var test = false; if (typeof Trie !== "undefined") { test = new Trie() } else { return false; }; return (typeof test.add == "function") }()), "The Trie has an add method.");'
|
||||
- text: El Trie tiene un método de impresión.
|
||||
testString: 'assert((function testTrie() { var test = false; if (typeof Trie !== "undefined") { test = new Trie() } else { return false; }; return (typeof test.print == "function") }()), "The Trie has a print method.");'
|
||||
- text: El Trie tiene un método isWord.
|
||||
testString: 'assert((function testTrie() { var test = false; if (typeof Trie !== "undefined") { test = new Trie() } else { return false; }; return (typeof test.isWord == "function") }()), "The Trie has an isWord method.");'
|
||||
- text: El método de impresión devuelve todos los elementos agregados al trie como cadenas en una matriz.
|
||||
testString: 'assert((function testTrie() { var test = false; if (typeof Trie !== "undefined") { test = new Trie() } else { return false; }; test.add("jump"); test.add("jumps"); test.add("jumped"); test.add("house"); test.add("mouse"); var added = test.print(); return (added.indexOf("jump") != -1 && added.indexOf("jumps") != -1 && added.indexOf("jumped") != -1 && added.indexOf("house") != -1 && added.indexOf("mouse") != -1 && added.length == 5); }()), "The print method returns all items added to the trie as strings in an array.");'
|
||||
- text: El método isWord devuelve verdadero solo para las palabras agregadas al trío y falso para todas las demás palabras.
|
||||
testString: 'assert((function testTrie() { var test = false; if (typeof Trie !== "undefined") { test = new Trie() } else { return false; }; test.add("hop"); test.add("hops"); test.add("hopped"); test.add("hoppy"); test.add("hope"); return (test.isWord("hop") && !test.isWord("ho") && test.isWord("hopped") && !test.isWord("hopp") && test.isWord("hoppy") && !test.isWord("hoping")); }()), "The isWord method returns true only for words added to the trie and false for all other words.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
var displayTree = (tree) => console.log(JSON.stringify(tree, null, 2));
|
||||
var Node = function() {
|
||||
this.keys = new Map();
|
||||
this.end = false;
|
||||
this.setEnd = function() {
|
||||
this.end = true;
|
||||
};
|
||||
this.isEnd = function() {
|
||||
return this.end;
|
||||
};
|
||||
};
|
||||
var Trie = function() {
|
||||
// change code below this line
|
||||
// change code above this line
|
||||
};
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,61 @@
|
||||
---
|
||||
id: 587d825b367417b2b2512c8d
|
||||
title: Create an ES6 JavaScript Map
|
||||
localeTitle: Crear un mapa de JavaScript ES6
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
La nueva versión de JavaScript nos proporciona un objeto Map incorporado que proporciona gran parte de la funcionalidad que escribimos a mano en el último desafío. Este objeto de mapa, aunque similar a los objetos JavaScript normales, proporciona algunas funciones útiles de las que carecen los objetos normales. Por ejemplo, un mapa ES6 rastrea el orden de inserción de los elementos que se le agregan. Aquí hay una descripción más completa de sus métodos:
|
||||
<code>.has(key)</code> devuelve verdadero o falso según la presencia de una clave
|
||||
<code>.get(key)</code> devuelve el valor asociado con una clave
|
||||
<code>.set(key, value)</code> establece un nueva clave, valor par
|
||||
<code>.delete(key)</code> elimina una clave, valor par
|
||||
<code>.clear()</code> elimina toda clave, valor pares
|
||||
<code>.entries()</code> devuelve una matriz de todas las claves en orden de inserción
|
||||
<code>.values()</code> devuelve un matriz de todos los valores en orden de inserción
|
||||
Instrucciones: Defina un objeto de mapa de JavaScript y asígnele una variable llamada myMap. Agregue la clave, el par de valores <code>freeCodeCamp</code> , <code>Awesome!</code> lo.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: El objeto myMap existe.
|
||||
testString: 'assert(typeof myMap === "object", "The myMap object exists.");'
|
||||
- text: 'myMap contiene el par de valores clave <code clase = "notranslate"> freeCodeCamp </code>, <code clase = "notranslate"> ¡Impresionante! </code>.'
|
||||
testString: 'assert(myMap.get("freeCodeCamp") === "Awesome!", "myMap contains the key value pair <code>freeCodeCamp</code>, <code>Awesome!</code>.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
// change code below this line
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,73 @@
|
||||
---
|
||||
id: 587d8254367417b2b2512c70
|
||||
title: Create and Add to Sets in ES6
|
||||
localeTitle: Crear y agregar a conjuntos en ES6
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Ahora que ha trabajado con ES5, va a realizar algo similar en ES6. Esto será considerablemente más fácil. ES6 contiene una estructura de datos incorporada <code>Set</code> muchas de las operaciones que ha escrito a mano se incluyen ahora para usted. Echemos un vistazo:
|
||||
Para crear un nuevo conjunto vacío:
|
||||
<code>var set = new Set();</code>
|
||||
Puede crear un conjunto con un valor:
|
||||
<code>var set = new Set(1);</code>
|
||||
Puede crear un conjunto con una matriz:
|
||||
<code>var set = new Set([1, 2, 3]);</code>
|
||||
Una vez que haya creado un conjunto, puede agregar los valores que desee utilizando el método de <code>add</code> :
|
||||
<blockquote>var set = new Set([1, 2, 3]);<br>set.add([4, 5, 6]);</blockquote>
|
||||
Como recordatorio, un conjunto es una estructura de datos que no puede contener valores duplicados:
|
||||
<blockquote>var set = new Set([1, 2, 3, 1, 2, 3]);<br>// set contains [1, 2, 3] only</blockquote>
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
Para este ejercicio, devuelva un conjunto con los siguientes valores: <code>1, 2, 3, 'Taco', 'Cat', 'Awesome'</code>
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: 'Tu <code>Set</code> solo debe contener los valores <code>1, 2, 3, Taco, Cat, Awesome</code> '.
|
||||
testString: 'assert(function(){var test = checkSet(); return (test.size == 6) && test.has(1) && test.has(2) && test.has(3) && test.has("Taco") && test.has("Cat") && test.has("Awesome");}, "Your <code>Set</code> should only contain the values <code>1, 2, 3, Taco, Cat, Awesome</code>.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function checkSet() {
|
||||
var set = new Set([1, 2, 3, 3, 2, 1, 2, 3, 1]);
|
||||
// change code below this line
|
||||
|
||||
// change code above this line
|
||||
console.log(set);
|
||||
return set;
|
||||
}
|
||||
|
||||
checkSet();
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
function checkSet(){var set = new Set([1,2,3,'Taco','Cat','Awesome']);
|
||||
return set;}
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,83 @@
|
||||
---
|
||||
id: 587d8258367417b2b2512c80
|
||||
title: Delete a Leaf Node in a Binary Search Tree
|
||||
localeTitle: Eliminar un nodo de hoja en un árbol de búsqueda binario
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Este es el primero de los tres desafíos en los que implementaremos una operación más difícil en los árboles de búsqueda binarios: eliminación. La eliminación es difícil porque la eliminación de nodos rompe los enlaces en el árbol. Estos enlaces deben restablecerse cuidadosamente para garantizar que se mantenga la estructura del árbol binario. Para algunas eliminaciones, esto significa que el árbol debe ser reorganizado. En general, encontrará uno de los tres casos cuando intente eliminar un nodo:
|
||||
Nodo hoja: el objetivo que se eliminará tiene cero hijos.
|
||||
Un hijo: el objetivo que se eliminará solo tiene un hijo.
|
||||
Dos hijos: El objetivo a eliminar tiene dos nodos hijos.
|
||||
Eliminar un nodo hoja es fácil, simplemente lo eliminamos. Eliminar un nodo con un hijo también es relativamente fácil, simplemente lo eliminamos y vinculamos su padre al hijo del nodo que eliminamos. Sin embargo, la eliminación de un nodo con dos hijos es más difícil, ya que esto crea dos nodos hijos que deben volver a conectarse al árbol padre. Veremos cómo lidiar con este caso en el tercer desafío. Además, debe tener en cuenta algunos casos de ventaja al manejar la eliminación. ¿Qué pasa si el árbol está vacío? ¿Qué pasa si el nodo a eliminar es el nodo raíz? ¿Y si solo hay dos elementos en el árbol? Por ahora, vamos a manejar el primer caso donde eliminamos un nodo de hoja.
|
||||
Instrucciones: Crea un método en nuestro árbol binario llamado <code>remove</code> . Construiremos la lógica para nuestra operación de eliminación aquí. Primero, querrá crear una función dentro de eliminar que encuentre el nodo que intentamos eliminar en el árbol actual. Si el nodo no está presente en el árbol, <code>remove</code> debe devolver <code>null</code> . Ahora, si el nodo de destino es un nodo de hoja sin hijos, entonces la referencia principal debe establecerse en <code>null</code> . Esto elimina efectivamente el nodo del árbol. Para hacer esto, también deberá hacer un seguimiento del padre del nodo que estamos intentando eliminar. También será útil para crear una forma de realizar un seguimiento del número de hijos que tiene el nodo de destino, ya que esto determinará en qué caso se encuentra nuestra eliminación.
|
||||
Manejaremos el segundo y tercer caso en los próximos desafíos. ¡Buena suerte!
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: La estructura de datos <code>BinarySearchTree</code> existe.
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() }; return (typeof test == "object")})(), "The <code>BinarySearchTree</code> data structure exists.");'
|
||||
- text: El árbol de búsqueda binario tiene un método llamado <code>remove</code> .
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; return (typeof test.remove == "function")})(), "The binary search tree has a method called <code>remove</code>.");'
|
||||
- text: Intentar eliminar un elemento que no existe devuelve <code>null</code> .
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; if (typeof test.remove !== "function") { return false; }; return (test.remove(100) == null); })(), "Trying to remove an element that does not exist returns <code>null</code>.");'
|
||||
- text: 'Si el nodo raíz no tiene hijos, al eliminarlo, se establece la raíz en <code>null</code> '.
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; if (typeof test.remove !== "function") { return false; }; test.add(500); test.remove(500); return (test.inorder() == null); })(), "If the root node has no children, deleting it sets the root to <code>null</code>.");'
|
||||
- text: El método de <code>remove</code> elimina los nodos de hoja del árbol.
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; if (typeof test.remove !== "function") { return false; }; test.add(5); test.add(3); test.add(7); test.add(6); test.add(10); test.add(12); test.remove(3); test.remove(12); test.remove(10); return (test.inorder().join("") == "567"); })(), "The <code>remove</code> method removes leaf nodes from the tree");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
var displayTree = (tree) => console.log(JSON.stringify(tree, null, 2));
|
||||
function Node(value) {
|
||||
this.value = value;
|
||||
this.left = null;
|
||||
this.right = null;
|
||||
}
|
||||
|
||||
function BinarySearchTree() {
|
||||
this.root = null;
|
||||
// case 1: target has no children, change code below this line
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
console.info('after the test');
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,123 @@
|
||||
---
|
||||
id: 587d8258367417b2b2512c81
|
||||
title: Delete a Node with One Child in a Binary Search Tree
|
||||
localeTitle: Eliminar un nodo con un hijo en un árbol de búsqueda binario
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Ahora que podemos eliminar los nodos de hoja, pasemos al segundo caso: eliminar un nodo con un hijo. Para este caso, digamos que tenemos un árbol con los siguientes nodos 1 - 2 - 3 donde 1 es la raíz. Para eliminar 2, simplemente necesitamos hacer la referencia correcta en 1 punto a 3. De manera más general, para eliminar un nodo con un solo hijo, hacemos que la referencia principal de ese nodo sea el siguiente nodo del árbol.
|
||||
Instrucciones: Hemos proporcionado algún código en nuestro método de <code>remove</code> que cumple las tareas del último desafío. Encontramos el objetivo a eliminar y su padre y definimos la cantidad de hijos que tiene el nodo objetivo. Agreguemos el siguiente caso aquí para los nodos de destino con un solo hijo. Aquí, tendremos que determinar si el único hijo es una rama izquierda o derecha en el árbol y luego establecer la referencia correcta en el padre para apuntar a este nodo. Además, consideremos el caso en el que el destino es el nodo raíz (esto significa que el nodo principal será <code>null</code> ). Siéntase libre de reemplazar todo el código de inicio con el suyo, siempre y cuando pase las pruebas.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: La estructura de datos <code>BinarySearchTree</code> existe.
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() }; return (typeof test == "object")})(), "The <code>BinarySearchTree</code> data structure exists.");'
|
||||
- text: El árbol de búsqueda binario tiene un método llamado <code>remove</code> .
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; return (typeof test.remove == "function")})(), "The binary search tree has a method called <code>remove</code>.");'
|
||||
- text: Intentar eliminar un elemento que no existe devuelve <code>null</code> .
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; if (typeof test.remove !== "function") { return false; }; return (test.remove(100) == null); })(), "Trying to remove an element that does not exist returns <code>null</code>.");'
|
||||
- text: 'Si el nodo raíz no tiene hijos, al eliminarlo, se establece la raíz en <code>null</code> '.
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; if (typeof test.remove !== "function") { return false; }; test.add(500); test.remove(500); return (test.inorder() == null); })(), "If the root node has no children, deleting it sets the root to <code>null</code>.");'
|
||||
- text: El método de <code>remove</code> elimina los nodos de hoja del árbol.
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; if (typeof test.remove !== "function") { return false; }; test.add(5); test.add(3); test.add(7); test.add(6); test.add(10); test.add(12); test.remove(3); test.remove(12); test.remove(10); return (test.inorder().join("") == "567"); })(), "The <code>remove</code> method removes leaf nodes from the tree");'
|
||||
- text: El método <code>remove</code> elimina los nodos con un hijo.
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; if (typeof test.remove !== "function") { return false; }; test.add(-1); test.add(3); test.add(7); test.add(16); test.remove(16); test.remove(7); test.remove(3); return (test.inorder().join("") == "-1"); })(), "The <code>remove</code> method removes nodes with one child.");'
|
||||
- text: Al eliminar la raíz en un árbol con dos nodos, el segundo es la raíz.
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; if (typeof test.remove !== "function") { return false; }; test.add(15); test.add(27); test.remove(15); return (test.inorder().join("") == "27"); })(), "Removing the root in a tree with two nodes sets the second to be the root.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
var displayTree = (tree) => console.log(JSON.stringify(tree, null, 2));
|
||||
function Node(value) {
|
||||
this.value = value;
|
||||
this.left = null;
|
||||
this.right = null;
|
||||
}
|
||||
|
||||
function BinarySearchTree() {
|
||||
this.root = null;
|
||||
this.remove = function(value) {
|
||||
if (this.root === null) {
|
||||
return null;
|
||||
}
|
||||
var target;
|
||||
var parent = null;
|
||||
// find the target value and its parent
|
||||
(function findValue(node = this.root) {
|
||||
if (value == node.value) {
|
||||
target = node;
|
||||
} else if (value < node.value && node.left !== null) {
|
||||
parent = node;
|
||||
return findValue(node.left);
|
||||
} else if (value < node.value && node.left === null) {
|
||||
return null;
|
||||
} else if (value > node.value && node.right !== null) {
|
||||
parent = node;
|
||||
return findValue(node.right);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}).bind(this)();
|
||||
if (target === null) {
|
||||
return null;
|
||||
}
|
||||
// count the children of the target to delete
|
||||
var children = (target.left !== null ? 1 : 0) + (target.right !== null ? 1 : 0);
|
||||
// case 1: target has no children
|
||||
if (children === 0) {
|
||||
if (target == this.root) {
|
||||
this.root = null;
|
||||
}
|
||||
else {
|
||||
if (parent.left == target) {
|
||||
parent.left = null;
|
||||
} else {
|
||||
parent.right = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
// case 2: target has one child, change code below this line
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
console.info('after the test');
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,142 @@
|
||||
---
|
||||
id: 587d8258367417b2b2512c82
|
||||
title: Delete a Node with Two Children in a Binary Search Tree
|
||||
localeTitle: Eliminar un nodo con dos hijos en un árbol de búsqueda binario
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Eliminar los nodos que tienen dos hijos es el caso más difícil de implementar. La eliminación de un nodo como este produce dos subárboles que ya no están conectados a la estructura de árbol original. ¿Cómo podemos reconectarlos? Un método es encontrar el valor más pequeño en el subárbol derecho del nodo de destino y reemplazar el nodo de destino con este valor. Seleccionar el reemplazo de esta manera asegura que sea mayor que cada nodo en el subárbol izquierdo, se convierte en el nuevo padre, pero también en menos que cada nodo en el subárbol derecho se convierte en el nuevo padre.
|
||||
Una vez que se realiza este reemplazo, el nodo de reemplazo debe eliminarse del subárbol derecho. Incluso esta operación es complicada porque el reemplazo puede ser una hoja o puede ser el padre de un subárbol derecho. Si es una hoja debemos eliminar la referencia de su padre. De lo contrario, debe ser el hijo derecho del objetivo. En este caso, debemos reemplazar el valor objetivo con el valor de reemplazo y hacer que la referencia objetivo sea el hijo derecho del reemplazo.
|
||||
Instrucciones: Terminemos nuestro método de <code>remove</code> manejando el tercer caso. Hemos proporcionado un código nuevo para los dos primeros casos. Agregue un poco de código ahora para manejar los nodos de destino con dos hijos. ¿Algún caso de borde a tener en cuenta? ¿Qué pasa si el árbol tiene sólo tres nodos? Una vez que haya terminado, esto completará nuestra operación de eliminación de árboles de búsqueda binarios. Buen trabajo, este es un problema bastante difícil!
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: La estructura de datos <code>BinarySearchTree</code> existe.
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() }; return (typeof test == "object")})(), "The <code>BinarySearchTree</code> data structure exists.");'
|
||||
- text: El árbol de búsqueda binario tiene un método llamado <code>remove</code> .
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; return (typeof test.remove == "function")})(), "The binary search tree has a method called <code>remove</code>.");'
|
||||
- text: Intentar eliminar un elemento que no existe devuelve <code>null</code> .
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; return (typeof test.remove == "function") ? (test.remove(100) == null) : false})(), "Trying to remove an element that does not exist returns <code>null</code>.");'
|
||||
- text: 'Si el nodo raíz no tiene hijos, al eliminarlo, se establece la raíz en <code>null</code> '.
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; test.add(500); test.remove(500); return (typeof test.remove == "function") ? (test.inorder() == null) : false})(), "If the root node has no children, deleting it sets the root to <code>null</code>.");'
|
||||
- text: El método de <code>remove</code> elimina los nodos de hoja del árbol.
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; test.add(5); test.add(3); test.add(7); test.add(6); test.add(10); test.add(12); test.remove(3); test.remove(12); test.remove(10); return (typeof test.remove == "function") ? (test.inorder().join("") == "567") : false})(), "The <code>remove</code> method removes leaf nodes from the tree");'
|
||||
- text: El método <code>remove</code> elimina los nodos con un hijo.
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; if (typeof test.remove !== "function") { return false; }; test.add(-1); test.add(3); test.add(7); test.add(16); test.remove(16); test.remove(7); test.remove(3); return (test.inorder().join("") == "-1"); })(), "The <code>remove</code> method removes nodes with one child.");'
|
||||
- text: Al eliminar la raíz en un árbol con dos nodos, el segundo es la raíz.
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; if (typeof test.remove !== "function") { return false; }; test.add(15); test.add(27); test.remove(15); return (test.inorder().join("") == "27"); })(), "Removing the root in a tree with two nodes sets the second to be the root.");'
|
||||
- text: El método de <code>remove</code> elimina los nodos con dos hijos mientras mantiene la estructura del árbol de búsqueda binario.
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; if (typeof test.remove !== "function") { return false; }; test.add(1); test.add(4); test.add(3); test.add(7); test.add(9); test.add(11); test.add(14); test.add(15); test.add(19); test.add(50); test.remove(9); if (!test.isBinarySearchTree()) { return false; }; test.remove(11); if (!test.isBinarySearchTree()) { return false; }; test.remove(14); if (!test.isBinarySearchTree()) { return false; }; test.remove(19); if (!test.isBinarySearchTree()) { return false; }; test.remove(3); if (!test.isBinarySearchTree()) { return false; }; test.remove(50); if (!test.isBinarySearchTree()) { return false; }; test.remove(15); if (!test.isBinarySearchTree()) { return false; }; return (test.inorder().join("") == "147"); })(), "The <code>remove</code> method removes nodes with two children while maintaining the binary search tree structure.");'
|
||||
- text: La raíz se puede eliminar en un árbol de tres nodos.
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; if (typeof test.remove !== "function") { return false; }; test.add(100); test.add(50); test.add(300); test.remove(100); return (test.inorder().join("") == 50300); })(), "The root can be removed on a tree of three nodes.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
var displayTree = (tree) => console.log(JSON.stringify(tree, null, 2));
|
||||
function Node(value) {
|
||||
this.value = value;
|
||||
this.left = null;
|
||||
this.right = null;
|
||||
}
|
||||
|
||||
function BinarySearchTree() {
|
||||
this.root = null;
|
||||
this.remove = function(value) {
|
||||
if (this.root === null) {
|
||||
return null;
|
||||
}
|
||||
var target;
|
||||
var parent = null;
|
||||
// find the target value and its parent
|
||||
(function findValue(node = this.root) {
|
||||
if (value == node.value) {
|
||||
target = node;
|
||||
} else if (value < node.value && node.left !== null) {
|
||||
parent = node;
|
||||
return findValue(node.left);
|
||||
} else if (value < node.value && node.left === null) {
|
||||
return null;
|
||||
} else if (value > node.value && node.right !== null) {
|
||||
parent = node;
|
||||
return findValue(node.right);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}).bind(this)();
|
||||
if (target === null) {
|
||||
return null;
|
||||
}
|
||||
// count the children of the target to delete
|
||||
var children = (target.left !== null ? 1 : 0) + (target.right !== null ? 1 : 0);
|
||||
// case 1: target has no children
|
||||
if (children === 0) {
|
||||
if (target == this.root) {
|
||||
this.root = null;
|
||||
}
|
||||
else {
|
||||
if (parent.left == target) {
|
||||
parent.left = null;
|
||||
} else {
|
||||
parent.right = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
// case 2: target has one child
|
||||
else if (children == 1) {
|
||||
var newChild = (target.left !== null) ? target.left : target.right;
|
||||
if (parent === null) {
|
||||
target.value = newChild.value;
|
||||
target.left = null;
|
||||
target.right = null;
|
||||
} else if (newChild.value < parent.value) {
|
||||
parent.left = newChild;
|
||||
} else {
|
||||
parent.right = newChild;
|
||||
}
|
||||
target = null;
|
||||
}
|
||||
// case 3: target has two children, change code below this line
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
console.info('after the test');
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,83 @@
|
||||
---
|
||||
id: 587d825d367417b2b2512c96
|
||||
title: Depth-First Search
|
||||
localeTitle: Búsqueda en profundidad
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
igual que <dfn>en la búsqueda de amplitud en primer lugar</dfn> , aquí aprenderemos sobre otro algoritmo de recorrido de gráficos llamado <dfn>búsqueda de primero en profundidad</dfn> .
|
||||
Mientras que la búsqueda en amplitud busca las longitudes de borde incrementales lejos del nodo de origen, la <dfn>búsqueda en profundidad</dfn> primero recorre un camino de bordes lo más lejos posible.
|
||||
Una vez que llega a un extremo de una ruta, la búsqueda volverá al último nodo con una ruta de borde no visitada y continuará la búsqueda.
|
||||
Visualmente, esto es lo que hace el algoritmo donde el nodo superior es el punto de inicio de la búsqueda.
|
||||
<img class='img-responsive' src='https://camo.githubusercontent.com/aaad9e39961daf34d967c616edeb50abf3bf1235/68747470733a2f2f75706c6f61642e77696b696d656469612e6f72672f77696b6970656469612f636f6d6d6f6e732f372f37662f44657074682d46697273742d5365617263682e676966'>
|
||||
Una salida simple de este algoritmo es una lista de nodos a los que se puede acceder desde un nodo determinado. Entonces, al implementar este algoritmo, deberá realizar un seguimiento de los nodos que visita.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
Escriba una función <code>dfs()</code> que tome un <code>graph</code> matriz de adyacencia no <code>graph</code> y una <code>root</code> etiqueta de nodo como parámetros. La etiqueta del nodo solo será el valor numérico del nodo entre <code>0</code> y <code>n - 1</code> , donde <code>n</code> es el número total de nodos en el gráfico.
|
||||
Su función debe generar una matriz de todos los nodos accesibles desde la <code>root</code> .
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: 'El gráfico de entrada <code>[[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 1], [0, 0, 1, 0]]</code> con un nodo de inicio de <code>1</code> debería devolver una matriz con <code>0</code> , <code>1</code> , <code>2</code> y <code>3</code> '.
|
||||
testString: 'assert.sameMembers((function() { var graph = [[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 1], [0, 0, 1, 0]]; return dfs(graph, 1);})(), [0, 1, 2, 3], "The input graph <code>[[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 1], [0, 0, 1, 0]]</code> with a start node of <code>1</code> should return an array with <code>0</code>, <code>1</code>, <code>2</code>, and <code>3</code>.");'
|
||||
- text: 'El gráfico de entrada <code>[[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 1], [0, 0, 1, 0]]</code> con un nodo de inicio de <code>1</code> debería devolver una matriz con cuatro elementos '.
|
||||
testString: 'assert((function() { var graph = [[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 1], [0, 0, 1, 0]]; return dfs(graph, 1);})().length === 4, "The input graph <code>[[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 1], [0, 0, 1, 0]]</code> with a start node of <code>1</code> should return an array with four elements.");'
|
||||
- text: 'El gráfico de entrada <code>[[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 0]]</code> con un nodo de inicio de <code>3</code> debería devolver una matriz con <code>3</code> '.
|
||||
testString: 'assert.sameMembers((function() { var graph = [[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 0]]; return dfs(graph, 3);})(), [3], "The input graph <code>[[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 0]]</code> with a start node of <code>3</code> should return an array with <code>3</code>.");'
|
||||
- text: 'El gráfico de entrada <code>[[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 0]]</code> con un nodo de inicio de <code>3</code> debería devolver una matriz con un elemento '.
|
||||
testString: 'assert((function() { var graph = [[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 0]]; return dfs(graph, 3);})().length === 1, "The input graph <code>[[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 0]]</code> with a start node of <code>3</code> should return an array with one element.");'
|
||||
- text: 'El gráfico de entrada <code>[[0, 1, 0, 0], [1, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]]</code> con un nodo de inicio de <code>3</code> debería devolver una matriz con <code>2</code> y <code>3</code> '.
|
||||
testString: 'assert.sameMembers((function() { var graph = [[0, 1, 0, 0], [1, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]]; return dfs(graph, 3);})(), [2, 3], "The input graph <code>[[0, 1, 0, 0], [1, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]]</code> with a start node of <code>3</code> should return an array with <code>2</code> and <code>3</code>.");'
|
||||
- text: 'El gráfico de entrada <code>[[0, 1, 0, 0], [1, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]]</code> con un nodo de inicio de <code>3</code> debería devolver una matriz con dos elementos '.
|
||||
testString: 'assert((function() { var graph = [[0, 1, 0, 0], [1, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]]; return dfs(graph, 3);})().length === 2, "The input graph <code>[[0, 1, 0, 0], [1, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]]</code> with a start node of <code>3</code> should return an array with two elements.");'
|
||||
- text: 'El gráfico de entrada <code>[[0, 1, 0, 0], [1, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]]</code> con un nodo de inicio de <code>0</code> debería devolver una matriz con <code>0</code> y <code>1</code> '.
|
||||
testString: 'assert.sameMembers((function() { var graph = [[0, 1, 0, 0], [1, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]]; return dfs(graph, 0);})(), [0, 1], "The input graph <code>[[0, 1, 0, 0], [1, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]]</code> with a start node of <code>0</code> should return an array with <code>0</code> and <code>1</code>.");'
|
||||
- text: 'El gráfico de entrada <code>[[0, 1, 0, 0], [1, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]]</code> con un nodo de inicio de <code>0</code> debería devolver una matriz con dos elementos '.
|
||||
testString: 'assert((function() { var graph = [[0, 1, 0, 0], [1, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]]; return dfs(graph, 0);})().length === 2, "The input graph <code>[[0, 1, 0, 0], [1, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]]</code> with a start node of <code>0</code> should return an array with two elements.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function dfs(graph, root) {
|
||||
|
||||
}
|
||||
|
||||
var exDFSGraph = [
|
||||
[0, 1, 0, 0],
|
||||
[1, 0, 1, 0],
|
||||
[0, 1, 0, 1],
|
||||
[0, 0, 1, 0]
|
||||
];
|
||||
console.log(dfs(exDFSGraph, 3));
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
function dfs(graph, root) { var stack = []; var tempV; var visited = []; var tempVNeighbors = []; stack.push(root); while (stack.length > 0) { tempV = stack.pop(); if (visited.indexOf(tempV) == -1) { visited.push(tempV); tempVNeighbors = graph[tempV]; for (var i = 0; i < tempVNeighbors.length; i++) { if (tempVNeighbors[i] == 1) { stack.push(i); }}}} return visited;}
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,86 @@
|
||||
---
|
||||
id: 587d8257367417b2b2512c7d
|
||||
title: Find the Minimum and Maximum Height of a Binary Search Tree
|
||||
localeTitle: Encuentra la altura mínima y máxima de un árbol de búsqueda binario
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
En el último desafío describimos un escenario en el que un árbol podría desequilibrarse. Para entender el concepto de equilibrio, echemos un vistazo a otra propiedad del árbol: la altura. La altura en un árbol representa la distancia desde el nodo raíz a cualquier nodo hoja dado. Diferentes caminos en una estructura de árbol altamente ramificada pueden tener diferentes alturas, pero para un árbol dado habrá una altura mínima y máxima. Si el árbol está equilibrado, estos valores diferirán como máximo en uno. Esto significa que en un árbol equilibrado, todos los nodos de hoja existen dentro del mismo nivel, o si no están dentro del mismo nivel, están a lo sumo en un nivel.
|
||||
La propiedad del equilibrio es importante para los árboles porque es lo que determina la eficiencia de las operaciones de los árboles. Como explicamos en el último desafío, enfrentamos la complejidad del peor de los casos para árboles muy desequilibrados. Los árboles de equilibrio automático se usan comúnmente para explicar este problema en árboles con conjuntos de datos dinámicos. Los ejemplos comunes de estos incluyen árboles AVL, árboles rojo-negros y árboles-B. Todos estos árboles contienen lógica interna adicional que vuelve a equilibrar el árbol cuando las inserciones o eliminaciones crean un estado de desequilibrio.
|
||||
Nota: una propiedad similar a la altura es la profundidad, que se refiere a qué tan lejos está un nodo dado del nodo raíz.
|
||||
Instrucciones: escriba dos métodos para nuestro árbol binario: <code>findMinHeight</code> y <code>findMaxHeight</code> . Estos métodos deben devolver un valor entero para la altura mínima y máxima dentro de un árbol binario dado, respectivamente. Si el nodo está vacío, asignémosle una altura de <code>-1</code> (ese es el caso base). Finalmente, agregue un tercer método <code>isBalanced</code> que devuelva <code>true</code> o <code>false</code> dependiendo de si el árbol está equilibrado o no. Puedes usar los dos primeros métodos que acabas de escribir para determinar esto.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: La estructura de datos <code>BinarySearchTree</code> existe.
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() }; return (typeof test == "object")})(), "The <code>BinarySearchTree</code> data structure exists.");'
|
||||
- text: El árbol de búsqueda binario tiene un método llamado <code>findMinHeight</code> .
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; return (typeof test.findMinHeight == "function")})(), "The binary search tree has a method called <code>findMinHeight</code>.");'
|
||||
- text: El árbol de búsqueda binario tiene un método llamado <code>findMaxHeight</code> .
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; return (typeof test.findMaxHeight == "function")})(), "The binary search tree has a method called <code>findMaxHeight</code>.");'
|
||||
- text: El árbol de búsqueda binario tiene un método llamado <code>isBalanced</code> .
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; return (typeof test.isBalanced == "function")})(), "The binary search tree has a method called <code>isBalanced</code>.");'
|
||||
- text: El método <code>findMinHeight</code> devuelve la altura mínima del árbol.
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; if (typeof test.findMinHeight !== "function") { return false; }; test.add(4); test.add(1); test.add(7); test.add(87); test.add(34); test.add(45); test.add(73); test.add(8); return (test.findMinHeight() == 1); })(), "The <code>findMinHeight</code> method returns the minimum height of the tree.");'
|
||||
- text: El método <code>findMaxHeight</code> devuelve la altura máxima del árbol.
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; if (typeof test.findMaxHeight !== "function") { return false; }; test.add(4); test.add(1); test.add(7); test.add(87); test.add(34); test.add(45); test.add(73); test.add(8); return (test.findMaxHeight() == 5); })(), "The <code>findMaxHeight</code> method returns the maximum height of the tree.");'
|
||||
- text: Un árbol vacío devuelve una altura de <code>-1</code> .
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; if (typeof test.findMaxHeight !== "function") { return false; }; return (test.findMaxHeight() == -1); })(), "An empty tree returns a height of <code>-1</code>.");'
|
||||
- text: El método <code>isBalanced</code> devuelve verdadero si el árbol es un árbol de búsqueda binaria equilibrada.
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; if (typeof test.isBalanced !== "function") { return false; }; test.add(4); test.add(1); test.add(7); test.add(87); test.add(34); test.add(45); test.add(73); test.add(8); return test.isBalanced(); })(), "The <code>isBalanced</code> method returns true if the tree is a balanced binary search tree.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
var displayTree = (tree) => console.log(JSON.stringify(tree, null, 2));
|
||||
function Node(value) {
|
||||
this.value = value;
|
||||
this.left = null;
|
||||
this.right = null;
|
||||
}
|
||||
function BinarySearchTree() {
|
||||
this.root = null;
|
||||
// change code below this line
|
||||
// change code above this line
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
console.info('after the test');
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,85 @@
|
||||
---
|
||||
id: 587d8256367417b2b2512c7a
|
||||
title: Find the Minimum and Maximum Value in a Binary Search Tree
|
||||
localeTitle: Encuentre el valor mínimo y máximo en un árbol de búsqueda binario
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Esta serie de desafíos introducirá la estructura de datos del árbol. Los árboles son una estructura de datos importante y versátil en informática. Por supuesto, su nombre proviene del hecho de que cuando se visualizan se parecen mucho a los árboles con los que estamos familiarizados en el mundo natural. Una estructura de datos de árbol comienza con un nodo, normalmente denominado raíz, y desde aquí se bifurca a nodos adicionales, cada uno de los cuales puede tener más nodos secundarios, y así sucesivamente. La estructura de datos generalmente se visualiza con el nodo raíz en la parte superior; Se puede pensar en él como un árbol natural al revés.
|
||||
Primero, describamos algunos términos comunes que encontraremos con los árboles. El nodo raíz es la parte superior del árbol. Los puntos de datos en el árbol se llaman nodos. Los nodos con ramas que conducen a otros nodos se conocen como el padre del nodo al que la rama lleva (el hijo). Otros términos familiares más complicados se aplican como podría esperarse. Un subárbol se refiere a todos los descendientes de un nodo particular, las ramas se pueden denominar bordes y los nodos de hoja son nodos al final del árbol que no tienen hijos. Finalmente, tenga en cuenta que los árboles son inherentemente estructuras de datos recursivas. Es decir, cualquier hijo de un nodo es padre de su propio subárbol, y así sucesivamente. Es importante entender la naturaleza recursiva de los árboles cuando se diseñan algoritmos para operaciones de árboles comunes.
|
||||
Para comenzar, discutiremos un tipo particular de árbol, el árbol binario. De hecho, discutiremos un árbol binario particular, un árbol de búsqueda binario. Vamos a describir lo que esto significa. Si bien la estructura de datos del árbol puede tener cualquier número de ramas en un solo nodo, un árbol binario solo puede tener dos ramas para cada nodo. Además, un árbol de búsqueda binario se ordena con respecto a los subárboles secundarios, de modo que el valor de cada nodo en el subárbol izquierdo es menor o igual que el valor del nodo principal, y el valor de cada nodo en el subárbol derecho es mayor o igual que el valor del nodo padre. Es muy útil visualizar esta relación para entenderla mejor:
|
||||
<div style='width: 100%; display: flex; justify-content: center; align-items: center;'><img style='width: 100%; max-width: 350px;' src='https://user-images.githubusercontent.com/18563015/32136009-1e665d98-bbd6-11e7-9133-63184f9f9182.png'></div>
|
||||
Ahora esta relación ordenada es muy fácil de ver. Tenga en cuenta que cada valor a la izquierda de 8, el nodo raíz, es menor que 8, y cada valor a la derecha es mayor que 8. También tenga en cuenta que esta relación se aplica también a cada uno de los subárboles. Por ejemplo, el primer hijo izquierdo es un subárbol. 3 es el nodo principal, y tiene exactamente dos nodos secundarios: según las reglas que gobiernan los árboles de búsqueda binarios, sabemos sin mirar que el elemento secundario izquierdo de este nodo (y cualquiera de sus elementos secundarios) será menor que 3, y el derecho child (y cualquiera de sus hijos) será mayor que 3 (pero también menor que el valor raíz de la estructura), y así sucesivamente.
|
||||
Los árboles de búsqueda binarios son estructuras de datos muy comunes y útiles porque proporcionan tiempo logarítmico en el caso promedio para varias operaciones comunes, como búsqueda, inserción y eliminación.
|
||||
Instrucciones: Empezaremos simple. Aquí hemos definido el esqueleto de una estructura de árbol de búsqueda binaria además de una función para crear nodos para nuestro árbol. Observe que cada nodo puede tener un valor izquierdo y derecho. A estos se les asignarán subárboles secundarios si existen. En nuestro árbol de búsqueda binario, defina dos métodos, <code>findMin</code> y <code>findMax</code> . Estos métodos deben devolver el valor mínimo y máximo retenido en el árbol de búsqueda binario (no se preocupe por agregar valores al árbol por ahora, hemos agregado algunos en el fondo). Si te quedas atascado, reflexiona sobre el invariante que debe ser cierto para los árboles de búsqueda binarios: cada subárbol izquierdo es menor o igual que su principal y cada subárbol derecho es mayor o igual que su principal. Digamos también que nuestro árbol solo puede almacenar valores enteros. Si el árbol está vacío, cualquiera de los métodos debe devolver <code>null</code> .
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: La estructura de datos <code>BinarySearchTree</code> existe.
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() }; return (typeof test == "object")})(), "The <code>BinarySearchTree</code> data structure exists.");'
|
||||
- text: El árbol de búsqueda binario tiene un método llamado <code>findMin</code> .
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; return (typeof test.findMin == "function")})(), "The binary search tree has a method called <code>findMin</code>.");'
|
||||
- text: El árbol de búsqueda binario tiene un método llamado <code>findMax</code> .
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; return (typeof test.findMax == "function")})(), "The binary search tree has a method called <code>findMax</code>.");'
|
||||
- text: El método <code>findMin</code> devuelve el valor mínimo en el árbol de búsqueda binario.
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; if (typeof test.findMin !== "function") { return false; }; test.add(4); test.add(1); test.add(7); test.add(87); test.add(34); test.add(45); test.add(73); test.add(8); return test.findMin() == 1; })(), "The <code>findMin</code> method returns the minimum value in the binary search tree.");'
|
||||
- text: El método <code>findMax</code> devuelve el valor máximo en el árbol de búsqueda binario.
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; if (typeof test.findMax !== "function") { return false; }; test.add(4); test.add(1); test.add(7); test.add(87); test.add(34); test.add(45); test.add(73); test.add(8); return test.findMax() == 87; })(), "The <code>findMax</code> method returns the maximum value in the binary search tree.");'
|
||||
- text: Los métodos <code>findMin</code> y <code>findMax</code> devuelven un <code>null</code> para un árbol vacío.
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; if (typeof test.findMin !== "function") { return false; }; if (typeof test.findMax !== "function") { return false; }; return (test.findMin() == null && test.findMax() == null) })(), "The <code>findMin</code> and <code>findMax</code> methods return <code>null</code> for an empty tree.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
var displayTree = (tree) => console.log(JSON.stringify(tree, null, 2));
|
||||
function Node(value) {
|
||||
this.value = value;
|
||||
this.left = null;
|
||||
this.right = null;
|
||||
}
|
||||
function BinarySearchTree() {
|
||||
this.root = null;
|
||||
// change code below this line
|
||||
// change code above this line
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
console.info('after the test');
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,75 @@
|
||||
---
|
||||
id: 587d825b367417b2b2512c8c
|
||||
title: Implement Heap Sort with a Min Heap
|
||||
localeTitle: Implementar Heap Sort con un Min Heap
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Ahora que podemos agregar y eliminar elementos, veamos algunas aplicaciones en las que se pueden usar los montones. Los montones se usan comúnmente para implementar colas de prioridad porque siempre almacenan un artículo de mayor o menor valor en la primera posición. Además, se utilizan para implementar un algoritmo de clasificación denominado ordenación de pila. Veremos cómo hacer esto aquí. La clasificación de montones utiliza un montón mínimo, lo contrario de un montón máximo. Un montón mínimo siempre almacena el elemento de menor valor en la posición raíz.
|
||||
ordenación de montones funciona tomando una matriz sin clasificar, agregando cada elemento de la matriz a un montón mínimo y luego extrayendo cada elemento de la pila mínima a una nueva matriz. La estructura de almacenamiento dinámico mínimo garantiza que la nueva matriz contendrá los elementos originales en el orden más pequeño al más grande. Este es uno de los algoritmos de clasificación más eficientes con un rendimiento promedio y en el peor de los casos de O (nlog (n)).
|
||||
Instrucciones: Implementemos la ordenación de pila con una pila mínima. Siéntase libre de adaptar su código de pila máxima aquí. Cree un objeto MinHeap con métodos de insertar, eliminar y ordenar. El método de clasificación debe devolver una matriz de todos los elementos en el montón mínimo ordenados de menor a mayor.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: La estructura de datos MinHeap existe.
|
||||
testString: 'assert((function() { var test = false; if (typeof MinHeap !== "undefined") { test = new MinHeap() }; return (typeof test == "object")})(), "The MinHeap data structure exists.");'
|
||||
- text: MinHeap tiene un método llamado insertar.
|
||||
testString: 'assert((function() { var test = false; if (typeof MinHeap !== "undefined") { test = new MinHeap() } else { return false; }; return (typeof test.insert == "function")})(), "MinHeap has a method called insert.");'
|
||||
- text: MinHeap tiene un método llamado eliminar.
|
||||
testString: 'assert((function() { var test = false; if (typeof MinHeap !== "undefined") { test = new MinHeap() } else { return false; }; return (typeof test.remove == "function")})(), "MinHeap has a method called remove.");'
|
||||
- text: MinHeap tiene un método llamado ordenar.
|
||||
testString: 'assert((function() { var test = false; if (typeof MinHeap !== "undefined") { test = new MinHeap() } else { return false; }; return (typeof test.sort == "function")})(), "MinHeap has a method called sort.");'
|
||||
- text: El método de clasificación devuelve una matriz que contiene todos los elementos agregados al montón mínimo en orden ordenado.
|
||||
testString: 'assert((function() { var test = false; if (typeof MinHeap !== "undefined") { test = new MinHeap() } else { return false; }; test.insert(3); test.insert(12); test.insert(5); test.insert(10); test.insert(1); test.insert(27); test.insert(42); test.insert(57); test.insert(5); var result = test.sort(); return (isSorted(result)); })(), "The sort method returns an array containing all items added to the min heap in sorted order.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
// check if array is sorted
|
||||
function isSorted(arr) {
|
||||
var check = (i) => (i == arr.length - 1) ? true : (arr[i] > arr[i + 1]) ? false : check(i + 1);
|
||||
return check(0);
|
||||
}
|
||||
// generate a randomly filled array
|
||||
var array = new Array();
|
||||
(function createArray(size = 5) {
|
||||
array.push(+(Math.random() * 100).toFixed(0));
|
||||
return (size > 1) ? createArray(size - 1) : undefined;
|
||||
})(25);
|
||||
var MinHeap = function() {
|
||||
// change code below this line
|
||||
// change code above this line
|
||||
};
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,75 @@
|
||||
---
|
||||
id: 587d8256367417b2b2512c79
|
||||
title: Incidence Matrix
|
||||
localeTitle: Matriz de incidencia
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Otra forma de representar una gráfica es colocarla en una <dfn>matriz de incidencia.</dfn>
|
||||
Una <dfn>matriz de incidencia</dfn> es una <dfn>matriz</dfn> bidimensional (2D). En términos generales, una matriz de incidencia relaciona dos clases diferentes de objetos entre sus dos dimensiones. Este tipo de matriz es similar a una matriz de adyacencia. Sin embargo, las filas y columnas significan algo más aquí.
|
||||
En las gráficas, tenemos aristas y nodos. Estas serán nuestras "dos clases diferentes de objetos". Esta matriz tendrá las filas, los nodos y las columnas, los bordes. Esto significa que podemos tener un número desigual de filas y columnas.
|
||||
Cada columna representará un borde único. Además, cada borde conecta dos nodos. Para mostrar que hay un borde entre dos nodos, colocará un 1 en las dos filas de una columna en particular. A continuación se muestra un gráfico de 3 nodos con un borde entre el nodo 1 y el nodo 3.
|
||||
<blockquote> 1<br> ---<br>1 | 1<br>2 | 0<br>3 | 1</blockquote>
|
||||
Aquí hay un ejemplo de una <code>incidence matrix</code> con 4 aristas y 4 nodos. Recuerde, las columnas son los bordes y las filas son los nodos mismos.
|
||||
<blockquote> 1 2 3 4<br> --------<br>1 | 0 1 1 1<br>2 | 1 1 0 0<br>3 | 1 0 0 1<br>4 | 0 0 1 0</blockquote>
|
||||
A continuación se muestra una implementación de JavaScript de la misma cosa.
|
||||
<blockquote>var incMat = [<br> [0, 1, 1, 1],<br> [1, 1, 0, 0],<br> [1, 0, 0, 1],<br> [0, 0, 1, 0]<br>];</blockquote>
|
||||
Para hacer un gráfico dirigido, use <code>-1</code> para un borde que sale de un nodo particular y <code>1</code> para un borde que ingresa a un nodo.
|
||||
<blockquote>var incMatDirected = [<br> [ 0, -1, 1, -1],<br> [-1, 1, 0, 0],<br> [ 1, 0, 0, 1],<br> [ 0, 0, -1, 0]<br>];</blockquote>
|
||||
gráficos también pueden tener <dfn>pesos</dfn> en sus bordes. Hasta ahora, tenemos bordes <dfn>no ponderados</dfn> donde solo la presencia y la falta de borde es binaria ( <code>0</code> o <code>1</code> ). Puede tener diferentes pesos dependiendo de su aplicación. Un peso diferente se representa como números mayores que 1.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
Cree una matriz de incidencia de un gráfico no dirigido con cinco nodos y cuatro bordes. Esta matriz debe estar en una matriz multidimensional.
|
||||
Estos cinco nodos tienen relaciones siguiendo relaciones. El primer borde está entre el primer y el segundo nodo. El segundo borde está entre el segundo y tercer nodo. El tercer borde está entre el tercer y quinto nodo. Y el borde cuatro está entre el cuarto y el segundo nodo. Todos los pesos de borde son uno y el orden de borde es importante.
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>incMatUndirected</code> solo debe contener cinco nodos.
|
||||
testString: 'assert((incMatUndirected.length === 5) && incMatUndirected.map(function(x) { return x.length === 4 }).reduce(function(a, b) { return a && b }) , "<code>incMatUndirected</code> should only contain five nodes.");'
|
||||
- text: Debe haber un primer borde entre el primer y el segundo nodo.
|
||||
testString: 'assert((incMatUndirected[0][0] === 1) && (incMatUndirected[1][0] === 1), "There should be a first edge between the first and second node.");'
|
||||
- text: Debe haber un segundo borde entre el segundo y tercer nodo.
|
||||
testString: 'assert((incMatUndirected[1][1] === 1) && (incMatUndirected[2][1] === 1), "There should be a second edge between the second and third node.");'
|
||||
- text: Debe haber un tercer borde entre el tercer y quinto nodo.
|
||||
testString: 'assert((incMatUndirected[2][2] === 1) && (incMatUndirected[4][2] === 1), "There should be a third edge between the third and fifth node.");'
|
||||
- text: Debe haber un cuarto borde entre el segundo y cuarto nodo.
|
||||
testString: 'assert((incMatUndirected[1][3] === 1) && (incMatUndirected[3][3] === 1), "There should be a fourth edge between the second and fourth node.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
var incMatUndirected = [
|
||||
|
||||
];
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
var incMatUndirected = [[1, 0, 0, 0],[1, 1, 0, 1],[0, 1, 1, 0],[0, 0, 0, 1],[0, 0, 1, 0]];
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,75 @@
|
||||
---
|
||||
id: 587d825a367417b2b2512c8a
|
||||
title: Insert an Element into a Max Heap
|
||||
localeTitle: Insertar un elemento en un montón máximo
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Ahora vamos a pasar a otra estructura de datos de árbol, el montón binario. Un montón binario es un árbol binario parcialmente ordenado que satisface la propiedad de montón. La propiedad del montón especifica una relación entre los nodos padre e hijo. Puede tener un montón máximo, en el que todos los nodos principales son mayores o iguales que sus nodos secundarios, o un montón mínimo, en el que lo contrario es cierto. Los montones binarios también son árboles binarios completos. Esto significa que todos los niveles del árbol están completamente llenos y si el último nivel está parcialmente lleno, se llenará de izquierda a derecha.
|
||||
Mientras que los montones binarios se pueden implementar como estructuras de árbol con nodos que contienen referencias a la izquierda y a la derecha, el orden parcial de acuerdo con la propiedad del montón nos permite representar el montón con una matriz. Lo que nos interesa es la relación padre-hijo y con aritmética simple podemos calcular los hijos de cualquier padre y el padre de cualquier nodo hijo.
|
||||
Por ejemplo, considere esta representación matricial de un montón binario mínimo:
|
||||
<code>[ 6, 22, 30, 37, 63, 48, 42, 76 ]</code>
|
||||
El nodo raíz es el primer elemento, 6. Sus hijos son 22 y 30. Si observamos la relación entre los índices de matriz de estos valores, para el índice i, los hijos son 2 * i + 1 y 2 * i + 2. Del mismo modo, el elemento en el índice 0 es el padre de estos dos hijos en los índices 1 y 2. Más generalmente, podemos encontrar el padre de un nodo en cualquier índice con lo siguiente: (i - 1) / 2. Estos patrones se mantendrán como verdaderos a medida que el árbol binario crezca a cualquier tamaño. Finalmente, podemos hacer un ligero ajuste para facilitar aún más esta aritmética al omitir el primer elemento de la matriz. Al hacer esto, se crea la siguiente relación para cualquier elemento en un índice dado i:
|
||||
Ejemplo Representación de matriz:
|
||||
<code>[ null, 6, 22, 30, 37, 63, 48, 42, 76 ]</code>
|
||||
Hijo de un elemento a la izquierda: i * 2
|
||||
El elemento derecho de un elemento: i * 2 + 1
|
||||
El elemento primario de un elemento: i / 2
|
||||
Una vez que encierre su cabeza alrededor de las matemáticas, usar una representación de matriz es muy útil porque las ubicaciones de los nodos se pueden determinar rápidamente con esta aritmética y el uso de la memoria disminuye. porque no es necesario mantener las referencias a los nodos secundarios.
|
||||
Instrucciones: Aquí crearemos un montón máximo. Comience simplemente creando un método de inserción que agregue elementos a nuestro montón. Durante la inserción, es importante mantener siempre la propiedad de montón. Para un montón máximo, esto significa que el elemento raíz siempre debe tener el mayor valor en el árbol y todos los nodos primarios deben ser mayores que sus secundarios. Para una implementación de matriz de un montón, esto normalmente se logra en tres pasos:
|
||||
Agregue el nuevo elemento al final de la matriz.
|
||||
Si el elemento es más grande que sus padres, cámbielos.
|
||||
Continúa cambiando hasta que el nuevo elemento sea más pequeño que su padre o llegues a la raíz del árbol.
|
||||
Finalmente, agregue un método de impresión que devuelva una matriz de todos los elementos que se han agregado al montón.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: La estructura de datos MaxHeap existe.
|
||||
testString: 'assert((function() { var test = false; if (typeof MaxHeap !== "undefined") { test = new MaxHeap() }; return (typeof test == "object")})(), "The MaxHeap data structure exists.");'
|
||||
- text: MaxHeap tiene un método llamado insertar.
|
||||
testString: 'assert((function() { var test = false; if (typeof MaxHeap !== "undefined") { test = new MaxHeap() } else { return false; }; return (typeof test.insert == "function")})(), "MaxHeap has a method called insert.");'
|
||||
- text: MaxHeap tiene un método llamado imprimir.
|
||||
testString: 'assert((function() { var test = false; if (typeof MaxHeap !== "undefined") { test = new MaxHeap() } else { return false; }; return (typeof test.print == "function")})(), "MaxHeap has a method called print.");'
|
||||
- text: El método de inserción agrega elementos de acuerdo con la propiedad max heap.
|
||||
testString: 'assert((function() { var test = false; if (typeof MaxHeap !== "undefined") { test = new MaxHeap() } else { return false; }; test.insert(50); test.insert(100); test.insert(700); test.insert(32); test.insert(51); let result = test.print(); return ((result.length == 5) ? result[0] == 700 : result[1] == 700) })(), "The insert method adds elements according to the max heap property.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
var MaxHeap = function() {
|
||||
// change code below this line
|
||||
// change code above this line
|
||||
};
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,75 @@
|
||||
---
|
||||
id: 587d8259367417b2b2512c83
|
||||
title: Invert a Binary Tree
|
||||
localeTitle: Invertir un árbol binario
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Aquí crearemos una función para invertir un árbol binario. Dado un árbol binario, queremos producir un nuevo árbol que sea equivalente a la imagen de espejo de este árbol. La ejecución de un recorrido inorder en un árbol invertido explorará los nodos en orden inverso en comparación con el recorrido inorder del árbol original. Escribe un método para hacer esto llamado <code>invert</code> en nuestro árbol binario. Llamar a este método debería invertir la estructura de árbol actual. Idealmente, nos gustaría hacer esto in situ en tiempo lineal. Es decir, solo visitamos cada nodo una vez y modificamos la estructura de árbol existente a medida que avanzamos, sin utilizar ninguna memoria adicional. ¡Buena suerte!
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: La estructura de datos <code>BinarySearchTree</code> existe.
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() }; return (typeof test == "object")})(), "The <code>BinarySearchTree</code> data structure exists.");'
|
||||
- text: El árbol de búsqueda binario tiene un método llamado <code>invert</code> .
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; return (typeof test.invert == "function")})(), "The binary search tree has a method called <code>invert</code>.");'
|
||||
- text: El método de <code>invert</code> invierte correctamente la estructura de árbol.
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; if (typeof test.invert !== "function") { return false; }; test.add(4); test.add(1); test.add(7); test.add(87); test.add(34); test.add(45); test.add(73); test.add(8); test.invert(); return test.inorder().join("") == "877345348741"; })(), "The <code>invert</code> method correctly inverts the tree structure.");'
|
||||
- text: Invertir un árbol vacío devuelve <code>null</code> .
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; if (typeof test.invert !== "function") { return false; }; return (test.invert() == null); })(), "Inverting an empty tree returns <code>null</code>.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
var displayTree = (tree) => console.log(JSON.stringify(tree, null, 2));
|
||||
function Node(value) {
|
||||
this.value = value;
|
||||
this.left = null;
|
||||
this.right = null;
|
||||
}
|
||||
function BinarySearchTree() {
|
||||
this.root = null;
|
||||
// change code below this line
|
||||
// change code above this line
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
console.info('after the test');
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,64 @@
|
||||
---
|
||||
id: 587d8250367417b2b2512c5e
|
||||
title: Learn how a Stack Works
|
||||
localeTitle: Aprende cómo funciona una pila
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Probablemente esté familiarizado con la pila de libros en su mesa. Es probable que haya utilizado la función de deshacer de un editor de texto. También es probable que esté acostumbrado a presionar el botón Atrás de su teléfono para volver a la vista anterior en su aplicación.
|
||||
¿Sabes lo que todos tienen en común? Todos ellos almacenan los datos de una manera que puede desplazarse hacia atrás.
|
||||
El libro más alto de la pila fue el que se colocó allí por última vez. Si quita ese libro de la parte superior de su pila, expondría el libro que se colocó allí antes del último libro y así sucesivamente.
|
||||
Si lo piensa, en todos los ejemplos anteriores, está recibiendo el tipo de servicio de <dfn>último en</dfn> entrar <dfn>, primero en salir</dfn> . Intentaremos imitar esto con nuestro código.
|
||||
Este esquema de almacenamiento de datos se llama una <dfn>pila</dfn> . En particular, tendríamos que implementar el método <code>push()</code> que empuja los objetos JavaScript en la parte superior de la pila; y el método <code>pop()</code> , que elimina el objeto JavaScript que está en la parte superior de la pila en el momento actual.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
Aquí tenemos una pila de asignaciones de tareas representadas como una matriz: <code>"BIO12"</code> está en la base, y <code>"PSY44"</code> está en la parte superior de la pila.
|
||||
Modifique la matriz dada y trátela como una <code>stack</code> usando los métodos de JavaScript mencionados anteriormente. Retire el elemento superior <code>"PSY44"</code> de la pila. Luego agrega <code>"CS50"</code> para que sea el nuevo elemento superior de la pila.
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>homeworkStack</code> solo debe contener 4 elementos.
|
||||
testString: 'assert(homeworkStack.length === 4, "<code>homeworkStack</code> should only contain 4 elements.");'
|
||||
- text: El último elemento en <code>homeworkStack</code> debería ser <code>"CS50"</code> .
|
||||
testString: 'assert(homeworkStack[3] === "CS50", "The last element in <code>homeworkStack</code> should be <code>"CS50"</code>.");'
|
||||
- text: <code>homeworkStack</code> no debe contener <code>"PSY44"</code> .
|
||||
testString: 'assert(homeworkStack.indexOf("PSY44") === -1, "<code>homeworkStack</code> should not contain <code>"PSY44"</code>.");'
|
||||
- text: La declaración inicial de <code>homeworkStack</code> no debe ser cambiada.
|
||||
testString: 'assert(code.match(/=/g).length === 1 && /homeworkStack\s*=\s*\["BIO12"\s*,\s*"HIS80"\s*,\s*"MAT122"\s*,\s*"PSY44"\]/.test(code), "The initial declaration of the <code>homeworkStack</code> should not be changed.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
var homeworkStack = ["BIO12","HIS80","MAT122","PSY44"];
|
||||
// Only change code below this line
|
||||
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,114 @@
|
||||
---
|
||||
id: 587d8254367417b2b2512c6e
|
||||
title: Perform a Difference on Two Sets of Data
|
||||
localeTitle: Realizar una diferencia en dos conjuntos de datos
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
En este ejercicio vamos a realizar una diferencia en 2 conjuntos de datos. Crearemos un método en nuestra estructura de datos de <code>Set</code> llamada <code>difference</code> . Una diferencia de conjuntos debe comparar dos conjuntos y devolver los elementos presentes en el primer conjunto que están ausentes en el segundo. Este método debe tomar otro <code>Set</code> como argumento y devolver la <code>difference</code> de los dos conjuntos.
|
||||
Por ejemplo, si <code>setA = ['a','b','c']</code> y <code>setB = ['a','b','d','e']</code> , entonces la diferencia de setA y setB es: <code>setA.difference(setB) = ['c']</code> .
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: Tu clase <code>Set</code> debería tener un método de <code>difference</code> .
|
||||
testString: 'assert(function(){var test = new Set(); return (typeof test.difference === "function")}, "Your <code>Set</code> class should have a <code>difference</code> method.");'
|
||||
- text: Se devolvió la colección adecuada.
|
||||
testString: 'assert(function(){var setA = new Set(); var setB = new Set(); setA.add("a"); setA.add("b"); setA.add("c"); setB.add("c"); setB.add("d"); var differenceSetAB = setA.difference(setB); return (differenceSetAB.size() === 2) && (differenceSetAB.values() === [ "a", "b" ])}, "The proper collection was returned");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function Set() {
|
||||
// the var collection will hold the set
|
||||
var collection = [];
|
||||
// this method will check for the presence of an element and return true or false
|
||||
this.has = function(element) {
|
||||
return (collection.indexOf(element) !== -1);
|
||||
};
|
||||
// this method will return all the values in the set
|
||||
this.values = function() {
|
||||
return collection;
|
||||
};
|
||||
// this method will add an element to the set
|
||||
this.add = function(element) {
|
||||
if(!this.has(element)){
|
||||
collection.push(element);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
// this method will remove an element from a set
|
||||
this.remove = function(element) {
|
||||
if(this.has(element)){
|
||||
var index = collection.indexOf(element);
|
||||
collection.splice(index,1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
// this method will return the size of the collection
|
||||
this.size = function() {
|
||||
return collection.length;
|
||||
};
|
||||
// this method will return the union of two sets
|
||||
this.union = function(otherSet) {
|
||||
var unionSet = new Set();
|
||||
var firstSet = this.values();
|
||||
var secondSet = otherSet.values();
|
||||
firstSet.forEach(function(e){
|
||||
unionSet.add(e);
|
||||
});
|
||||
secondSet.forEach(function(e){
|
||||
unionSet.add(e);
|
||||
});
|
||||
return unionSet;
|
||||
};
|
||||
// this method will return the intersection of two sets as a new set
|
||||
this.intersection = function(otherSet) {
|
||||
var intersectionSet = new Set();
|
||||
var firstSet = this.values();
|
||||
firstSet.forEach(function(e){
|
||||
if(otherSet.has(e)){
|
||||
intersectionSet.add(e);
|
||||
}
|
||||
});
|
||||
return intersectionSet;
|
||||
};
|
||||
// change code below this line
|
||||
// change code above this line
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
function Set() {var collection = []; this.has = function(e){return(collection.indexOf(e) !== -1);};this.values = function() {return collection;};this.add = function(element) {if (!this.has(element)) {collection.push(element);return true;} else {return false;}};this.remove = function(element) {if(this.has(element)) {var i = collection.indexOf(element);collection.splice(i, 1);return true;}return false;};this.size = function() {return collection.length;};this.union = function(set) {var u = new Set();var c = this.values();var s = set.values();c.forEach(function(element){u.add(element);});s.forEach(function(element){u.add(element);});return u;};this.intersection = function(set) {var i = new Set();var c = this.values();c.forEach(function(element){if(s.has(element)) i.add(element);});};this.difference = function(set) {var d = new Set();var c = this.values();c.forEach(function(e){if(!set.has(e)) d.add(e);});};}
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,133 @@
|
||||
---
|
||||
id: 587d8254367417b2b2512c6f
|
||||
title: Perform a Subset Check on Two Sets of Data
|
||||
localeTitle: Realizar una verificación de subconjunto en dos conjuntos de datos
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
En este ejercicio vamos a realizar una prueba de subconjunto en 2 conjuntos de datos. Crearemos un método en nuestra estructura de datos <code>Set</code> llamada <code>subset</code> . Esto comparará el primer conjunto, contra el segundo y si el primer conjunto está completamente contenido dentro del Segundo, devolverá verdadero.
|
||||
Por ejemplo, si <code>setA = ['a','b']</code> y <code>setB = ['a','b','c','d']</code> , entonces el subconjunto de setA y setB es: <code>setA.subset(setB)</code> debe ser <code>true</code> .
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: Tu clase <code>Set</code> debería tener un método de <code>union</code> .
|
||||
testString: 'assert(function(){var test = new Set(); return (typeof test.subset === "function")}, "Your <code>Set</code> class should have a <code>union</code> method.");'
|
||||
- text: El primer Set () estaba contenido en el segundo Set
|
||||
testString: 'assert(function(){var setA = new Set(); var setB = new Set(); setA.add("a"); setB.add("b"); setB.add("c"); setB.add("a"); setB.add("d"); var subsetSetAB = setA.subset(setB);return (subsetSetAB === true)}, "The first Set() was contained in the second Set");'
|
||||
- text: ' <code>["a", "b"].subset(["a", "b", "c", "d"])</code> debe devolver <code>true</code> ")'
|
||||
testString: 'assert(function(){var setA = new Set(); var setB = new Set(); setA.add("a"); setA.add("b"); setB.add("a"); setB.add("b"); setB.add("c"); setB.add("d"); var subsetSetAB = setA.subset(setB); return (subsetSetAB === true)}, "<code>["a", "b"].subset(["a", "b", "c", "d"])</code> should return <code>true</code>");'
|
||||
- text: ' <code>["a", "b", "c"].subset(["a", "b"])</code> debe devolver <code>false</code> ")'
|
||||
testString: 'assert(function(){var setA = new Set(); var setB = new Set(); setA.add("a"); setA.add("b"); setA.add("c"); setB.add("a"); setB.add("b"); var subsetSetAB = setA.subset(setB); return (subsetSetAB === false)}, "<code>["a", "b", "c"].subset(["a", "b"])</code> should return <code>false</code>");'
|
||||
- text: ' <code>[].subset([])</code> debe devolver <code>true</code> '
|
||||
testString: 'assert(function(){var setA = new Set(); var setB = new Set(); var subsetSetAB = setA.subset(setB); return (subsetSetAB === true)}, "<code>[].subset([])</code> should return <code>true</code>");'
|
||||
- text: ' <code>["a", "b"].subset(["c", "d"])</code> debe devolver <code>false</code> ")'
|
||||
testString: 'assert(function(){var setA = new Set(); var setB = new Set(); setA.add("a"); setA.add("b"); setB.add("c"); setB.add("d"); var subsetSetAB = setA.subset(setB); return (subsetSetAB === false)}, "<code>["a", "b"].subset(["c", "d"])</code> should return <code>false</code>");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function Set() {
|
||||
// the var collection will hold the set
|
||||
var collection = [];
|
||||
// this method will check for the presence of an element and return true or false
|
||||
this.has = function(element) {
|
||||
return (collection.indexOf(element) !== -1);
|
||||
};
|
||||
// this method will return all the values in the set
|
||||
this.values = function() {
|
||||
return collection;
|
||||
};
|
||||
// this method will add an element to the set
|
||||
this.add = function(element) {
|
||||
if(!this.has(element)){
|
||||
collection.push(element);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
// this method will remove an element from a set
|
||||
this.remove = function(element) {
|
||||
if(this.has(element)){
|
||||
var index = collection.indexOf(element);
|
||||
collection.splice(index,1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
// this method will return the size of the collection
|
||||
this.size = function() {
|
||||
return collection.length;
|
||||
};
|
||||
// this method will return the union of two sets
|
||||
this.union = function(otherSet) {
|
||||
var unionSet = new Set();
|
||||
var firstSet = this.values();
|
||||
var secondSet = otherSet.values();
|
||||
firstSet.forEach(function(e){
|
||||
unionSet.add(e);
|
||||
});
|
||||
secondSet.forEach(function(e){
|
||||
unionSet.add(e);
|
||||
});
|
||||
return unionSet;
|
||||
};
|
||||
// this method will return the intersection of two sets as a new set
|
||||
this.intersection = function(otherSet) {
|
||||
var intersectionSet = new Set();
|
||||
var firstSet = this.values();
|
||||
firstSet.forEach(function(e){
|
||||
if(otherSet.has(e)){
|
||||
intersectionSet.add(e);
|
||||
}
|
||||
});
|
||||
return intersectionSet;
|
||||
};
|
||||
// this method will return the difference of two sets as a new set
|
||||
this.difference = function(otherSet) {
|
||||
var differenceSet = new Set();
|
||||
var firstSet = this.values();
|
||||
firstSet.forEach(function(e){
|
||||
if(!otherSet.has(e)){
|
||||
differenceSet.add(e);
|
||||
}
|
||||
});
|
||||
return differenceSet;
|
||||
};
|
||||
// change code below this line
|
||||
// change code above this line
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
function Set() {var collection = []; this.has = function(e){return(collection.indexOf(e) !== -1);};this.values = function() {return collection;};this.add = function(element) {if (!this.has(element)) {collection.push(element);return true;} else {return false;}};this.remove = function(element) {if(this.has(element)) {var i = collection.indexOf(element);collection.splice(i, 1);return true;}return false;};this.size = function() {return collection.length;};this.union = function(set) {var u = new Set();var c = this.values();var s = set.values();c.forEach(function(element){u.add(element);});s.forEach(function(element){u.add(element);});return u;};this.intersection = function(set) {var i = new Set();var c = this.values();c.forEach(function(element){if(s.has(element)) i.add(element);});};this.difference = function(set) {var d = new Set();var c = this.values();c.forEach(function(e){if(!set.has(e)) d.add(e);});};this.subset = function(set) {var isSubset = true;var c = this.values();c.forEach(function(e){if(!set.has(e)) isSubset = false;});return isSubset;};}
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,91 @@
|
||||
---
|
||||
id: 587d8253367417b2b2512c6c
|
||||
title: Perform a Union on Two Sets
|
||||
localeTitle: Realizar una unión en dos sets
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
En este ejercicio vamos a realizar una unión en dos conjuntos de datos. Crearemos un método en nuestra estructura de datos de <code>Set</code> llamada <code>union</code> . Este método debe tomar otro <code>Set</code> como argumento y devolver la <code>union</code> de los dos conjuntos, excluyendo cualquier valor duplicado.
|
||||
Por ejemplo, si <code>setA = ['a','b','c']</code> y <code>setB = ['a','b','d','e']</code> , entonces la unión de setA y setB es: <code>setA.union(setB) = ['a', 'b', 'c', 'd', 'e']</code> .
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: Tu clase <code>Set</code> debería tener un método de <code>union</code> .
|
||||
testString: 'assert((function(){var test = new Set(); return (typeof test.union === "function")})(), "Your <code>Set</code> class should have a <code>union</code> method.");'
|
||||
- text: Se devolvió la colección adecuada.
|
||||
testString: 'assert((function(){var setA = new Set(); var setB = new Set(); setA.add("a"); setA.add("b"); setA.add("c"); setB.add("c"); setB.add("d"); var unionSetAB = setA.union(setB); var final = unionSetAB.values(); return (final.indexOf("a") !== -1 && final.indexOf("b") !== -1 && final.indexOf("c") !== -1 && final.indexOf("d") !== -1 && final.length === 4)})(), "The proper collection was returned");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function Set() {
|
||||
// the var collection will hold the set
|
||||
var collection = [];
|
||||
// this method will check for the presence of an element and return true or false
|
||||
this.has = function(element) {
|
||||
return (collection.indexOf(element) !== -1);
|
||||
};
|
||||
// this method will return all the values in the set
|
||||
this.values = function() {
|
||||
return collection;
|
||||
};
|
||||
// this method will add an element to the set
|
||||
this.add = function(element) {
|
||||
if(!this.has(element)){
|
||||
collection.push(element);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
// this method will remove an element from a set
|
||||
this.remove = function(element) {
|
||||
if(this.has(element)){
|
||||
var index = collection.indexOf(element);
|
||||
collection.splice(index,1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
// this method will return the size of the set
|
||||
this.size = function() {
|
||||
return collection.length;
|
||||
};
|
||||
// change code below this line
|
||||
|
||||
// change code above this line
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
function Set() {var collection = []; this.has = function(e){return(collection.indexOf(e) !== -1);};this.values = function() {return collection;};this.add = function(element) {if (!this.has(element)) {collection.push(element);return true;} else {return false;}};this.remove = function(element) {if(this.has(element)) {var i = collection.indexOf(element);collection.splice(i, 1);return true;}return false;};this.size = function() {return collection.length;};this.union = function(set) {var u = new Set();var c = this.values();var s = set.values();c.forEach(function(element){u.add(element);});s.forEach(function(element){u.add(element);});return u;};}
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,103 @@
|
||||
---
|
||||
id: 587d8253367417b2b2512c6d
|
||||
title: Perform an Intersection on Two Sets of Data
|
||||
localeTitle: Realizar una intersección en dos conjuntos de datos
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
En este ejercicio vamos a realizar una intersección en 2 conjuntos de datos. Crearemos un método en nuestra estructura de datos del <code>Set</code> llamada <code>intersection</code> . Una intersección de conjuntos representa todos los valores que son comunes a dos o más conjuntos. Este método debe tomar otro <code>Set</code> como argumento y devolver la <code>intersection</code> de los dos conjuntos.
|
||||
Por ejemplo, si <code>setA = ['a','b','c']</code> y <code>setB = ['a','b','d','e']</code> , entonces la intersección de setA y setB es: <code>setA.intersection(setB) = ['a', 'b']</code> .
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: Tu clase <code>Set</code> debería tener un método de <code>intersection</code> .
|
||||
testString: 'assert(function(){var test = new Set(); return (typeof test.intersection === "function")}, "Your <code>Set</code> class should have a <code>intersection</code> method.");'
|
||||
- text: Se devolvió la colección adecuada.
|
||||
testString: 'assert(function(){ var setA = new Set(); var setB = new Set(); setA.add("a"); setA.add("b"); setA.add("c"); setB.add("c"); setB.add("d"); var intersectionSetAB = setA.intersection(setB); return (intersectionSetAB.size() === 1 && intersectionSetAB.values()[0] === "c")}, "The proper collection was returned");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function Set() {
|
||||
// the var collection will hold the set
|
||||
var collection = [];
|
||||
// this method will check for the presence of an element and return true or false
|
||||
this.has = function(element) {
|
||||
return (collection.indexOf(element) !== -1);
|
||||
};
|
||||
// this method will return all the values in the set
|
||||
this.values = function() {
|
||||
return collection;
|
||||
};
|
||||
// this method will add an element to the set
|
||||
this.add = function(element) {
|
||||
if(!this.has(element)){
|
||||
collection.push(element);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
// this method will remove an element from a set
|
||||
this.remove = function(element) {
|
||||
if(this.has(element)){
|
||||
var index = collection.indexOf(element);
|
||||
collection.splice(index,1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
// this method will return the size of the collection
|
||||
this.size = function() {
|
||||
return collection.length;
|
||||
};
|
||||
// this method will return the union of two sets
|
||||
this.union = function(otherSet) {
|
||||
var unionSet = new Set();
|
||||
var firstSet = this.values();
|
||||
var secondSet = otherSet.values();
|
||||
firstSet.forEach(function(e){
|
||||
unionSet.add(e);
|
||||
});
|
||||
secondSet.forEach(function(e){
|
||||
unionSet.add(e);
|
||||
});
|
||||
return unionSet;
|
||||
};
|
||||
// change code below this line
|
||||
// change code above this line
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
function Set() {var collection = []; this.has = function(e){return(collection.indexOf(e) !== -1);};this.values = function() {return collection;};this.add = function(element) {if (!this.has(element)) {collection.push(element);return true;} else {return false;}};this.remove = function(element) {if(this.has(element)) {var i = collection.indexOf(element);collection.splice(i, 1);return true;}return false;};this.size = function() {return collection.length;};this.union = function(set) {var u = new Set();var c = this.values();var s = set.values();c.forEach(function(element){u.add(element);});s.forEach(function(element){u.add(element);});return u;};this.intersection = function(set) {var i = new Set();var c = this.values();c.forEach(function(element){if(s.has(element)) i.add(element);});};}
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,66 @@
|
||||
---
|
||||
id: 587d825b367417b2b2512c8b
|
||||
title: Remove an Element from a Max Heap
|
||||
localeTitle: Eliminar un elemento de un montón máximo
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Ahora que podemos agregar elementos a nuestro montón, veamos cómo podemos eliminar elementos. Eliminar e insertar elementos requiere una lógica similar. En un montón máximo, normalmente querrá eliminar el mayor valor, por lo que esto implica simplemente extraerlo de la raíz de nuestro árbol. Esto romperá la propiedad del montón de nuestro árbol, por lo que debemos restablecerla de alguna manera. Normalmente, para un montón máximo, esto se hace de la siguiente manera:
|
||||
Mueva el último elemento del montón a la posición raíz.
|
||||
Si cualquiera de los hijos de la raíz es mayor, intercambie la raíz con el hijo de mayor valor.
|
||||
Continúa intercambiando hasta que el padre sea mayor que ambos hijos o hasta que alcances el último nivel en el árbol.
|
||||
Instrucciones: Agregue un método a nuestro montón máximo llamado eliminar. Este método debe devolver el mayor valor que se ha agregado a nuestro montón máximo y eliminarlo del montón. También debe reordenar el montón para que se mantenga la propiedad de montón. Después de eliminar un elemento, el siguiente elemento más grande que quede en el montón debe convertirse en la raíz. Agregue su método de inserción de nuevo aquí también.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: La estructura de datos MaxHeap existe.
|
||||
testString: 'assert((function() { var test = false; if (typeof MaxHeap !== "undefined") { test = new MaxHeap() }; return (typeof test == "object")})(), "The MaxHeap data structure exists.");'
|
||||
- text: MaxHeap tiene un método llamado imprimir.
|
||||
testString: 'assert((function() { var test = false; if (typeof MaxHeap !== "undefined") { test = new MaxHeap() } else { return false; }; return (typeof test.print == "function")})(), "MaxHeap has a method called print.");'
|
||||
- text: MaxHeap tiene un método llamado insertar.
|
||||
testString: 'assert((function() { var test = false; if (typeof MaxHeap !== "undefined") { test = new MaxHeap() } else { return false; }; return (typeof test.insert == "function")})(), "MaxHeap has a method called insert.");'
|
||||
- text: MaxHeap tiene un método llamado eliminar.
|
||||
testString: 'assert((function() { var test = false; if (typeof MaxHeap !== "undefined") { test = new MaxHeap() } else { return false; }; return (typeof test.remove == "function")})(), "MaxHeap has a method called remove.");'
|
||||
- text: El método de eliminación elimina el elemento más grande de la pila máxima y mantiene la propiedad de pila máxima.
|
||||
testString: 'assert((function() { var test = false; if (typeof MaxHeap !== "undefined") { test = new MaxHeap() } else { return false; }; test.insert(30); test.insert(300); test.insert(500); test.insert(10); let result = []; result.push(test.remove()); result.push(test.remove()); result.push(test.remove()); result.push(test.remove()); return (result.join("") == "5003003010") })(), "The remove method removes the greatest element from the max heap while maintaining the max heap property.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
var MaxHeap = function() {
|
||||
// change code below this line
|
||||
// change code above this line
|
||||
};
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,118 @@
|
||||
---
|
||||
id: 587d8251367417b2b2512c65
|
||||
title: Remove Elements from a Linked List by Index
|
||||
localeTitle: Eliminar elementos de una lista enlazada por índice
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Antes de pasar a otra estructura de datos, obtengamos un par de los últimos bits de práctica con listas vinculadas.
|
||||
Escribamos un método <code>removeAt</code> que elimine el <code>element</code> en un <code>index</code> dado. El método debe llamarse <code>removeAt(index)</code> . Para eliminar un <code>element</code> en un determinado <code>index</code> , deberemos mantener un recuento de cada nodo a medida que avanzamos a lo largo de la lista vinculada.
|
||||
Una técnica común utilizada para recorrer los elementos de una lista enlazada involucra a un <dfn>'corredor'</dfn> , o centinela, que 'apunta' a los nodos que su código está comparando. En nuestro caso, a partir de la <code>head</code> de nuestra lista, comenzamos con una <code>currentIndex</code> variable que comienza en <code>0</code> . El <code>currentIndex</code> debe incrementarse en uno para cada nodo que pasemos.
|
||||
Al igual que con nuestro método <code>remove(element)</code> , debemos tener cuidado de no dejar huérfano al resto de nuestra lista cuando eliminamos el nodo en nuestro método removeAt (índice). Mantenemos nuestros nodos contiguos asegurándonos de que el nodo que tiene referencia al nodo eliminado tenga una referencia al siguiente nodo.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
Escriba un <code>removeAt(index)</code> que elimine y devuelva un nodo a un <code>index</code> determinado. El método debe devolver <code>null</code> si el <code>index</code> dado es negativo, o mayor o igual a la <code>length</code> de la lista enlazada.
|
||||
Nota
|
||||
Recuerde mantener la cuenta del <code>currentIndex</code> .
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: Su clase <code>LinkedList</code> debe tener un método <code>removeAt</code> .
|
||||
testString: 'assert((function(){var test = new LinkedList(); return (typeof test.removeAt === "function")}()), "Your <code>LinkedList</code> class should have a <code>removeAt</code> method.");'
|
||||
- text: Su método <code>removeAt</code> debería reducir la <code>length</code> de la lista enlazada
|
||||
testString: 'assert((function(){var test = new LinkedList(); test.add("cat"); test.add("dog"); test.add("kitten"); test.removeAt(1); return test.size() === 2}()), "Your <code>removeAt</code> method should reduce the <code>length</code> of the linked list");'
|
||||
- text: El método <code>removeAt</code> también debe devolver el elemento del nodo eliminado.
|
||||
testString: 'assert((function(){var test = new LinkedList(); test.add("cat"); test.add("dog"); test.add("kitten"); return test.removeAt(1) === "dog"}()), "Your <code>removeAt</code> method should also return the element of the removed node.");'
|
||||
- text: El método <code>removeAt</code> también debe devolver <code>null</code> si el índice dado es menor que <code>0</code>
|
||||
testString: 'assert((function(){var test = new LinkedList(); test.add("cat"); test.add("dog"); test.add("kitten"); return (test.removeAt(-1) === null)}()), "Your <code>removeAt</code> method should also return <code>null</code> if the given index is less than <code>0</code>");'
|
||||
- text: El método <code>removeAt</code> también debe devolver un <code>null</code> si el índice dado es igual o mayor que la <code>length</code> de la lista enlazada.
|
||||
testString: 'assert((function(){var test = new LinkedList(); test.add("cat"); test.add("dog"); test.add("kitten"); return (test.removeAt(3) === null)}()), "Your <code>removeAt</code> method should also return <code>null</code> if the given index is equal or more than the <code>length</code> of the linked list.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function LinkedList() {
|
||||
var length = 0;
|
||||
var head = null;
|
||||
|
||||
var Node = function(element){ // {1}
|
||||
this.element = element;
|
||||
this.next = null;
|
||||
};
|
||||
|
||||
this.size = function(){
|
||||
return length;
|
||||
};
|
||||
|
||||
this.head = function(){
|
||||
return head;
|
||||
};
|
||||
|
||||
this.add = function(element){
|
||||
var node = new Node(element);
|
||||
if(head === null){
|
||||
head = node;
|
||||
} else {
|
||||
currentNode = head;
|
||||
|
||||
while(currentNode.next){
|
||||
currentNode = currentNode.next;
|
||||
}
|
||||
|
||||
currentNode.next = node;
|
||||
}
|
||||
|
||||
length++;
|
||||
};
|
||||
|
||||
this.remove = function(element){
|
||||
var currentNode = head;
|
||||
var previousNode;
|
||||
if(currentNode.element === element){
|
||||
head = currentNode.next;
|
||||
} else {
|
||||
while(currentNode.element !== element) {
|
||||
previousNode = currentNode;
|
||||
currentNode = currentNode.next;
|
||||
}
|
||||
|
||||
previousNode.next = currentNode.next;
|
||||
}
|
||||
|
||||
length --;
|
||||
};
|
||||
|
||||
// Only change code below this line
|
||||
|
||||
// Only change code above this line
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,161 @@
|
||||
---
|
||||
id: 587d8251367417b2b2512c63
|
||||
title: Remove Elements from a Linked List
|
||||
localeTitle: Eliminar elementos de una lista enlazada
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
El siguiente método importante que necesitará cualquier implementación de una lista vinculada es un método de <code>remove</code> . Este método debe tomar el elemento que queremos eliminar como argumento y luego buscar en la lista para encontrar y eliminar el nodo que contiene ese elemento.
|
||||
Siempre que eliminemos un nodo de una lista vinculada, es importante que no dejemos huérfanos accidentalmente al hacerlo. Recuerde que la <code>next</code> propiedad de cada nodo apunta al nodo que lo sigue en la lista. Si estamos eliminando el elemento medio, por ejemplo, vamos a querer asegurarse de que tenemos una conexión desde previa del nodo de ese elemento <code>next</code> propiedad para el elemento medio <code>next</code> propiedad (que es el siguiente nodo en la lista!)
|
||||
Esto podría suena realmente confuso, así que volvamos al ejemplo de la línea de conga para tener un buen modelo conceptual. Imagínate a ti mismo en una línea de conga, y la persona que está directamente delante de ti deja la línea. La persona que acaba de dejar la línea ya no tiene a sus manos sobre nadie, y usted ya no tiene las manos sobre la persona que se fue. Da un paso adelante y pone sus manos sobre la siguiente persona que ve.
|
||||
Si el elemento que queremos eliminar es el elemento <code>head</code> , reasignamos la <code>head</code> al segundo nodo de la lista enlazada.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
Escriba un método de <code>remove</code> que tome un elemento y lo elimine de la lista vinculada.
|
||||
Nota
|
||||
La <code>length</code> de la lista debe disminuir en uno cada vez que se elimine un elemento de la lista vinculada.
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: Su clase <code>LinkedList</code> debe tener un método de <code>remove</code> .
|
||||
testString: 'assert((function(){var test = new LinkedList(); return (typeof test.remove === "function")}()), "Your <code>LinkedList</code> class should have a <code>remove</code> method.");'
|
||||
- text: Su método de <code>remove</code> debe reasignar la <code>head</code> al segundo nodo cuando se elimina el primer nodo.
|
||||
testString: 'assert((function(){var test = new LinkedList(); test.add("cat"); test.add("dog"); test.remove("cat"); return test.head().element === "dog"}()), "Your <code>remove</code> method should reassign <code>head</code> to the second node when the first node is removed.");'
|
||||
- text: Su método de <code>remove</code> debe disminuir la <code>length</code> de la lista enlazada en uno por cada nodo eliminado.
|
||||
testString: 'assert((function(){var test = new LinkedList(); test.add("cat"); test.add("dog"); test.remove("cat"); return test.size() === 1})(), "Your <code>remove</code> method should decrease the <code>length</code> of the linked list by one for every node removed.");'
|
||||
- text: El método de <code>remove</code> debe reasignar la referencia del nodo anterior del nodo eliminado a la <code>next</code> referencia del nodo eliminado.
|
||||
testString: 'assert((function(){var test = new LinkedList(); test.add("cat"); test.add("dog");test.add("kitten"); test.remove("dog"); return test.head().next.element === "kitten"})(), "Your <code>remove</code> method should reassign the reference of the previous node of the removed node to the removed node's <code>next</code> reference.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function LinkedList() {
|
||||
var length = 0;
|
||||
var head = null;
|
||||
|
||||
var Node = function(element){
|
||||
this.element = element;
|
||||
this.next = null;
|
||||
};
|
||||
|
||||
this.size = function(){
|
||||
return length;
|
||||
};
|
||||
|
||||
this.head = function(){
|
||||
return head;
|
||||
};
|
||||
|
||||
this.add = function(element){
|
||||
var node = new Node(element);
|
||||
if(head === null){
|
||||
head = node;
|
||||
} else {
|
||||
currentNode = head;
|
||||
|
||||
while(currentNode.next){
|
||||
currentNode = currentNode.next;
|
||||
}
|
||||
|
||||
currentNode.next = node;
|
||||
}
|
||||
|
||||
length++;
|
||||
};
|
||||
|
||||
this.remove = function(element){
|
||||
// Only change code below this line
|
||||
|
||||
// Only change code above this line
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
class Node {
|
||||
constructor (element) {
|
||||
this.element = element;
|
||||
this.next = null;
|
||||
}
|
||||
}
|
||||
|
||||
class LinkedList {
|
||||
constructor () {
|
||||
this._length = 0;
|
||||
this._head = null;
|
||||
}
|
||||
|
||||
head () {
|
||||
return this._head;
|
||||
}
|
||||
|
||||
size () {
|
||||
return this._length;
|
||||
}
|
||||
|
||||
add (element) {
|
||||
const node = new Node(element);
|
||||
|
||||
if (this._head === null) {
|
||||
this._head = node;
|
||||
} else {
|
||||
let current = this._head;
|
||||
|
||||
while (current.next !== null) {
|
||||
current = current.next;
|
||||
}
|
||||
|
||||
current.next = node;
|
||||
}
|
||||
|
||||
++this._length;
|
||||
}
|
||||
|
||||
remove (element) {
|
||||
if (this._head === null) return;
|
||||
|
||||
let previous;
|
||||
let current = this._head;
|
||||
|
||||
while (current.next !== null && current.element !== element) {
|
||||
previous = current;
|
||||
current = current.next;
|
||||
}
|
||||
|
||||
if (previous) {
|
||||
previous.next = current.next;
|
||||
} else {
|
||||
this._head = current.next;
|
||||
}
|
||||
|
||||
--this._length;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,78 @@
|
||||
---
|
||||
id: 587d8253367417b2b2512c6b
|
||||
title: Remove from a Set
|
||||
localeTitle: Eliminar de un conjunto
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
En este ejercicio vamos a crear una función de borrado para nuestro conjunto. La función debe llamarse <code>this.remove</code> . Esta función debe aceptar un valor y verificar si existe en el conjunto. Si lo hace, elimine ese valor del conjunto y devuelva verdadero. De lo contrario, devuelve falso.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: Tu clase <code>Set</code> debería tener un método de <code>remove</code> .
|
||||
testString: 'assert((function(){var test = new Set(); return (typeof test.remove === "function")}()), "Your <code>Set</code> class should have a <code>remove</code> method.");'
|
||||
- text: El método de <code>remove</code> solo debe eliminar los elementos que están presentes en el conjunto.
|
||||
testString: 'assert.deepEqual((function(){var test = new Set(); test.add("a");test.add("b");test.remove("c"); return test.values(); })(), ["a", "b"], "Your <code>remove</code> method should only remove items that are present in the set.");'
|
||||
- text: Su método de <code>remove</code> debe eliminar el elemento dado del conjunto.
|
||||
testString: 'assert((function(){var test = new Set(); test.add("a");test.add("b");test.remove("a"); var vals = test.values(); return (vals[0] === "b" && vals.length === 1)}()), "Your <code>remove</code> method should remove the given item from the set.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function Set() {
|
||||
// the var collection will hold the set
|
||||
var collection = [];
|
||||
// this method will check for the presence of an element and return true or false
|
||||
this.has = function(element) {
|
||||
return (collection.indexOf(element) !== -1);
|
||||
};
|
||||
// this method will return all the values in the set
|
||||
this.values = function() {
|
||||
return collection;
|
||||
};
|
||||
// this method will add an element to the set
|
||||
this.add = function(element) {
|
||||
if(!this.has(element)){
|
||||
collection.push(element);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
// change code below this line
|
||||
// change code above this line
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
function Set() {var collection = []; this.has = function(e){return(collection.indexOf(e) !== -1);};this.values = function() {return collection;};this.add = function(element) {if (!this.has(element)) {collection.push(element);return true;} else {return false;}};this.remove = function(element) {if(this.has(element)) {var i = collection.indexOf(element);collection.splice(i, 1);return true;}return false;};}
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,68 @@
|
||||
---
|
||||
id: 587d8254367417b2b2512c71
|
||||
title: Remove items from a set in ES6
|
||||
localeTitle: Eliminar elementos de un conjunto en ES6
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Practiquemos la eliminación de elementos de un Conjunto ES6 utilizando el método de <code>delete</code> .
|
||||
Primero, cree un conjunto ES6
|
||||
<code>var set = new Set([1,2,3]);</code>
|
||||
Ahora elimine un elemento de su Set con el método de <code>delete</code> .
|
||||
<blockquote>set.delete(1);<br>console.log([...set]) // should return [ 2, 3 ]<blockquote>
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
Ahora, cree un conjunto con los enteros 1, 2, 3, 4 y 5.
|
||||
Elimine los valores 2 y 5, y luego devuelva el conjunto.
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: 'Tu Set debe contener los valores 1, 3 y 4'
|
||||
testString: 'assert(function(){var test = checkSet(); return test.has(1) && test.has(3) && test.has(4) && test.size === 3}, "Your Set should contain the values 1, 3, & 4");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function checkSet(){
|
||||
var set = //Create a set with values 1, 2, 3, 4, & 5
|
||||
//Remove the value 2
|
||||
//Remove the value 5
|
||||
//Return the set
|
||||
return set;
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
function checkSet(){
|
||||
var set = new Set([1,2,3,4,5]);
|
||||
set.delete(2);
|
||||
set.delete(5);
|
||||
return set;}
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,79 @@
|
||||
---
|
||||
id: 587d825a367417b2b2512c88
|
||||
title: Reverse a Doubly Linked List
|
||||
localeTitle: Invertir una lista doblemente vinculada
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Creemos un método más para nuestra lista doblemente enlazada llamada reversa que invierte la lista en su lugar. Una vez que se ejecuta el método, la cabeza debe apuntar a la cola anterior y la cola debe apuntar a la cabeza anterior. Ahora, si recorremos la lista de principio a fin, deberíamos encontrar los nodos en orden inverso en comparación con la lista original. Intentar revertir una lista vacía debe devolver nulo.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: La estructura de datos DoublyLinkedList existe.
|
||||
testString: 'assert((function() { var test = false; if (typeof DoublyLinkedList !== "undefined") { test = new DoublyLinkedList() }; return (typeof test == "object")})(), "The DoublyLinkedList data structure exists.");'
|
||||
- text: DoublyLinkedList tiene un método llamado agregar.
|
||||
testString: 'assert((function() { var test = false; if (typeof DoublyLinkedList !== "undefined") { test = new DoublyLinkedList() }; if (test.add == undefined) { return false; }; return (typeof test.add == "function")})(), "The DoublyLinkedList has a method called add.");'
|
||||
- text: El DoublyLinkedList tiene un método llamado reversa.
|
||||
testString: 'assert((function() { var test = false; if (typeof DoublyLinkedList !== "undefined") { test = new DoublyLinkedList() }; if (test.reverse == undefined) { return false; }; return (typeof test.reverse == "function")})(), "The DoublyLinkedList has a method called reverse.");'
|
||||
- text: Invertir una lista vacía devuelve nulo.
|
||||
testString: 'assert((function() { var test = false; if (typeof DoublyLinkedList !== "undefined") { test = new DoublyLinkedList() }; return (test.reverse() == null); })(), "Reversing an empty list returns null.");'
|
||||
- text: El método inverso invierte la lista.
|
||||
testString: 'assert((function() { var test = false; if (typeof DoublyLinkedList !== "undefined") { test = new DoublyLinkedList() }; test.add(58); test.add(61); test.add(32); test.reverse(); return (test.print().join("") == "326158"); })(), "The reverse method reverses the list.");'
|
||||
- text: Las referencias siguientes y anteriores se mantienen correctamente cuando se invierte una lista.
|
||||
testString: 'assert((function() { var test = false; if (typeof DoublyLinkedList !== "undefined") { test = new DoublyLinkedList() }; test.add(11); test.add(22); test.add(33); test.reverse(); return (test.printReverse().join("") == "112233"); })(), "The next and previous references are correctly maintained when a list is reversed.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
var Node = function(data, prev) {
|
||||
this.data = data;
|
||||
this.prev = prev;
|
||||
this.next = null;
|
||||
};
|
||||
var DoublyLinkedList = function() {
|
||||
this.head = null;
|
||||
this.tail = null;
|
||||
// change code below this line
|
||||
// change code above this line
|
||||
};
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
console.info('after the test');
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,114 @@
|
||||
---
|
||||
id: 587d8251367417b2b2512c64
|
||||
title: Search within a Linked List
|
||||
localeTitle: Buscar dentro de una lista enlazada
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Agreguemos algunos métodos más útiles a nuestra clase de lista vinculada. ¿No sería útil si pudiéramos decir si nuestra lista estaba vacía o no, al igual que con nuestras clases de <code>Stack</code> y <code>Queue</code> ?
|
||||
También deberíamos poder encontrar elementos específicos en nuestra lista enlazada. ¡Recorrer a través de estructuras de datos es algo con lo que querrás practicar mucho! Vamos a crear un método <code>indexOf</code> que tome un <code>element</code> como un argumento y devuelva el <code>index</code> ese elemento en la lista enlazada. Si el elemento no se encuentra en la lista enlazada, devuelva <code>-1</code> .
|
||||
Implementemos también un método que haga lo contrario: un método <code>elementAt</code> que toma un <code>index</code> como argumento y devuelve el <code>element</code> en el <code>index</code> dado. Si no se encuentra ningún <code>element</code> , devuelva <code>undefined</code> .
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
Escriba un método <code>isEmpty</code> que compruebe si la lista enlazada está vacía, un método <code>indexOf</code> que devuelve el <code>index</code> de un elemento determinado y un <code>elementAt</code> que devuelve un <code>element</code> en un <code>index. <code>0</code></code> determinado <code>index. <code>0</code></code> </section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: Su clase <code>LinkedList</code> debe tener un método <code>indexOf</code> .
|
||||
testString: 'assert((function(){var test = new LinkedList(); return (typeof test.indexOf === "function")}()), "Your <code>LinkedList</code> class should have a <code>indexOf</code> method.");'
|
||||
- text: Tu clase <code>LinkedList</code> debe tener un método <code>elementAt</code> .
|
||||
testString: 'assert((function(){var test = new LinkedList(); return (typeof test.elementAt === "function")}()), "Your <code>LinkedList</code> class should have a <code>elementAt</code> method.");'
|
||||
- text: Su método de <code>size</code> debe devolver la longitud de la lista enlazada
|
||||
testString: 'assert((function(){var test = new LinkedList(); test.add("cat"); test.add("dog"); test.add("kitten"); return test.size() === 3}()), "Your <code>size</code> method should return the length of the linked list");'
|
||||
- text: Su método <code>indexOf</code> debe devolver el índice del elemento dado.
|
||||
testString: 'assert((function(){var test = new LinkedList(); test.add("cat"); test.add("dog"); test.add("kitten"); return test.indexOf("kitten") === 2}()), "Your <code>indexOf</code> method should return the index of the given element.");'
|
||||
- text: Su método <code>elementAt</code> debería regresar al elemento en un índice dado.
|
||||
testString: 'assert((function(){var test = new LinkedList(); test.add("cat"); test.add("dog"); test.add("kitten"); return test.elementAt(1) === "dog"}()), "Your <code>elementAt</code> method should return at element at a given index.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function LinkedList() {
|
||||
var length = 0;
|
||||
var head = null;
|
||||
|
||||
var Node = function(element){ // {1}
|
||||
this.element = element;
|
||||
this.next = null;
|
||||
};
|
||||
|
||||
this.size = function() {
|
||||
return length;
|
||||
};
|
||||
|
||||
this.head = function(){
|
||||
return head;
|
||||
};
|
||||
|
||||
this.add = function(element){
|
||||
var node = new Node(element);
|
||||
if(head === null){
|
||||
head = node;
|
||||
} else {
|
||||
currentNode = head;
|
||||
|
||||
while(currentNode.next){
|
||||
currentNode = currentNode.next;
|
||||
}
|
||||
|
||||
currentNode.next = node;
|
||||
}
|
||||
|
||||
length++;
|
||||
};
|
||||
|
||||
this.remove = function(element){
|
||||
var currentNode = head;
|
||||
var previousNode;
|
||||
if(currentNode.element === element){
|
||||
head = currentNode.next;
|
||||
} else {
|
||||
while(currentNode.element !== element) {
|
||||
previousNode = currentNode;
|
||||
currentNode = currentNode.next;
|
||||
}
|
||||
|
||||
previousNode.next = currentNode.next;
|
||||
}
|
||||
|
||||
length --;
|
||||
};
|
||||
|
||||
// Only change code below this line
|
||||
|
||||
// Only change code above this line
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,85 @@
|
||||
---
|
||||
id: 8d1923c8c441eddfaeb5bdef
|
||||
title: Size of the Set
|
||||
localeTitle: Tamaño del set
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
En este ejercicio vamos a crear una función de tamaño para nuestro Conjunto. Esta función debe llamarse <code>this.size</code> y debe devolver el tamaño de la colección.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: Tu clase <code>Set</code> debería tener un método de <code>size</code> .
|
||||
testString: 'assert((function(){var test = new Set(); return (typeof test.size === "function")}()), "Your <code>Set</code> class should have a <code>size</code> method.");'
|
||||
- text: El método de <code>size</code> debe devolver el número de elementos en la colección.
|
||||
testString: 'assert((function(){var test = new Set(); test.add("a");test.add("b");test.remove("a");return (test.size() === 1)}()), "The <code>size</code> method should return the number of elements in the collection.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function Set() {
|
||||
// the var collection will hold the set
|
||||
var collection = [];
|
||||
// this method will check for the presence of an element and return true or false
|
||||
this.has = function(element) {
|
||||
return (collection.indexOf(element) !== -1);
|
||||
};
|
||||
// this method will return all the values in the set
|
||||
this.values = function() {
|
||||
return collection;
|
||||
};
|
||||
// this method will add an element to the set
|
||||
this.add = function(element) {
|
||||
if(!this.has(element)){
|
||||
collection.push(element);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
// this method will remove an element from a set
|
||||
this.remove = function(element) {
|
||||
if(this.has(element)){
|
||||
var index = collection.indexOf(element);
|
||||
collection.splice(index,1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
// change code below this line
|
||||
// change code above this line
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
function Set() {var collection = []; this.has = function(e){return(collection.indexOf(e) !== -1);};this.values = function() {return collection;};this.add = function(element) {if (!this.has(element)) {collection.push(element);return true;} else {return false;}};this.remove = function(element) {if(this.has(element)) {var i = collection.indexOf(element);collection.splice(i, 1);return true;}return false;};this.size = function() {return collection.length;};}
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,72 @@
|
||||
---
|
||||
id: 587d8253367417b2b2512c6a
|
||||
title: Typed Arrays
|
||||
localeTitle: Matrices mecanografiadas
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
matrices son objetos de JavaScript que pueden contener muchos elementos diferentes.
|
||||
<code>var complexArr = [1, 5, "2", "Word", {"name": "James"}];</code>
|
||||
Básicamente, lo que sucede en segundo plano es que su navegador le dará automáticamente la cantidad correcta de espacio de memoria para esa matriz. También cambiará según sea necesario si agrega o elimina datos.
|
||||
Sin embargo, en el mundo del alto rendimiento y los diferentes tipos de elementos, a veces debe ser más específico sobre la cantidad de memoria que se asigna a una matriz.
|
||||
<dfn>Arrays tipados</dfn> son la respuesta a este problema. Ahora puede decir cuánta memoria desea asignar a una matriz. A continuación se muestra una descripción básica de los diferentes tipos de arreglos disponibles y el tamaño en bytes para cada elemento de ese arreglo.
|
||||
<table class='table table-striped'><tr><th> Tipo </th><th> Cada tamaño de elemento en bytes. </th></tr><tr><td> <code>Int8Array</code> </td> <td> 1 </td></tr><tr><td> <code>Uint8Array</code> </td> <td> 1 </td></tr><tr><td> <code>Uint8ClampedArray</code> </td> <td> 1 </td></tr><tr><td> <code>Int16Array</code> </td> <td> 2 </td></tr><tr><td> <code>Uint16Array</code> </td> <td> 2 </td></tr><tr><td> <code>Int32Array</code> </td> <td> 4 </td></tr><tr><td> <code>Uint32Array</code> </td> <td> 4 </td></tr><tr><td> <code>Float32Array</code> </td> <td> 4 </td></tr><tr><td> <code>Float64Array</code> </td> <td> 8 </td></tr></table>
|
||||
Hay dos formas de crear este tipo de arreglos. Una forma es crearlo directamente. A continuación se muestra cómo crear un <code>Int16Array</code> 3 longitudes.
|
||||
<blockquote>var i8 = new Int16Array(3);<br>console.log(i8);<br>// Returns [0, 0, 0]</blockquote>
|
||||
También puede crear un <dfn>búfer</dfn> para asignar la cantidad de datos (en bytes) que desea que ocupe la matriz.
|
||||
<strong>Nota</strong> <br> Para crear matrices escritas utilizando buffers, debe asignar el número de bytes para que sea un múltiplo de los bytes enumerados anteriormente.
|
||||
<blockquote>// Create same Int16Array array differently<br>var byteSize = 6; // Needs to be multiple of 2<br>var buffer = new ArrayBuffer(byteSize);<br>var i8View = new Int16Array(buffer);<br>buffer.byteLength; // Returns 6<br>i8View.byteLength; // Returns 6<br>console.log(i8View); // Returns [0, 0, 0]</blockquote>
|
||||
<dfn>Los buffers</dfn> son objetos de propósito general que solo transportan datos. No puedes acceder a ellos normalmente. Para acceder a ellos, primero debe crear una <dfn>vista</dfn> .
|
||||
<blockquote>i8View[0] = 42;<br>console.log(i8View); // Returns [42, 0, 0]</blockquote>
|
||||
<strong>Nota</strong> <br> Los arreglos escritos no tienen algunos de los métodos que tienen los arreglos tradicionales, como <code>.pop()</code> o <code>.push()</code> . Los arreglos <code>Array.isArray()</code> también fallan en <code>Array.isArray()</code> que verifica si algo es un arreglo. Aunque es más simple, esto puede ser una ventaja para que los motores de JavaScript menos sofisticados los implementen.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
Primero crea un <code>buffer</code> 64 bytes. Luego cree una <code>Int32Array</code> tipo <code>Int32Array</code> con una vista llamada <code>i32View</code> .
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: Su <code>buffer</code> debe tener 64 bytes de tamaño.
|
||||
testString: 'assert(buffer.byteLength === 64, "Your <code>buffer</code> should be 64 bytes large.");'
|
||||
- text: Su vista <code>i32View</code> de su búfer debe tener 64 bytes de tamaño.
|
||||
testString: 'assert(i32View.byteLength === 64, "Your <code>i32View</code> view of your buffer should be 64 bytes large.");'
|
||||
- text: Tu vista <code>i32View</code> de tu búfer debe tener 16 elementos de longitud.
|
||||
testString: 'assert(i32View.length === 16, "Your <code>i32View</code> view of your buffer should be 16 elements long.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
var buffer;
|
||||
var i32View;
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
var buffer = new ArrayBuffer(64);
|
||||
var i32View = new Int32Array(buffer);
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,74 @@
|
||||
---
|
||||
id: 587d8255367417b2b2512c72
|
||||
title: Use .has and .size on an ES6 Set
|
||||
localeTitle: Utilice .has y .size en un conjunto ES6
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Veamos los métodos .has y .size disponibles en el objeto ES6 Set.
|
||||
Primero, cree un conjunto ES6
|
||||
<code>var set = new Set([1,2,3]);</code>
|
||||
El método .has comprobará si el valor está contenido dentro del conjunto.
|
||||
<code>var hasTwo = set.has(2);</code>
|
||||
El método .size devolverá un número entero que representa el tamaño del Set
|
||||
<code>var howBig = set.size;</code>
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
En este ejercicio pasaremos una matriz y un valor a la función checkSet (). Su función debe crear un conjunto ES6 a partir del argumento de la matriz. Encuentra si el conjunto contiene el argumento de valor. Encuentra el tamaño del conjunto. Y devuelve esos dos valores en una matriz.
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: ' <code>checkSet([4, 5, 6], 3)</code> debe devolver [false, 3]'
|
||||
testString: 'assert(function(){var test = checkSet([4,5,6], 3); test === [ false, 3 ]}, "<code>checkSet([4, 5, 6], 3)</code> should return [ false, 3 ]");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function checkSet(arrToBeSet, checkValue){
|
||||
|
||||
// change code below this line
|
||||
|
||||
// change code above this line
|
||||
|
||||
}
|
||||
|
||||
checkSet([ 1, 2, 3], 2); // Should return [ true, 3 ]
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
function checkSet(arrToBeSet, checkValue){
|
||||
var set = new Set(arrToBeSet);
|
||||
var result = [
|
||||
set.has(checkValue),
|
||||
set.size
|
||||
];
|
||||
return result;
|
||||
}
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,83 @@
|
||||
---
|
||||
id: 587d8258367417b2b2512c7f
|
||||
title: Use Breadth First Search in a Binary Search Tree
|
||||
localeTitle: Utilice la búsqueda en primer lugar en un árbol de búsqueda binario
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Aquí vamos a introducir otro método de recorrido de árboles: búsqueda de amplitud en primer lugar. En contraste con los métodos de búsqueda de profundidad primero del último desafío, la búsqueda de amplitud primero explora todos los nodos en un nivel dado dentro de un árbol antes de continuar al siguiente nivel. Normalmente, las colas se utilizan como estructuras de datos auxiliares en el diseño de los algoritmos de búsqueda más avanzados.
|
||||
En este método, comenzamos agregando el nodo raíz a una cola. Luego comenzamos un ciclo en el que sacamos de la cola el primer elemento de la cola, lo agregamos a una nueva matriz y luego inspeccionamos ambos subárboles secundarios. Si sus hijos no son nulos, se ponen en cola. Este proceso continúa hasta que la cola está vacía.
|
||||
Instrucciones: Vamos a crear un primer método de búsqueda en nuestro árbol llamado <code>levelOrder</code> . Este método debe devolver una matriz que contenga los valores de todos los nodos de árbol, explorados de manera integral. Asegúrese de devolver los valores de la matriz, no los nodos en sí. Un nivel debe ser recorrido de izquierda a derecha. A continuación, escribamos un método similar llamado <code>reverseLevelOrder</code> que realiza la misma búsqueda pero en la dirección inversa (de derecha a izquierda) en cada nivel.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: La estructura de datos <code>BinarySearchTree</code> existe.
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() }; return (typeof test == "object")})(), "The <code>BinarySearchTree</code> data structure exists.");'
|
||||
- text: El árbol de búsqueda binario tiene un método llamado <code>levelOrder</code> .
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; return (typeof test.levelOrder == "function")})(), "The binary search tree has a method called <code>levelOrder</code>.");'
|
||||
- text: El árbol de búsqueda binario tiene un método llamado <code>reverseLevelOrder</code> .
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; return (typeof test.reverseLevelOrder == "function")})(), "The binary search tree has a method called <code>reverseLevelOrder</code>.");'
|
||||
- text: El método <code>levelOrder</code> devuelve una matriz de los valores de nodo de árbol explorados en orden de nivel.
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; if (typeof test.levelOrder !== "function") { return false; }; test.add(7); test.add(1); test.add(9); test.add(0); test.add(3); test.add(8); test.add(10); test.add(2); test.add(5); test.add(4); test.add(6); return (test.levelOrder().join("") == "719038102546"); })(), "The <code>levelOrder</code> method returns an array of the tree node values explored in level order.");'
|
||||
- text: El método <code>reverseLevelOrder</code> devuelve una matriz de los valores de nodo de árbol explorados en el orden de nivel inverso.
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; if (typeof test.reverseLevelOrder !== "function") { return false; }; test.add(7); test.add(1); test.add(9); test.add(0); test.add(3); test.add(8); test.add(10); test.add(2); test.add(5); test.add(4); test.add(6); return (test.reverseLevelOrder().join("") == "791108305264"); })(), "The <code>reverseLevelOrder</code> method returns an array of the tree node values explored in reverse level order.");'
|
||||
- text: El método <code>levelOrder</code> devuelve <code>null</code> para un árbol vacío.
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; if (typeof test.levelOrder !== "function") { return false; }; return (test.levelOrder() == null); })(), "The <code>levelOrder</code> method returns <code>null</code> for an empty tree.");'
|
||||
- text: El método <code>reverseLevelOrder</code> devuelve <code>null</code> para un árbol vacío.
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; if (typeof test.reverseLevelOrder !== "function") { return false; }; return (test.reverseLevelOrder() == null); })(), "The <code>reverseLevelOrder</code> method returns <code>null</code> for an empty tree.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
var displayTree = (tree) => console.log(JSON.stringify(tree, null, 2));
|
||||
function Node(value) {
|
||||
this.value = value;
|
||||
this.left = null;
|
||||
this.right = null;
|
||||
}
|
||||
function BinarySearchTree() {
|
||||
this.root = null;
|
||||
// change code below this line
|
||||
// change code above this line
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
console.info('after the test');
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,93 @@
|
||||
---
|
||||
id: 587d8257367417b2b2512c7e
|
||||
title: Use Depth First Search in a Binary Search Tree
|
||||
localeTitle: Utilice la búsqueda en profundidad primero en un árbol de búsqueda binario
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Sabemos cómo buscar un árbol de búsqueda binario para un valor específico. Pero ¿y si solo queremos explorar todo el árbol? ¿O qué sucede si no tenemos un árbol ordenado y solo necesitamos buscar un valor? Aquí introduciremos algunos métodos de recorrido de árboles que se pueden usar para explorar estructuras de datos de árboles. Lo primero es buscar primero en profundidad. En la búsqueda en profundidad, un subárbol determinado se explora lo más profundamente posible antes de que la búsqueda continúe en otro subárbol. Hay tres formas de hacerlo:
|
||||
En orden: comience la búsqueda en el nodo más a la izquierda y finalice en el nodo más a la derecha.
|
||||
Pre-orden: Explorar todas las raíces antes de las hojas.
|
||||
Orden posterior: Explorar todas las hojas antes de las raíces.
|
||||
Como puede suponer, puede elegir diferentes métodos de búsqueda según el tipo de datos que su árbol esté almacenando y lo que está buscando. Para un árbol de búsqueda binario, un recorrido inorder devuelve los nodos en orden ordenado.
|
||||
Instrucciones: Aquí crearemos estos tres métodos de búsqueda en nuestro árbol de búsqueda binario. La búsqueda en profundidad es una operación intrínsecamente recursiva que continúa explorando más subárboles mientras haya nodos secundarios presentes. Una vez que entienda este concepto básico, puede simplemente reorganizar el orden en el que explora los nodos y subárboles para producir cualquiera de las tres búsquedas anteriores. Por ejemplo, en la búsqueda posterior al pedido querríamos repetir todo el camino a un nodo hoja antes de que comencemos a devolver cualquiera de los nodos, mientras que en la búsqueda previa al pedido deseamos devolver primero los nodos y luego continuar recurriendo abajo del arbol
|
||||
Defina los métodos <code>inorder</code> , <code>preorder</code> y <code>postorder</code> en nuestro árbol. Cada uno de estos métodos debe devolver una matriz de elementos que representan el recorrido del árbol. Asegúrese de devolver los valores enteros en cada nodo de la matriz, no los nodos en sí. Finalmente, devuelve <code>null</code> si el árbol está vacío.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: La estructura de datos <code>BinarySearchTree</code> existe.
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() }; return (typeof test == "object")})(), "The <code>BinarySearchTree</code> data structure exists.");'
|
||||
- text: El árbol de búsqueda binario tiene un método llamado <code>inorder</code> .
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; return (typeof test.inorder == "function")})(), "The binary search tree has a method called <code>inorder</code>.");'
|
||||
- text: El árbol de búsqueda binario tiene un método llamado <code>preorder</code> .
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; return (typeof test.preorder == "function")})(), "The binary search tree has a method called <code>preorder</code>.");'
|
||||
- text: El árbol de búsqueda binario tiene un método llamado <code>postorder</code> .
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; return (typeof test.postorder == "function")})(), "The binary search tree has a method called <code>postorder</code>.");'
|
||||
- text: El método <code>inorder</code> devuelve una matriz de los valores de nodo que resultan de un recorrido inorder.
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; if (typeof test.inorder !== "function") { return false; }; test.add(7); test.add(1); test.add(9); test.add(0); test.add(3); test.add(8); test.add(10); test.add(2); test.add(5); test.add(4); test.add(6); return (test.inorder().join("") == "012345678910"); })(), "The <code>inorder</code> method returns an array of the node values that result from an inorder traversal.");'
|
||||
- text: El método de <code>preorder</code> retorna una matriz de los valores de nodo que resultan de un recorrido de preorder.
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; if (typeof test.preorder !== "function") { return false; }; test.add(7); test.add(1); test.add(9); test.add(0); test.add(3); test.add(8); test.add(10); test.add(2); test.add(5); test.add(4); test.add(6); return (test.preorder().join("") == "710325469810"); })(), "The <code>preorder</code> method returns an array of the node values that result from a preorder traversal.");'
|
||||
- text: El método de orden <code>postorder</code> devuelve una matriz de los valores de nodo que resultan de un recorrido de orden posterior.
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; if (typeof test.postorder !== "function") { return false; }; test.add(7); test.add(1); test.add(9); test.add(0); test.add(3); test.add(8); test.add(10); test.add(2); test.add(5); test.add(4); test.add(6); return (test.postorder().join("") == "024653181097"); })(), "The <code>postorder</code> method returns an array of the node values that result from a postorder traversal.");'
|
||||
- text: El método <code>inorder</code> devuelve <code>null</code> para un árbol vacío.
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; if (typeof test.inorder !== "function") { return false; }; return (test.inorder() == null); })(), "The <code>inorder</code> method returns <code>null</code> for an empty tree.");'
|
||||
- text: El método de <code>preorder</code> devuelve <code>null</code> para un árbol vacío.
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; if (typeof test.preorder !== "function") { return false; }; return (test.preorder() == null); })(), "The <code>preorder</code> method returns <code>null</code> for an empty tree.");'
|
||||
- text: El método <code>postorder</code> devuelve <code>null</code> para un árbol vacío.
|
||||
testString: 'assert((function() { var test = false; if (typeof BinarySearchTree !== "undefined") { test = new BinarySearchTree() } else { return false; }; if (typeof test.postorder !== "function") { return false; }; return (test.postorder() == null); })(), "The <code>postorder</code> method returns <code>null</code> for an empty tree.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
var displayTree = (tree) => console.log(JSON.stringify(tree, null, 2));
|
||||
function Node(value) {
|
||||
this.value = value;
|
||||
this.left = null;
|
||||
this.right = null;
|
||||
}
|
||||
function BinarySearchTree() {
|
||||
this.root = null;
|
||||
// change code below this line
|
||||
// change code above this line
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
console.info('after the test');
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,62 @@
|
||||
---
|
||||
id: 587d8255367417b2b2512c73
|
||||
title: Use Spread and Notes for ES5 Set() Integration
|
||||
localeTitle: Use Spread and Notes para la integración de ES5 Set ()
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
¿Recuerdas el operador de propagación ES6 <code>...</code> ?
|
||||
<code>...</code> puede tomar objetos iterables en ES6 y convertirlos en matrices.
|
||||
Vamos a crear un Set, y echa un vistazo a la función de propagación.
|
||||
<blockquote>var set = new Set([1,2,3]);<br>var setToArr = [...set]<br>console.log(setToArr) // returns [ 1, 2, 3 ]</blockquote>
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
En este ejercicio pasaremos un objeto establecido a la función <code>checkSet</code> . Debe devolver una matriz que contenga los valores del conjunto.
|
||||
Ahora ha aprendido con éxito cómo usar el objeto <code>Set()</code> ES6, ¡buen trabajo!
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: ¡Tu Set fue devuelto correctamente!
|
||||
testString: 'assert(function(){var test = checkSet(new Set([1,2,3,4,5,6,7])); test === [ 1, 2, 3, 4, 5, 6, 7 ]}, "Your Set was returned correctly!");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function checkSet(set){
|
||||
// change code below this line
|
||||
|
||||
// change code above this line
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
function checkSet(set){
|
||||
return [...set];}
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,66 @@
|
||||
---
|
||||
id: 587d8251367417b2b2512c61
|
||||
title: Work with Nodes in a Linked List
|
||||
localeTitle: Trabajar con nodos en una lista enlazada
|
||||
challengeType: 1
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Otra estructura de datos común con la que se encontrará en informática es la <dfn>lista enlazada</dfn> . Una lista enlazada es una colección lineal de elementos de datos, llamados 'nodos', cada uno de los cuales apunta al siguiente. Cada <dfn>nodo</dfn> en una lista enlazada contiene dos piezas clave de información: el <code>element</code> sí, y una referencia al siguiente <code>node</code> .
|
||||
Imagina que estás en una línea de conga. Tienes las manos en la siguiente persona en la línea, y la persona detrás de ti tiene las manos sobre ti. Puede ver a la persona directamente delante de usted, pero está bloqueando la vista de las otras personas en la fila. Un nodo es como una persona en una línea de conga: saben quiénes son y solo pueden ver a la siguiente persona en la línea, pero no son conscientes de las otras personas que están delante o detrás.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
En nuestro editor de código, hemos creado dos nodos, <code>Kitten</code> y <code>Puppy</code> , y hemos conectado manualmente el nodo <code>Kitten</code> nodo <code>Puppy</code> .
|
||||
Crea un nodo <code>Cat</code> y <code>Dog</code> y agrégalos manualmente a la línea.
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: Su nodo <code>Puppy</code> debería tener una referencia a un nodo <code>Cat</code> .
|
||||
testString: 'assert(Puppy.next.element === "Cat", "Your <code>Puppy</code> node should have a reference to a <code>Cat</code> node.");'
|
||||
- text: Su nodo <code>Cat</code> debe tener una referencia a un nodo <code>Dog</code> .
|
||||
testString: 'assert(Cat.next.element === "Dog", "Your <code>Cat</code> node should have a reference to a <code>Dog</code> node.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
var Node = function(element){
|
||||
this.element = element;
|
||||
this.next = null;
|
||||
};
|
||||
var Kitten = new Node("Kitten");
|
||||
var Puppy = new Node("Puppy");
|
||||
|
||||
Kitten.next = Puppy;
|
||||
// only add code below this line
|
||||
|
||||
// test your code
|
||||
console.log(Kitten.next);
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,59 @@
|
||||
---
|
||||
id: 5
|
||||
localeTitle: 5900f3e41000cf542c50fef6
|
||||
challengeType: 5
|
||||
title: 'Problem 119: Digit power sum'
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
El número 512 es interesante porque es igual a la suma de sus dígitos elevados a alguna potencia: 5 + 1 + 2 = 8, y 83 = 512. Otro ejemplo de un número con esta propiedad es 614656 = 284.
|
||||
define como el enésimo término de esta secuencia e insiste en que un número debe contener al menos dos dígitos para tener una suma.
|
||||
Te dan que a2 = 512 y a10 = 614656.
|
||||
Encuentra a30.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>euler119()</code> debe devolver 248155780267521.
|
||||
testString: 'assert.strictEqual(euler119(), 248155780267521, "<code>euler119()</code> should return 248155780267521.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function euler119() {
|
||||
// Good luck!
|
||||
return true;
|
||||
}
|
||||
|
||||
euler119();
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,68 @@
|
||||
---
|
||||
id: 5
|
||||
localeTitle: 5900f4231000cf542c50ff35
|
||||
challengeType: 5
|
||||
title: 'Problem 182: RSA encryption'
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
El cifrado RSA se basa en el siguiente procedimiento:
|
||||
Generar dos primos distintos p y q.Compute n = pq y φ = (p-1) (q-1).
|
||||
Encuentra un entero e, 1 <e<φ, such that gcd(e,φ)=1.<code> 0 Un mensaje en este sistema es un número en el intervalo [0, n-1].
|
||||
Un texto que se va a cifrar se convierte de alguna manera en mensajes (números en el intervalo [0, n-1]).
|
||||
Para cifrar el texto, para cada mensaje, m, c = me mod n se calcula.
|
||||
Para descifrar el texto, se necesita el siguiente procedimiento: calcular d tal que ed = 1 mod φ, luego para cada mensaje cifrado, c, calcular m = cd mod n.
|
||||
Existen valores de e y m tales que me mod n = m. Llamamos mensajes m para los cuales me mod n = m mensajes no ocultos.
|
||||
Un problema al elegir e es que no debe haber demasiados mensajes no ocultos. Por ejemplo, vamos a p = 19 y q = 37.
|
||||
Entonces n = 19 * 37 = 703 y φ = 18 * 36 = 648.
|
||||
Si elegimos e = 181, entonces, aunque gcd (181,648) = 1 resulta que todos los mensajes posibles m (0≤m≤n-1) no están ocultos al calcularme mod n.
|
||||
Para cualquier elección válida de e existen algunos mensajes no ocultos.
|
||||
Es importante que el número de mensajes no ocultos sea mínimo.
|
||||
Elige p = 1009 y q = 3643.
|
||||
Encuentra la suma de todos los valores de e, 1 <e<φ(1009,3643) and gcd(e,φ)=1, so that the number of unconcealed messages for this value of e is at a minimum.<code> 0 </section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>euler182()</code> debe devolver 399788195976.
|
||||
testString: 'assert.strictEqual(euler182(), 399788195976, "<code>euler182()</code> should return 399788195976.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function euler182() {
|
||||
// Good luck!
|
||||
return true;
|
||||
}
|
||||
|
||||
euler182();
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,57 @@
|
||||
---
|
||||
id: 5
|
||||
localeTitle: 5900f4651000cf542c50ff77
|
||||
challengeType: 5
|
||||
title: 'Problem 248: Numbers for which Euler’s totient function equals 13!'
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
El primer número n para el cual φ (n) = 13! es 6227180929.
|
||||
Encuentra la 150,000 de dicho número.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>euler248()</code> debe devolver 23507044290.
|
||||
testString: 'assert.strictEqual(euler248(), 23507044290, "<code>euler248()</code> should return 23507044290.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function euler248() {
|
||||
// Good luck!
|
||||
return true;
|
||||
}
|
||||
|
||||
euler248();
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,56 @@
|
||||
---
|
||||
id: 5
|
||||
localeTitle: 5900f4661000cf542c50ff78
|
||||
challengeType: 5
|
||||
title: 'Problem 250: 250250'
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Encuentre el número de subconjuntos no vacíos de {11, 22, 33, ..., 250250250250}, la suma de cuyos elementos es divisible por 250. Ingrese los 16 dígitos más a la derecha como su respuesta.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>euler250()</code> debe devolver 1425480602091519.
|
||||
testString: 'assert.strictEqual(euler250(), 1425480602091519, "<code>euler250()</code> should return 1425480602091519.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function euler250() {
|
||||
// Good luck!
|
||||
return true;
|
||||
}
|
||||
|
||||
euler250();
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,65 @@
|
||||
---
|
||||
id: 5
|
||||
localeTitle: 5900f4711000cf542c50ff84
|
||||
challengeType: 5
|
||||
title: 'Problem 261: Pivotal Square Sums'
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Llamemos a un entero positivo ka cuadrado-pivote, si hay un par de enteros m> 0 y n ≥ k, de modo que la suma de los cuadrados consecutivos (m + 1) hasta k sea igual a la suma de m consecutivos cuadrados de (n + 1) en:
|
||||
|
||||
(km) 2 + ... + k2 = (n + 1) 2 + ... + (n + m) 2.
|
||||
|
||||
Algunos pequeños pivotes cuadrados son
|
||||
4: 32 + 42
|
||||
= 52
|
||||
21: 202 + 212 = 292
|
||||
24: 212 + 222 + 232 + 242 = 252 + 262 + 272
|
||||
110: 1082 + 1092 + 1102 = 1332 + 1342Encuentre la suma de todos los distintos pivotes cuadrados ≤ 1010.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>euler261()</code> debe devolver 238890850232021.
|
||||
testString: 'assert.strictEqual(euler261(), 238890850232021, "<code>euler261()</code> should return 238890850232021.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function euler261() {
|
||||
// Good luck!
|
||||
return true;
|
||||
}
|
||||
|
||||
euler261();
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,81 @@
|
||||
---
|
||||
id: 5
|
||||
localeTitle: 5900f4ab1000cf542c50ffbd
|
||||
challengeType: 5
|
||||
title: 'Problem 318: 2011 nines'
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Considera el número real √2 + √3.
|
||||
Cuando calculamos las potencias pares de √2 + √3
|
||||
obtenemos:
|
||||
(√2 + √3) 2 = 9.898979485566356 ...
|
||||
(√2 + √3) 4 = 97.98979485566356 ...
|
||||
(√2 + √3) 6 = 969.998969071069263 ...
|
||||
(√2 + √3) 8 = 9601.99989585502907 ...
|
||||
(√2 + √3) 10 = 95049.999989479221 ...
|
||||
(√2 + √3) 12 = 940897.9999989371855 .. .
|
||||
(√2 + √3) 14 = 9313929.99999989263 ...
|
||||
(√2 + √3) 16 = 92198401.99999998915 ...
|
||||
|
||||
Parece que el número de nueves consecutivas al principio de la parte fraccionaria de estas potencias No está disminuyendo.
|
||||
De hecho, se puede probar que la parte fraccionaria de (√2 + √3) 2n se acerca a 1 para n grande.
|
||||
|
||||
|
||||
Considere todos los números reales de la forma √p + √q con p y q enteros positivos yp <q, such that the fractional part<code> 0 de (√p + √q) 2n se acerca a 1 para n grande.
|
||||
|
||||
|
||||
Sea C (p, q, n) el número de nueves consecutivas al comienzo de la parte fraccionaria de (√p + √q) 2n.
|
||||
|
||||
|
||||
Sea N (p, q) el valor mínimo de n tal que C (p, q, n) ≥ 2011.
|
||||
|
||||
|
||||
Encuentre ∑N (p, q) para p + q ≤ 2011.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>euler318()</code> debe devolver 709313889.
|
||||
testString: 'assert.strictEqual(euler318(), 709313889, "<code>euler318()</code> should return 709313889.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function euler318() {
|
||||
// Good luck!
|
||||
return true;
|
||||
}
|
||||
|
||||
euler318();
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,92 @@
|
||||
---
|
||||
id: 5
|
||||
localeTitle: 5900f4e51000cf542c50fff7
|
||||
challengeType: 5
|
||||
title: 'Problem 376: Nontransitive sets of dice'
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Considera el siguiente juego de dados con puntos no estándar:
|
||||
|
||||
|
||||
|
||||
Muere A: 1 4 4 4 4 4 4
|
||||
Muere B: 2 2 2 5 5 5
|
||||
Muere C: 3 3 3 3 3 6
|
||||
|
||||
|
||||
Un juego es jugado por dos jugadores que recogen un dado por turnos y lo hacen rodar. El jugador que saca el valor más alto gana.
|
||||
|
||||
|
||||
|
||||
Si el primer jugador elige el dado A y el segundo el jugador muere B, obtenemos
|
||||
P (el segundo jugador gana) = 7/12> 1/2
|
||||
|
||||
|
||||
Si el primer jugador elige el dado B y el segundo jugador elige die C obtenemos
|
||||
P (el segundo jugador gana) = 7/12> 1/2
|
||||
|
||||
|
||||
Si el primer jugador elige die C y el segundo jugador elige die A obtenemos
|
||||
P (el segundo jugador gana) = 25/36> 1/2
|
||||
|
||||
|
||||
Entonces, cualquiera que sea el dado que elija el primer jugador, el segundo jugador puede elegir otro dado y tener una probabilidad de ganar de más del 50%.
|
||||
Un conjunto de dados que tiene esta propiedad se llama un conjunto de dados no transitivos.
|
||||
|
||||
|
||||
|
||||
Queremos investigar cuántos conjuntos de dados no transitivos existen. Asumiremos las siguientes condiciones: Hay tres dados de seis caras con cada lado que tiene entre 1 y N pips, inclusive.
|
||||
dados con el mismo conjunto de puntos son iguales, independientemente del lado en el que se encuentren los puntos.
|
||||
El mismo valor de pip puede aparecer en múltiples dados; si ambos jugadores lanzan el mismo valor, ninguno de los dos gana.
|
||||
Los conjuntos de dados {A, B, C}, {B, C, A} y {C, A, B} son el mismo conjunto.
|
||||
|
||||
Para N = 7 encontramos que hay 9780 tales conjuntos.
|
||||
¿Cuántos hay para N = 30?
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>euler376()</code> debe devolver 973059630185670.
|
||||
testString: 'assert.strictEqual(euler376(), 973059630185670, "<code>euler376()</code> should return 973059630185670.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function euler376() {
|
||||
// Good luck!
|
||||
return true;
|
||||
}
|
||||
|
||||
euler376();
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,67 @@
|
||||
---
|
||||
id: 5
|
||||
localeTitle: 5900f4ea1000cf542c50fffc
|
||||
challengeType: 5
|
||||
title: 'Problem 381: (prime-k) factorial'
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Para un primo p, deje que S (p) = (∑ (pk)!) Mod (p) para 1 ≤ k ≤ 5.
|
||||
|
||||
|
||||
Por ejemplo, si p = 7,
|
||||
(7-1)! + (7-2)! + (7-3)! + (7-4)! + (7-5)! = 6! + 5! + 4! + 3! + 2! = 720 + 120 + 24 + 6 + 2 = 872.
|
||||
Como 872 mod (7) = 4, S (7) = 4.
|
||||
|
||||
|
||||
Se puede verificar que ∑S (p) = 480 para 5 ≤ p < 100.
|
||||
|
||||
|
||||
Encuentra ∑S (p) para 5 ≤ p <108.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>euler381()</code> debe devolver 139602943319822.
|
||||
testString: 'assert.strictEqual(euler381(), 139602943319822, "<code>euler381()</code> should return 139602943319822.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function euler381() {
|
||||
// Good luck!
|
||||
return true;
|
||||
}
|
||||
|
||||
euler381();
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,79 @@
|
||||
---
|
||||
id: 5
|
||||
localeTitle: 5900f3941000cf542c50fea7
|
||||
challengeType: 5
|
||||
title: 'Problem 40: Champernowne"s constant'
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Una fracción decimal irracional se crea mediante la concatenación de los números enteros positivos:
|
||||
<span style='display: block; text-align: center;'>,12345678910 <b style='color: red;'>1</b> 112131415161718192021 ...</span>
|
||||
Se puede observar que el 12 <sup>de</sup> dígitos de la parte fraccionaria es de 1.
|
||||
Si <i>d <sub>n</sub></i> representa el <i><sup>enésimo</sup></i> dígitos de la parte fraccionaria , encuentra el valor de la siguiente expresión.
|
||||
<span style='display: block; text-align: center;'>d <sub>1</sub> × d <sub>10</sub> × d <sub>100</sub> × d <sub>1000</sub> × d <sub>10000</sub> × d <sub>100000</sub> × d <sub>1000000</sub></span>
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>champernownesConstant(100)</code> debe devolver 5.
|
||||
testString: 'assert.strictEqual(champernownesConstant(100), 5, "<code>champernownesConstant(100)</code> should return 5.");'
|
||||
- text: <code>champernownesConstant(1000)</code> debe devolver 15.
|
||||
testString: 'assert.strictEqual(champernownesConstant(1000), 15, "<code>champernownesConstant(1000)</code> should return 15.");'
|
||||
- text: <code>champernownesConstant(1000000)</code> debe devolver 210.
|
||||
testString: 'assert.strictEqual(champernownesConstant(1000000), 210, "<code>champernownesConstant(1000000)</code> should return 210.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function champernownesConstant(n) {
|
||||
// Good luck!
|
||||
return true;
|
||||
}
|
||||
|
||||
champernownesConstant(100);
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
function champernownesConstant(n) {
|
||||
let fractionalPart = ";
|
||||
for (let i = 0; fractionalPart.length <= n; i++) {
|
||||
fractionalPart += i.toString();
|
||||
}
|
||||
|
||||
let product = 1;
|
||||
for (let i = 0; i < n.toString().length; i++) {
|
||||
const index = 10 ** i;
|
||||
product *= parseInt(fractionalPart[index], 10);
|
||||
}
|
||||
|
||||
return product;
|
||||
}
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,79 @@
|
||||
---
|
||||
id: 5
|
||||
localeTitle: 5900f5021000cf542c510015
|
||||
challengeType: 5
|
||||
title: 'Problem 406: Guessing Game'
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Estamos tratando de encontrar un número oculto seleccionado del conjunto de enteros {1, 2, ..., n} haciendo preguntas.
|
||||
Cada número (pregunta) que hacemos, obtenemos una de tres respuestas posibles: "Su estimación es menor que el número oculto" (y usted incurre en un costo de a), o
|
||||
"Su estimación es mayor que el número oculto" ( e incurres en un costo de b), o
|
||||
"¡Sí, eso es todo!" (Y el juego termina).
|
||||
Dado el valor de n, a y b, una estrategia óptima minimiza el costo total para el peor de los casos.
|
||||
|
||||
Por ejemplo, si n = 5, a = 2 yb = 3, entonces podemos comenzar preguntando "2" como nuestra primera pregunta.
|
||||
|
||||
Si nos dicen que 2 es más alto que el número oculto (por un costo de b = 3), estamos seguros de que "1" es el número oculto (por un costo total de 3).
|
||||
Si nos dicen que 2 es más bajo que el número oculto (por un costo de a = 2), nuestra siguiente pregunta será "4".
|
||||
Si nos dicen que 4 es mayor que el número oculto (para un costo de b = 3), estamos seguros de que "3" es el número oculto (para un costo total de 2 + 3 = 5).
|
||||
Si nos dicen que 4 es menor que el número oculto (por un costo de a = 2), estamos seguros de que "5" es el número oculto (por un costo total de 2 + 2 = 4).
|
||||
Por lo tanto, el costo en el peor de los casos alcanzado por esta estrategia es 5. También se puede demostrar que este es el costo más bajo en el peor de los casos que se puede lograr.
|
||||
Entonces, de hecho, acabamos de describir una estrategia óptima para los valores dados de n, a y b.
|
||||
|
||||
Sea C (n, a, b) el costo más desfavorable alcanzado por una estrategia óptima para los valores dados de n, a y b.
|
||||
|
||||
Aquí hay algunos ejemplos:
|
||||
C (5, 2, 3) = 5
|
||||
C (500, √2, √3) = 13.22073197 ...
|
||||
C (20000, 5, 7) = 82
|
||||
C (2000000 , √5, √7) = 49.63755955 ...
|
||||
|
||||
Sean Fk los números de Fibonacci: Fk = Fk-1 + Fk-2 con casos base F1 = F2 = 1.Find ∑1≤k≤30 C (1012, √k, √Fk), y dé su respuesta redondeada a 8 lugares decimales detrás del punto decimal.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>euler406()</code> debe devolver 36813.12757207.
|
||||
testString: 'assert.strictEqual(euler406(), 36813.12757207, "<code>euler406()</code> should return 36813.12757207.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function euler406() {
|
||||
// Good luck!
|
||||
return true;
|
||||
}
|
||||
|
||||
euler406();
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,59 @@
|
||||
---
|
||||
id: 5
|
||||
localeTitle: 5900f3b31000cf542c50fec6
|
||||
challengeType: 5
|
||||
title: 'Problem 71: Ordered fractions'
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Considera la fracción, n / d, donde n y d son enteros positivos. Si n <d and HCF(n,d)=1, it is called a reduced proper fraction.<code> 0 Si enumeramos el conjunto de fracciones adecuadas reducidas para d ≤ 8 en orden ascendente de tamaño, obtenemos:
|
||||
1/8, 1/7, 1/6, 1/5, 1/4, 2/7, 1 / 3, 3/8, 2/5, 3/7, 1/2, 4/7, 3/5, 5/8, 2/3, 5/7, 3/4, 4/5, 5/6, 6/7, 7/8
|
||||
Se puede ver que 2/5 es la fracción inmediatamente a la izquierda de 3/7.
|
||||
Al enumerar el conjunto de fracciones apropiadas reducidas para d ≤ 1,000,000 en orden ascendente de tamaño, encuentre el numerador de la fracción inmediatamente a la izquierda de 3/7.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>euler71()</code> debe devolver 428570.
|
||||
testString: 'assert.strictEqual(euler71(), 428570, "<code>euler71()</code> should return 428570.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function euler71() {
|
||||
// Good luck!
|
||||
return true;
|
||||
}
|
||||
|
||||
euler71();
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@@ -0,0 +1,79 @@
|
||||
---
|
||||
title: 100 doors
|
||||
id: 594810f028c0303b75339acb
|
||||
localeTitle: 594810f028c0303b75339acb
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
<p> Hay 100 puertas seguidas que están inicialmente cerradas. Haces 100 pases por las puertas. La primera vez, visite todas las puertas y "active" la puerta (si la puerta está cerrada, ábrala; si está abierta, ciérrela). La segunda vez, solo visite cada segunda puerta (es decir, la puerta # 2, # 4, # 6, ...) y actívela. La tercera vez, visite cada tercera puerta (es decir, la puerta # 3, # 6, # 9, ...), etc., hasta que solo visite la puerta número 100. </p>
|
||||
<p> Implementar una función para determinar el estado de las puertas después de la última pasada. Devuelva el resultado final en una matriz, con solo el número de puerta incluido en la matriz si está abierta. </p>
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>getFinalOpenedDoors</code> es una función.
|
||||
testString: 'assert(typeof getFinalOpenedDoors === "function", "<code>getFinalOpenedDoors</code> is a function.");'
|
||||
- text: <code>getFinalOpenedDoors</code> debe devolver una matriz.
|
||||
testString: 'assert(Array.isArray(getFinalOpenedDoors(100)), "<code>getFinalOpenedDoors</code> should return an array.");'
|
||||
- text: <code>getFinalOpenedDoors</code> no produjo los resultados correctos.
|
||||
testString: 'assert.deepEqual(getFinalOpenedDoors(100), solution, "<code>getFinalOpenedDoors</code> did not produce the correct results.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function getFinalOpenedDoors (numDoors) {
|
||||
// Good luck!
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
console.info('after the test');
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
function getFinalOpenedDoors (numDoors) {
|
||||
// this is the final pattern (always squares).
|
||||
// thus, the most efficient solution simply returns an array of squares up to numDoors).
|
||||
const finalState = [];
|
||||
let i = 1;
|
||||
while (Math.pow(i, 2) <= numDoors) {
|
||||
finalState.push(Math.pow(i, 2));
|
||||
i++;
|
||||
}
|
||||
return finalState;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,156 @@
|
||||
---
|
||||
title: 24 game
|
||||
id: 5951e88f64ebf159166a1176
|
||||
localeTitle: 5951e88f64ebf159166a1176
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
<p> Implemente una función que tome una cadena de cuatro dígitos como su argumento, con cada dígito de 1 ──► 9 (inclusive) con repeticiones permitidas, y devuelva una expresión aritmética que se evalúe al número 24. Si no existe tal solución, devuelva " no existe ninguna solución ". </p>
|
||||
<p> Reglas: </p>
|
||||
Solo se permiten los siguientes operadores / funciones: multiplicación, división, suma, resta
|
||||
división debe usar coma flotante o aritmética racional, etc., para preservar los residuos.
|
||||
se permite formar números de varios dígitos a partir de los dígitos suministrados. (Entonces, una respuesta de 12 + 12 cuando se da 1, 2, 2 y 1 es incorrecta).
|
||||
El orden de los dígitos cuando se dan no tiene que ser preservado.
|
||||
<p> Entradas de ejemplo: </p>
|
||||
<code>solve24("4878");</code>
|
||||
<code>solve24("1234");</code>
|
||||
<code>solve24("6789");</code>
|
||||
<code>solve24("1127");</code>
|
||||
<p> Ejemplos de salidas (cadenas): </p>
|
||||
<code>(7-8/8)*4</code>
|
||||
<code>3*1*4*2</code>
|
||||
<code>(6*8)/(9-7)</code>
|
||||
<code>(1+7)*(2+1)</code>
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>solve24</code> es una función
|
||||
testString: 'assert(typeof solve24 === "function", "<code>solve24</code> is a function.");'
|
||||
- text: <code>solve24("4878")</code> debe devolver <code>(7-8/8)*4</code> o <code>4*(7-8/8)</code>
|
||||
testString: 'assert(include(answers[0], solve24(testCases[0])), "<code>solve24("4878")</code> should return <code>(7-8/8)*4</code> or <code>4*(7-8/8)</code>");'
|
||||
- text: <code>solve24("1234")</code> debe devolver cualquier arreglo de <code>1*2*3*4</code>
|
||||
testString: 'assert(include(answers[1], solve24(testCases[1])), "<code>solve24("1234")</code> should return any arrangement of <code>1*2*3*4</code>");'
|
||||
- text: <code>solve24("6789")</code> debe devolver <code>(6*8)/(9-7)</code> o <code>(8*6)/(9-7)</code>
|
||||
testString: 'assert(include(answers[2], solve24(testCases[2])), "<code>solve24("6789")</code> should return <code>(6*8)/(9-7)</code> or <code>(8*6)/(9-7)</code>");'
|
||||
- text: <code>solve24("1127")</code> debe devolver una permutación de <code>(1+7)*(1*2)</code>
|
||||
testString: 'assert(include(answers[3], solve24(testCases[3])), "<code>solve24("1127")</code> should return a permutation of <code>(1+7)*(1*2)</code>");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function solve24 (numStr) {
|
||||
// Good luck!
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
console.info('after the test');
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
// noprotect
|
||||
|
||||
function solve24 (numStr) {
|
||||
const digitsArr = numStr.split('');
|
||||
const answers = [];
|
||||
|
||||
const digitPermutations = [];
|
||||
const operatorPermutations = [];
|
||||
|
||||
function generateDigitPermutations (digits, permutations = []) {
|
||||
if (digits.length === 0) {
|
||||
digitPermutations.push(permutations);
|
||||
}
|
||||
else {
|
||||
for (let i = 0; i < digits.length; i++) {
|
||||
const curr = digits.slice();
|
||||
const next = curr.splice(i, 1);
|
||||
generateDigitPermutations(curr.slice(), permutations.concat(next));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function generateOperatorPermutations (permutations = []) {
|
||||
const operators = ['+', '-', '*', '/'];
|
||||
if (permutations.length === 3) {
|
||||
operatorPermutations.push(permutations);
|
||||
}
|
||||
else {
|
||||
for (let i = 0; i < operators.length; i++) {
|
||||
const curr = permutations.slice();
|
||||
curr.push(operators[i]);
|
||||
generateOperatorPermutations(curr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
generateDigitPermutations(digitsArr);
|
||||
generateOperatorPermutations();
|
||||
|
||||
interleave();
|
||||
|
||||
return answers[0];
|
||||
|
||||
function interleave () {
|
||||
for (let i = 0; i < digitPermutations.length; i++) {
|
||||
for (let j = 0; j < operatorPermutations.length; j++) {
|
||||
const d = digitPermutations[i];
|
||||
const o = operatorPermutations[j];
|
||||
const perm = [
|
||||
`${d[0]}${o[0]}${d[1]}${o[1]}${d[2]}${o[2]}${d[3]}`,
|
||||
`(${d[0]}${o[0]}${d[1]})${o[1]}${d[2]}${o[2]}${d[3]}`,
|
||||
`${d[0]}${o[0]}(${d[1]}${o[1]}${d[2]})${o[2]}${d[3]}`,
|
||||
`${d[0]}${o[0]}${d[1]}${o[1]}(${d[2]}${o[2]}${d[3]})`,
|
||||
`${d[0]}${o[0]}(${d[1]}${o[1]}${d[2]}${o[2]}${d[3]})`,
|
||||
`(${d[0]}${o[0]}${d[1]}${o[1]}${d[2]})${o[2]}${d[3]}`,
|
||||
`(${d[0]}${o[0]}${d[1]})${o[1]}(${d[2]}${o[2]}${d[3]})`
|
||||
];
|
||||
|
||||
perm.forEach(combination => {
|
||||
const res = eval(combination);
|
||||
|
||||
if (res === 24) {
|
||||
return answers.push(combination);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,103 @@
|
||||
---
|
||||
title: 9 billion names of God the integer
|
||||
id: 5949b579404977fbaefcd736
|
||||
localeTitle: 5949b579404977fbaefcd736
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
<p> Esta tarea es una variación de la <a href="https://en.wikipedia.org/wiki/The Nine Billion Names of God#Plot_summary" title="wp: Los nueve mil millones de nombres de Dios # Plot_summary">historia corta de Arthur C. Clarke</a> . </p>
|
||||
<p> (Los solucionadores deben ser conscientes de las consecuencias de completar esta tarea). </p>
|
||||
<p> En detalle, para especificar qué se entiende por un "nombre": </p>
|
||||
<p> El entero 1 tiene 1 nombre "1". </p>
|
||||
<p> El número entero 2 tiene 2 nombres "1 + 1" y "2". </p>
|
||||
<p> El número entero 3 tiene 3 nombres "1 + 1 + 1", "2 + 1" y "3". </p>
|
||||
<p> El número entero 4 tiene 5 nombres “1 + 1 + 1 + 1”, “2 + 1 + 1”, “2 + 2”, “3 + 1”, “4”. </p>
|
||||
<p> El número entero 5 tiene 7 nombres “1 + 1 + 1 + 1 + 1”, “2 + 1 + 1 + 1”, “2 + 2 + 1”, “3 + 1 + 1”, “3 + 2”, “4 + 1”, “5”. </p>
|
||||
<p> Esto se puede visualizar de la siguiente forma: </p>
|
||||
<pre>
|
||||
1
|
||||
1 1
|
||||
1 1 1
|
||||
1 2 1 1
|
||||
1 2 2 1 1
|
||||
1 3 3 2 1 1
|
||||
</pre>
|
||||
<p> Donde la fila $ n $ corresponde al entero $ n $, y cada columna $ C $ en la fila $ m $ de izquierda a derecha corresponde al número de nombres que comienzan con $ C $. </p>
|
||||
<p> Opcionalmente, tenga en cuenta que la suma de $ n $ -th row $ P (n) $ es la <a href="http://mathworld.wolfram.com/PartitionFunctionP.html" title="enlace: http://mathworld.wolfram.com/PartitionFunctionP.html">función de partición entera</a> . </p>
|
||||
Tarea
|
||||
<p> Implementar una función que devuelve la suma de la fila $ n $ -th. </p>
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>numberOfNames</code> es una función.
|
||||
testString: 'assert(typeof numberOfNames === "function", "<code>numberOfNames</code> is a function.");'
|
||||
- text: <code>numberOfNames(5)</code> debe ser igual a 7.
|
||||
testString: 'assert.equal(numberOfNames(5), 7, "<code>numberOfNames(5)</code> should equal 7.");'
|
||||
- text: <code>numberOfNames(12)</code> debe ser igual a 77.
|
||||
testString: 'assert.equal(numberOfNames(12), 77, "<code>numberOfNames(12)</code> should equal 77.");'
|
||||
- text: <code>numberOfNames(18)</code> debe ser igual a 385.
|
||||
testString: 'assert.equal(numberOfNames(18), 385, "<code>numberOfNames(18)</code> should equal 385.");'
|
||||
- text: <code>numberOfNames(23)</code> debe ser igual a 1255.
|
||||
testString: 'assert.equal(numberOfNames(23), 1255, "<code>numberOfNames(23)</code> should equal 1255.");'
|
||||
- text: <code>numberOfNames(42)</code> debe ser igual a 53174.
|
||||
testString: 'assert.equal(numberOfNames(42), 53174, "<code>numberOfNames(42)</code> should equal 53174.");'
|
||||
- text: <code>numberOfNames(123)</code> debe ser igual a 2552338241.
|
||||
testString: 'assert.equal(numberOfNames(123), 2552338241, "<code>numberOfNames(123)</code> should equal 2552338241.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function numberOfNames (num) {
|
||||
// Good luck!
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
function numberOfNames (num) {
|
||||
const cache = [
|
||||
[1]
|
||||
];
|
||||
for (let l = cache.length; l < num + 1; l++) {
|
||||
let Aa;
|
||||
let Mi;
|
||||
const r = [0];
|
||||
for (let x = 1; x < l + 1; x++) {
|
||||
r.push(r[r.length - 1] + (Aa = cache[l - x < 0 ? cache.length - (l - x) : l - x])[(Mi = Math.min(x, l - x)) < 0 ? Aa.length - Mi : Mi]);
|
||||
}
|
||||
cache.push(r);
|
||||
}
|
||||
return cache[num][cache[num].length - 1];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,122 @@
|
||||
---
|
||||
title: ABC Problem
|
||||
id: 594810f028c0303b75339acc
|
||||
localeTitle: 594810f028c0303b75339acc
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
<p> Se le entrega una colección de bloques ABC (por ejemplo, bloques del alfabeto infantil). Hay 20 bloques con dos letras en cada bloque. Un alfabeto completo está garantizado entre todos los lados de los bloques. La colección de muestras de bloques: </p>
|
||||
<p> (BO) </p>
|
||||
<p> (XK) </p>
|
||||
<p> (DQ) </p>
|
||||
<p> (CP) </p>
|
||||
<p> (N / A) </p>
|
||||
<p> (GT) </p>
|
||||
<p> (RE) </p>
|
||||
<p> (TG) </p>
|
||||
<p> (QD) </p>
|
||||
<p> (FS) </p>
|
||||
<p> (JW) </p>
|
||||
<p> (HU) </p>
|
||||
<p> (VI) </p>
|
||||
<p> (UN) </p>
|
||||
<p> (TRANSMISIÓN EXTERIOR) </p>
|
||||
<p> (ER) </p>
|
||||
<p> (FS) </p>
|
||||
<p> (LY) </p>
|
||||
<p> (ORDENADOR PERSONAL) </p>
|
||||
<p> (ZM) </p>
|
||||
<p> Algunas reglas a tener en cuenta: </p>
|
||||
Una vez que se usa una letra en un bloque, ese bloque no se puede usar de nuevo.
|
||||
La función debe ser insensible a mayúsculas y minúsculas.
|
||||
<p> Implementar una función que toma una cadena (palabra) y determina si la palabra se puede deletrear con la colección de bloques dada. </p>
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>canMakeWord</code> es una función.
|
||||
testString: 'assert(typeof canMakeWord === "function", "<code>canMakeWord</code> is a function.");'
|
||||
- text: <code>canMakeWord</code> debería devolver un booleano.
|
||||
testString: 'assert(typeof canMakeWord("hi") === "boolean", "<code>canMakeWord</code> should return a boolean.");'
|
||||
- text: <code>canMakeWord("bark")</code> debe devolver verdadero.
|
||||
testString: 'assert(canMakeWord(words[0]), "<code>canMakeWord("bark")</code> should return true.");'
|
||||
- text: <code>canMakeWord("BooK")</code> debe devolver falso.
|
||||
testString: 'assert(!canMakeWord(words[1]), "<code>canMakeWord("BooK")</code> should return false.");'
|
||||
- text: <code>canMakeWord("TReAT")</code> debe devolver verdadero.
|
||||
testString: 'assert(canMakeWord(words[2]), "<code>canMakeWord("TReAT")</code> should return true.");'
|
||||
- text: <code>canMakeWord("COMMON")</code> debe devolver falso.
|
||||
testString: 'assert(!canMakeWord(words[3]), "<code>canMakeWord("COMMON")</code> should return false.");'
|
||||
- text: <code>canMakeWord("squAD")</code> debe devolver true.
|
||||
testString: 'assert(canMakeWord(words[4]), "<code>canMakeWord("squAD")</code> should return true.");'
|
||||
- text: <code>canMakeWord("conFUSE")</code> debe devolver verdadero.
|
||||
testString: 'assert(canMakeWord(words[5]), "<code>canMakeWord("conFUSE")</code> should return true.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function canMakeWord (word) {
|
||||
// Good luck!
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
console.info('after the test');
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
function canMakeWord (word) {
|
||||
const characters = 'BO XK DQ CP NA GT RE TG QD FS JW HU VI AN OB ER FS LY PC ZM';
|
||||
const blocks = characters.split(' ').map(pair => pair.split(''));
|
||||
|
||||
const letters = [...word.toUpperCase()];
|
||||
let length = letters.length;
|
||||
const copy = new Set(blocks);
|
||||
|
||||
letters.forEach(letter => {
|
||||
for (let block of copy) {
|
||||
const index = block.indexOf(letter);
|
||||
|
||||
if (index !== -1) {
|
||||
length--;
|
||||
copy.delete(block);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
return !length;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,94 @@
|
||||
---
|
||||
title: 'Abundant, deficient and perfect number classifications'
|
||||
id: 594810f028c0303b75339acd
|
||||
localeTitle: 594810f028c0303b75339acd
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
<p> Estos definen tres clasificaciones de enteros positivos basados en sus <a href="http://rosettacode.org/wiki/Proper divisors" title="Divisores adecuados">divisores apropiados</a> . </p>
|
||||
<p> Sea $ P (n) $ la suma de los divisores apropiados de n, donde los divisores apropiados son todos enteros positivos n distintos de n en sí. </p>
|
||||
<p> Si <code>P(n) < n</code> entonces n se clasifica como "deficiente" </p>
|
||||
<p> Si <code>P(n) === n</code> , n se clasifica como "perfecto" </p>
|
||||
<p> Si <code>P(n) > n</code> entonces n se clasifica como "abundante" </p>
|
||||
<p> Ejemplo: </p>
|
||||
<p> 6 tiene divisores propios de 1, 2 y 3. </p>
|
||||
<p> 1 + 2 + 3 = 6, entonces 6 se clasifica como un número perfecto. </p>
|
||||
<p> Implemente una función que calcula cuántos de los enteros de 1 a 20,000 (inclusive) están en cada una de las tres clases. Muestra el resultado como una matriz en el siguiente formato <code>[deficient, perfect, abundant]</code> . </p>
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>getDPA</code> es una función.
|
||||
testString: 'assert(typeof getDPA === "function", "<code>getDPA</code> is a function.");'
|
||||
- text: <code>getDPA</code> debería devolver una matriz.
|
||||
testString: 'assert(Array.isArray(getDPA(100)), "<code>getDPA</code> should return an array.");'
|
||||
- text: <code>getDPA</code> valor de retorno de <code>getDPA</code> debe tener una longitud de 3.
|
||||
testString: 'assert(getDPA(100).length === 3, "<code>getDPA</code> return value should have a length of 3.");'
|
||||
- text: ' <code>getDPA(20000)</code> debe ser igual a [15043, 4, 4953]'
|
||||
testString: 'assert.deepEqual(getDPA(20000), solution, "<code>getDPA(20000)</code> should equal [15043, 4, 4953]");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function getDPA (num) {
|
||||
// Good luck!
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
console.info('after the test');
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
function getDPA (num) {
|
||||
const dpa = [1, 0, 0];
|
||||
for (let n = 2; n <= num; n += 1) {
|
||||
let ds = 1;
|
||||
const e = Math.sqrt(n);
|
||||
for (let d = 2; d < e; d += 1) {
|
||||
if (n % d === 0) {
|
||||
ds += d + (n / d);
|
||||
}
|
||||
}
|
||||
if (n % e === 0) {
|
||||
ds += e;
|
||||
}
|
||||
dpa[ds < n ? 0 : ds === n ? 1 : 2] += 1;
|
||||
}
|
||||
return dpa;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,78 @@
|
||||
---
|
||||
title: Accumulator factory
|
||||
id: 594810f028c0303b75339ace
|
||||
localeTitle: 594810f028c0303b75339ace
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
<p> Cree una función que tome un solo argumento (numérico) y devuelva otra función que sea un acumulador. La función del acumulador devuelto a su vez también toma un solo argumento numérico y devuelve la suma de todos los valores numéricos pasados hasta ese acumulador (incluido el valor inicial pasado cuando se creó el acumulador). </p>
|
||||
<p> Reglas: </p>
|
||||
<p> No utilice variables globales. </p>
|
||||
<p> Insinuación: </p>
|
||||
<p> Los cierres salvan el estado exterior. </p>
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>accumulator</code> es una función.
|
||||
testString: 'assert(typeof accumulator === "function", "<code>accumulator</code> is a function.");'
|
||||
- text: <code>accumulator(0)</code> debe devolver una función.
|
||||
testString: 'assert(typeof accumulator(0) === "function", "<code>accumulator(0)</code> should return a function.");'
|
||||
- text: <code>accumulator(0)(2)</code> debe devolver un número.
|
||||
testString: 'assert(typeof accumulator(0)(2) === "number", "<code>accumulator(0)(2)</code> should return a number.");'
|
||||
- text: 'Pasar los valores 3, -4, 1.5 y 5 debería devolver 5.5.'
|
||||
testString: 'assert(testFn(5) === 5.5, "Passing in the values 3, -4, 1.5, and 5 should return 5.5.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function accumulator (sum) {
|
||||
// Good luck!
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
console.info('after the test');
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
function accumulator (sum) {
|
||||
return function (n) {
|
||||
return sum += n;
|
||||
};
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,74 @@
|
||||
---
|
||||
title: Ackermann function
|
||||
id: 594810f028c0303b75339acf
|
||||
localeTitle: 594810f028c0303b75339acf
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
<p> La función de Ackermann es un ejemplo clásico de una función recursiva, especialmente porque no es una función recursiva primitiva. Crece muy rápidamente en valor, al igual que el tamaño de su árbol de llamadas. </p>
|
||||
<p> La función de Ackermann se define generalmente de la siguiente manera: </p>
|
||||
$ A (m, n) =
|
||||
\ begin {cases}
|
||||
n + 1 & \ mbox {if} m = 0 \\
|
||||
A (m-1, 1) & \ mbox {if} m> 0 \ mbox {y} n = 0 \\
|
||||
A (m-1, A (m, n-1)) & \ mbox {if} m> 0 \ mbox {y} n> 0.
|
||||
\ end {cases} $ $
|
||||
<p> Sus argumentos nunca son negativos y siempre termina. Escriba una función que devuelva el valor de $ A (m, n) $. Se prefiere la precisión arbitraria (ya que la función crece tan rápidamente), pero no es obligatoria. </p>
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>ack</code> es una función.
|
||||
testString: 'assert(typeof ack === "function", "<code>ack</code> is a function.");'
|
||||
- text: ' <code>ack(0, 0)</code> debe devolver 1.'
|
||||
testString: 'assert(ack(0, 0) === 1, "<code>ack(0, 0)</code> should return 1.");'
|
||||
- text: ' <code>ack(1, 1)</code> debe devolver 3.'
|
||||
testString: 'assert(ack(1, 1) === 3, "<code>ack(1, 1)</code> should return 3.");'
|
||||
- text: ' <code>ack(2, 5)</code> debe devolver 13.'
|
||||
testString: 'assert(ack(2, 5) === 13, "<code>ack(2, 5)</code> should return 13.");'
|
||||
- text: ' <code>ack(3, 3)</code> debe devolver 61.'
|
||||
testString: 'assert(ack(3, 3) === 61, "<code>ack(3, 3)</code> should return 61.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function ack (m, n) {
|
||||
// Good luck!
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
function ack (m, n) {
|
||||
return m === 0 ? n + 1 : ack(m - 1, n === 0 ? 1 : ack(m, n - 1));
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,153 @@
|
||||
---
|
||||
title: Align columns
|
||||
id: 594810f028c0303b75339ad0
|
||||
localeTitle: 594810f028c0303b75339ad0
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
<p> Dado un archivo de texto de muchas líneas, donde los campos dentro de una línea están delineados por un solo carácter de <code>$</code> , escriba un programa que alinee cada columna de campos asegurándose de que las palabras en cada columna estén separadas por al menos un espacio. Además, permita que cada palabra en una columna se justifique a la izquierda, a la derecha o al centro dentro de su columna. </p>
|
||||
<p> Usa el siguiente texto para probar tus programas: </p>
|
||||
<pre>
|
||||
Dado $ a $ texto $ archivo $ de $ muchas $ líneas
|
||||
donde $ campos $ dentro de $ a $ línea $
|
||||
son $ delineados $ por $ a $ simple $ 'dólar' $ carácter
|
||||
escribe $ a $ programa
|
||||
ese $ alinea $ cada $ columna $ de $ campos
|
||||
por $ asegurando $ que $ palabras $ en $ cada $
|
||||
columna $ están $ separados $ por $ en $ al menos $ un $ espacio.
|
||||
Además, $ permita $ por $ cada $ palabra $ en $ a $ columna $ a $ sea $ o bien $ dejó $
|
||||
justificado, $ derecho $ justificó
|
||||
o $ centro $ justificado dentro de $ su $ columna.
|
||||
</pre>
|
||||
<p> Tenga en cuenta que: </p>
|
||||
Las líneas de texto de entrada de ejemplo pueden, o no, tener caracteres de dólar al final.
|
||||
Todas las columnas deben compartir la misma alineación.
|
||||
Los caracteres de espacio consecutivo producidos adyacentes al final de las líneas son insignificantes para los propósitos de la tarea.
|
||||
El texto de salida se verá en una fuente mono-espaciada en un editor de texto plano o terminal básico.
|
||||
El espacio mínimo entre columnas debe calcularse a partir del texto y no estar codificado.
|
||||
No es un requisito agregar caracteres de separación entre o alrededor de las columnas.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>formatText</code> es una función.
|
||||
testString: 'assert(typeof formatText === "function", "<code>formatText</code> is a function.");'
|
||||
- text: ' <code>formatText</code> con la entrada anterior y la justificación "correcta" debe producir lo siguiente:'
|
||||
testString: 'assert.strictEqual(formatText(testInput, "right"), rightAligned, "<code>formatText</code> with the above input and "right" justification should produce the following: ");'
|
||||
- text: ' <code>formatText</code> con la entrada anterior y la justificación "izquierda" debe producir lo siguiente:'
|
||||
testString: 'assert.strictEqual(formatText(testInput, "left"), leftAligned, "<code>formatText</code> with the above input and "left" justification should produce the following: ");'
|
||||
- text: ' <code>formatText</code> con la entrada anterior y la justificación "central" debe producir lo siguiente:'
|
||||
testString: 'assert.strictEqual(formatText(testInput, "center"), centerAligned, "<code>formatText</code> with the above input and "center" justification should produce the following: ");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
const testArr = [
|
||||
'Given$a$text$file$of$many$lines',
|
||||
'where$fields$within$a$line$',
|
||||
'are$delineated$by$a$single$"dollar"$character',
|
||||
'write$a$program',
|
||||
'that$aligns$each$column$of$fields$',
|
||||
'by$ensuring$that$words$in$each$',
|
||||
'column$are$separated$by$at$least$one$space.',
|
||||
'Further,$allow$for$each$word$in$a$column$to$be$either$left$',
|
||||
'justified,$right$justified',
|
||||
'or$center$justified$within$its$column.'
|
||||
];
|
||||
|
||||
function formatText (input, justification) {
|
||||
// Good luck!
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
console.info('after the test');
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
const testArr = [
|
||||
'Given$a$text$file$of$many$lines',
|
||||
'where$fields$within$a$line$',
|
||||
'are$delineated$by$a$single$"dollar"$character',
|
||||
'write$a$program',
|
||||
'that$aligns$each$column$of$fields$',
|
||||
'by$ensuring$that$words$in$each$',
|
||||
'column$are$separated$by$at$least$one$space.',
|
||||
'Further,$allow$for$each$word$in$a$column$to$be$either$left$',
|
||||
'justified,$right$justified',
|
||||
'or$center$justified$within$its$column.'
|
||||
];
|
||||
|
||||
String.prototype.repeat = function (n) { return new Array(1 + parseInt(n)).join(this); };
|
||||
|
||||
function formatText (input, justification) {
|
||||
let x, y, max, cols = 0, diff, left, right;
|
||||
for (x = 0; x < input.length; x++) {
|
||||
input[x] = input[x].split('$');
|
||||
if (input[x].length > cols) {
|
||||
cols = input[x].length;
|
||||
}
|
||||
}
|
||||
for (x = 0; x < cols; x++) {
|
||||
max = 0;
|
||||
for (y = 0; y < input.length; y++) {
|
||||
if (input[y][x] && max < input[y][x].length) {
|
||||
max = input[y][x].length;
|
||||
}
|
||||
}
|
||||
for (y = 0; y < input.length; y++) {
|
||||
if (input[y][x]) {
|
||||
diff = (max - input[y][x].length) / 2;
|
||||
left = ' '.repeat(Math.floor(diff));
|
||||
right = ' '.repeat(Math.ceil(diff));
|
||||
if (justification === 'left') {
|
||||
right += left; left = ";
|
||||
}
|
||||
if (justification === 'right') {
|
||||
left += right; right = ";
|
||||
}
|
||||
input[y][x] = left + input[y][x] + right;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (x = 0; x < input.length; x++) {
|
||||
input[x] = input[x].join(' ');
|
||||
}
|
||||
input = input.join('\n');
|
||||
return input;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,119 @@
|
||||
---
|
||||
title: Amicable pairs
|
||||
id: 5949b579404977fbaefcd737
|
||||
localeTitle: 5949b579404977fbaefcd737
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Se dice que dos enteros $ N $ y $ M $ son <a href="https://en.wikipedia.org/wiki/Amicable numbers" title="wp: números amistosos">pares amigables</a> si $ N \ neq M $ y la suma de los <a href="http://rosettacode.org/wiki/Proper divisors" title="Divisores adecuados">divisores apropiados</a> de $ N $ ($ \ mathrm {suma} (\ mathrm {propDivs} (N) ) $) $ = M $ así como $ \ mathrm {suma} (\ mathrm {propDivs} (M)) = N $.
|
||||
Ejemplo:
|
||||
1184 y 1210 son un par amigable, con divisores apropiados:
|
||||
1, 2, 4, 8, 16, 32, 37, 74, 148, 296, 592 y
|
||||
1, 2, 5, 10, 11, 22, 55, 110, 121, 242, 605 respectivamente.
|
||||
Tarea:
|
||||
Calcula y muestra aquí los pares de amigos por debajo de 20,000 (hay ocho).
|
||||
Tareas relacionadas
|
||||
<a href="http://rosettacode.org/wiki/Proper divisors" title="Divisores adecuados">Divisores apropiados</a>
|
||||
<a href="http://rosettacode.org/wiki/Abundant, deficient and perfect number classifications" title="Numerosas, deficientes y perfectas clasificaciones numéricas.">Clasificaciones numéricas abundantes, deficientes y perfectas</a>
|
||||
<a href="http://rosettacode.org/wiki/Aliquot sequence classifications" title="Clasificaciones de secuencias alícuotas">Clasificaciones de secuencias de alícuotas</a> y su clasificación amistosa.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>amicablePairsUpTo</code> es una función.
|
||||
testString: 'assert(typeof amicablePairsUpTo === "function", "<code>amicablePairsUpTo</code> is a function.");'
|
||||
- text: ' <code>amicablePairsUpTo(300)</code> debe devolver <code>[[220,284]]</code> .'
|
||||
testString: 'assert.deepEqual(amicablePairsUpTo(300), answer300, "<code>amicablePairsUpTo(300)</code> should return <code>[[220,284]]</code>.");'
|
||||
- text: ' <code>amicablePairsUpTo(3000)</code> debe devolver <code>[[220,284],[1184,1210],[2620,2924]]</code> .'
|
||||
testString: 'assert.deepEqual(amicablePairsUpTo(3000), answer3000, "<code>amicablePairsUpTo(3000)</code> should return <code>[[220,284],[1184,1210],[2620,2924]]</code>.");'
|
||||
- text: ' <code>amicablePairsUpTo(20000)</code> debe devolver <code>[[220,284],[1184,1210],[2620,2924],[5020,5564],[6232,6368],[10744,10856],[12285,14595],[17296,18416]]</code> . '
|
||||
testString: 'assert.deepEqual(amicablePairsUpTo(20000), answer20000, "<code>amicablePairsUpTo(20000)</code> should return <code>[[220,284],[1184,1210],[2620,2924],[5020,5564],[6232,6368],[10744,10856],[12285,14595],[17296,18416]]</code>.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function amicablePairsUpTo (maxNum) {
|
||||
// Good luck!
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
console.info('after the test');
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
// amicablePairsUpTo :: Int -> [(Int, Int)]
|
||||
function amicablePairsUpTo (maxNum) {
|
||||
return range(1, maxNum)
|
||||
.map(x => properDivisors(x)
|
||||
.reduce((a, b) => a + b, 0))
|
||||
.reduce((a, m, i, lst) => {
|
||||
const n = i + 1;
|
||||
|
||||
return (m > n) && lst[m - 1] === n ?
|
||||
a.concat([
|
||||
[n, m]
|
||||
]) : a;
|
||||
}, []);
|
||||
}
|
||||
|
||||
// properDivisors :: Int -> [Int]
|
||||
function properDivisors (n) {
|
||||
if (n < 2) return [];
|
||||
|
||||
const rRoot = Math.sqrt(n);
|
||||
const intRoot = Math.floor(rRoot);
|
||||
const blnPerfectSquare = rRoot === intRoot;
|
||||
const lows = range(1, intRoot)
|
||||
.filter(x => (n % x) === 0);
|
||||
|
||||
return lows.concat(lows.slice(1)
|
||||
.map(x => n / x)
|
||||
.reverse()
|
||||
.slice(blnPerfectSquare | 0));
|
||||
}
|
||||
|
||||
// Int -> Int -> Maybe Int -> [Int]
|
||||
function range (m, n, step) {
|
||||
const d = (step || 1) * (n >= m ? 1 : -1);
|
||||
|
||||
return Array.from({
|
||||
length: Math.floor((n - m) / d) + 1
|
||||
}, (_, i) => m + (i * d));
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,89 @@
|
||||
---
|
||||
title: Averages-Mode
|
||||
id: 594d8d0ab97724821379b1e6
|
||||
localeTitle: 594d8d0ab97724821379b1e6
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
<p> Escribe un programa para encontrar el valor de <a href="https://en.wikipedia.org/wiki/Mode (statistics)" title="wp: modo (estadísticas)">modo</a> de una colección. </p><p> El caso donde la colección está vacía puede ser ignorado. Se debe tener cuidado para manejar el caso donde el modo no es único. </p><p> Si no es apropiado o no es posible admitir una colección general, use un vector (matriz), si es posible. Si no es apropiado o no es posible admitir un tipo de valor no especificado, use números enteros. </p>
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>mode</code> es una función.
|
||||
testString: 'assert(typeof mode === "function", "<code>mode</code> is a function.");'
|
||||
- text: ' <code>mode([1, 3, 6, 6, 6, 6, 7, 7, 12, 12, 17])</code> debe ser igual a <code>[6]</code> '
|
||||
testString: 'assert.deepEqual(mode(arr1), [6], "<code>mode([1, 3, 6, 6, 6, 6, 7, 7, 12, 12, 17])</code> should equal <code>[6]</code>");'
|
||||
- text: 'el <code>mode([1, 2, 4, 4, 1])</code> debe ser igual a <code>[1, 4]</code> .'
|
||||
testString: 'assert.deepEqual(mode(arr2).sort(), [1, 4], "<code>mode([1, 2, 4, 4, 1])</code> should equal <code>[1, 4]</code>.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function mode (arr) {
|
||||
// Good luck!
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
console.info('after the test');
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
function mode(arr) {
|
||||
const counter = {};
|
||||
let result = [];
|
||||
let max = 0;
|
||||
// for (const i in arr) {
|
||||
arr.forEach(el => {
|
||||
if (!(el in counter)) {
|
||||
counter[el] = 0;
|
||||
}
|
||||
counter[el]++;
|
||||
|
||||
if (counter[el] === max) {
|
||||
result.push(el);
|
||||
}
|
||||
else if (counter[el] > max) {
|
||||
max = counter[el];
|
||||
result = [el];
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,139 @@
|
||||
---
|
||||
title: Averages-Pythagorean means
|
||||
id: 594d966a1467eb84194f0086
|
||||
localeTitle: 594d966a1467eb84194f0086
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
<p class='rosetta__paragraph'> Calcule los tres <a class='rosetta__link--wiki' href='https://en.wikipedia.org/wiki/Pythagorean means' title="wp: medios pitagóricos">medios pitagóricos</a> del conjunto de enteros del <big>1</big> al <big>10</big> (inclusive). </p><p class='rosetta__paragraph'> Muestre que <big>$ A (x_1, \ ldots, x_n) \ geq G (x_1, \ ldots, x_n) \ geq H (x_1, \ ldots, x_n) $</big> para este conjunto de enteros positivos. </p> El más común de los tres medios, la <a class='rosetta__link--rosetta' href='http://rosettacode.org/wiki/Averages/Arithmetic mean' title="Medias / media aritmética">media aritmética</a> , es la suma de la lista dividida por su longitud: <big>$ A (x_1, \ ldots, x_n) = \ frac {x_1 + \ cdots + x_n} {n} $</big> La <a class='rosetta__link--wiki' href='https://en.wikipedia.org/wiki/Geometric mean' title="wp: media geométrica">geometría media</a> es la raíz $ n $ th del producto de la lista: <big>$ G (x_1, \ ldots, x_n) = \ sqrt [n] {x_1 \ cdots x_n} $</big> La <a class='rosetta__link--wiki' href='https://en.wikipedia.org/wiki/Harmonic mean' title="wp: media armónica">media armónica</a> es $ n $ dividida por la suma de el recíproco de cada elemento en la lista: <big>$ H (x_1, \ ldots, x_n) = \ frac {n} {\ frac {1} {x_1} + \ cdots + \ frac {1} {x_n}} $</big>
|
||||
<p class='rosetta__paragraph'> Suponga que la entrada es una matriz ordenada de todos los números inclusivos. </p>
|
||||
<p class='rosetta__paragraph'> Para la respuesta, envíe un objeto en el siguiente formato: </p>
|
||||
<pre class='rosetta__pre'>
|
||||
{
|
||||
valores: {
|
||||
Aritmética: 5.5,
|
||||
Geométrica: 4.528728688116765,
|
||||
Armónica: 3.414171521474055
|
||||
},
|
||||
prueba: 'es A> = G> = H? si '
|
||||
}
|
||||
</pre>
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>pythagoreanMeans</code> es una función.
|
||||
testString: 'assert(typeof pythagoreanMeans === "function", "<code>pythagoreanMeans</code> is a function.");'
|
||||
- text: ' <code>pythagoreanMeans([1, 2, ..., 10])</code> debe ser igual a la salida anterior.'
|
||||
testString: 'assert.deepEqual(pythagoreanMeans(range1), answer1, "<code>pythagoreanMeans([1, 2, ..., 10])</code> should equal the same output above.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function pythagoreanMeans (rangeArr) {
|
||||
// Good luck!
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
console.info('after the test');
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
function pythagoreanMeans (rangeArr) {
|
||||
// arithmeticMean :: [Number] -> Number
|
||||
const arithmeticMean = xs =>
|
||||
foldl((sum, n) => sum + n, 0, xs) / length(xs);
|
||||
|
||||
// geometricMean :: [Number] -> Number
|
||||
const geometricMean = xs =>
|
||||
raise(foldl((product, x) => product * x, 1, xs), 1 / length(xs));
|
||||
|
||||
// harmonicMean :: [Number] -> Number
|
||||
const harmonicMean = xs =>
|
||||
length(xs) / foldl((invSum, n) => invSum + (1 / n), 0, xs);
|
||||
|
||||
// GENERIC FUNCTIONS ------------------------------------------------------
|
||||
|
||||
// A list of functions applied to a list of arguments
|
||||
// <*> :: [(a -> b)] -> [a] -> [b]
|
||||
const ap = (fs, xs) => //
|
||||
Array.prototype.concat(...fs.map(f => //
|
||||
Array.prototype.concat(...xs.map(x => [f(x)]))));
|
||||
|
||||
// foldl :: (b -> a -> b) -> b -> [a] -> b
|
||||
const foldl = (f, a, xs) => xs.reduce(f, a);
|
||||
|
||||
// length :: [a] -> Int
|
||||
const length = xs => xs.length;
|
||||
|
||||
// mapFromList :: [(k, v)] -> Dictionary
|
||||
const mapFromList = kvs =>
|
||||
foldl((a, [k, v]) =>
|
||||
(a[(typeof k === 'string' && k)] = v, a), {}, kvs);
|
||||
|
||||
// raise :: Num -> Int -> Num
|
||||
const raise = (n, e) => Math.pow(n, e);
|
||||
/*
|
||||
// show :: a -> String
|
||||
// show :: a -> Int -> String
|
||||
const show = (...x) =>
|
||||
JSON.stringify.apply(
|
||||
null, x.length > 1 ? [x[0], null, x[1]] : x
|
||||
);
|
||||
*/
|
||||
// zip :: [a] -> [b] -> [(a,b)]
|
||||
const zip = (xs, ys) =>
|
||||
xs.slice(0, Math.min(xs.length, ys.length))
|
||||
.map((x, i) => [x, ys[i]]);
|
||||
|
||||
// TEST -------------------------------------------------------------------
|
||||
// mean :: Dictionary
|
||||
const mean = mapFromList(zip(
|
||||
['Arithmetic', 'Geometric', 'Harmonic'],
|
||||
ap([arithmeticMean, geometricMean, harmonicMean], [
|
||||
rangeArr
|
||||
])
|
||||
));
|
||||
|
||||
return {
|
||||
values: mean,
|
||||
test: `is A >= G >= H ? ${mean.Arithmetic >= mean.Geometric &&
|
||||
mean.Geometric >= mean.Harmonic ? 'yes' : 'no'}`
|
||||
};
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,71 @@
|
||||
---
|
||||
title: Averages-Root mean square
|
||||
id: 594da033de4190850b893874
|
||||
localeTitle: 594da033de4190850b893874
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
<p> Calcule el <a href="https://en.wikipedia.org/wiki/Root mean square" title="wp: cuadrado de la raíz">cuadrado</a> de la <a href="https://en.wikipedia.org/wiki/Root mean square" title="wp: cuadrado de la raíz">raíz</a> de los números del 1 al 10, ambos inclusive. </p>
|
||||
<p> La raíz cuadrada media también se conoce por sus iniciales RMS (o rms) y como la media cuadrática. </p><p> El RMS se calcula como la media de los cuadrados de los números, con raíz cuadrada: </p>
|
||||
<p> <big>$ x _ {\ mathrm {rms}} = \ sqrt {{{x_1} ^ 2 + {x_2} ^ 2 + \ cdots + {x_n} ^ 2} \ over n}. $</big> </p>
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>rms</code> es una función.
|
||||
testString: 'assert(typeof rms === "function", "<code>rms</code> is a function.");'
|
||||
- text: ' <code>rms([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])</code> debe ser igual a <code>6.2048368229954285</code> .'
|
||||
testString: 'assert.equal(rms(arr1), answer1, "<code>rms([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])</code> should equal <code>6.2048368229954285</code>.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function rms (arr) {
|
||||
// Good luck!
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
console.info('after the test');
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
function rms (arr) {
|
||||
const sumOfSquares = arr.reduce((s, x) => s + x * x, 0);
|
||||
return Math.sqrt(sumOfSquares / arr.length);
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,87 @@
|
||||
---
|
||||
title: Babbage problem
|
||||
id: 594db4d0dedb4c06a2a4cefd
|
||||
localeTitle: 594db4d0dedb4c06a2a4cefd
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
<p> <a href="https://en.wikipedia.org/wiki/Charles_Babbage" title="wp: Charles_Babbage">Charles Babbage</a> , mirando el tipo de problemas que su motor analítico podría resolver, dio este ejemplo: </p>
|
||||
<blockquote> What is the smallest positive integer whose square ends in the digits 269,696?</blockquote>
|
||||
<p> - Babbage, carta a Lord Bowden, 1837; ver Hollingdale y Tootill, <i>Electronic Computers</i> , segunda edición, 1970, pág. 125. </p>
|
||||
<p> Pensó que la respuesta podría ser 99,736, cuyo cuadrado es 9,947,269,696; pero no podía estar seguro. </p>
|
||||
<p> La tarea es averiguar si Babbage tuvo la respuesta correcta. </p>
|
||||
<p> Implemente una función para devolver el entero más bajo que satisfaga el problema de Babbage. Si Babbage tenía razón, devuelve el número de Babbage. </p>
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>babbage</code> es una función.
|
||||
testString: 'assert(typeof babbage === "function", "<code>babbage</code> is a function.");'
|
||||
- text: ' <code>babbage(99736, 269696)</code> no debe devolver 99736 (hay una respuesta más pequeña).'
|
||||
testString: 'assert.equal(babbage(babbageAns, endDigits), answer, "<code>babbage(99736, 269696)</code> should not return 99736 (there is a smaller answer).");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function babbage (babbageNum, endDigits) {
|
||||
// Good luck!
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
console.info('after the test');
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
function babbage (babbageAns, endDigits) {
|
||||
const babbageNum = Math.pow(babbageAns, 2);
|
||||
const babbageStartDigits = parseInt(babbageNum.toString().replace('269696', "));
|
||||
let answer = 99736;
|
||||
|
||||
// count down from this answer and save any sqrt int result. return lowest one
|
||||
for (let i = babbageStartDigits; i >= 0; i--) {
|
||||
const num = parseInt(i.toString().concat('269696'));
|
||||
const result = Math.sqrt(num);
|
||||
if (result === Math.floor(Math.sqrt(num))) {
|
||||
answer = result;
|
||||
}
|
||||
}
|
||||
|
||||
return answer;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,118 @@
|
||||
---
|
||||
title: Balanced brackets
|
||||
id: 594dc6c729e5700999302b45
|
||||
localeTitle: 594dc6c729e5700999302b45
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
<p> Determine si una cadena generada de corchetes está equilibrada; es decir, si consiste completamente en pares de paréntesis de apertura / cierre (en ese orden), ninguno de los cuales se equivoca. </p>
|
||||
Ejemplos:
|
||||
<p class='rosetta__paragraph'> (vacío) verdadero </p>
|
||||
<p class='rosetta__paragraph'> <code>[]</code> verdadero </p>
|
||||
<p class='rosetta__paragraph'> <code>][</code> falso </p>
|
||||
<p class='rosetta__paragraph'> <code>[][]</code> verdadero </p>
|
||||
<p class='rosetta__paragraph'> <code>][][</code> falso </p>
|
||||
<p class='rosetta__paragraph'> <code>[]][[]</code> falso </p>
|
||||
<p class='rosetta__paragraph'> <code>[[[[]]]]</code> verdadero </p>
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>isBalanced</code> es una función.
|
||||
testString: 'assert(typeof isBalanced === "function", "<code>isBalanced</code> is a function.");'
|
||||
- text: ' <code>isBalanced("[]")</code> debe devolver verdadero.'
|
||||
testString: 'assert(isBalanced(testCases[0]), "<code>isBalanced("[]")</code> should return true.");'
|
||||
- text: ' <code>isBalanced("]][[[][][][]][")</code> debe devolver falso.'
|
||||
testString: 'assert(!isBalanced(testCases[1]), "<code>isBalanced("]][[[][][][]][")</code> should return false.");'
|
||||
- text: ' <code>isBalanced("[][[[[][][[[]]]]]]")</code> debe devolver verdadero).
|
||||
testString: 'assert(isBalanced(testCases[2]), "<code>isBalanced("[][[[[][][[[]]]]]]")</code> should return true.");'
|
||||
- text: ' <code>isBalanced("][")</code> debe devolver verdadero.'
|
||||
testString: 'assert(!isBalanced(testCases[3]), "<code>isBalanced("][")</code> should return true.");'
|
||||
- text: ' <code>isBalanced("[[[]]]][[]")</code> debe devolver verdadero.'
|
||||
testString: 'assert(!isBalanced(testCases[4]), "<code>isBalanced("[[[]]]][[]")</code> should return true.");'
|
||||
- text: ' <code>isBalanced("][[]")</code> debe devolver verdadero.'
|
||||
testString: 'assert(!isBalanced(testCases[5]), "<code>isBalanced("][[]")</code> should return true.");'
|
||||
- text: ' <code>isBalanced("][[][]][[[]]")</code> debe devolver verdadero.'
|
||||
testString: 'assert(!isBalanced(testCases[6]), "<code>isBalanced("][[][]][[[]]")</code> should return true.");'
|
||||
- text: ' <code>isBalanced("[[][]]][")</code> debe devolver verdadero.'
|
||||
testString: 'assert(!isBalanced(testCases[7]), "<code>isBalanced("[[][]]][")</code> should return true.");'
|
||||
- text: ' <code>isBalanced("[[[]]][[]]]][][[")</code> debería devolver true.'
|
||||
testString: 'assert(!isBalanced(testCases[8]), "<code>isBalanced("[[[]]][[]]]][][[")</code> should return true.");'
|
||||
- text: ' <code>isBalanced("[]][[]]][[[[][]]")</code> debe devolver verdadero.'
|
||||
testString: 'assert(!isBalanced(testCases[9]), "<code>isBalanced("[]][[]]][[[[][]]")</code> should return true.");'
|
||||
- text: ' <code>isBalanced("][]][[][")</code> debe devolver verdadero.'
|
||||
testString: 'assert(!isBalanced(testCases[10]), "<code>isBalanced("][]][[][")</code> should return true.");'
|
||||
- text: ' <code>isBalanced("[[]][[][]]")</code> debe devolver verdadero.'
|
||||
testString: 'assert(isBalanced(testCases[11]), "<code>isBalanced("[[]][[][]]")</code> should return true.");'
|
||||
- text: ' <code>isBalanced("[[]]")</code> debe devolver verdadero.'
|
||||
testString: 'assert(isBalanced(testCases[12]), "<code>isBalanced("[[]]")</code> should return true.");'
|
||||
- text: ' <code>isBalanced("]][]][[]][[[")</code> debe devolver verdadero ".
|
||||
testString: 'assert(!isBalanced(testCases[13]), "<code>isBalanced("]][]][[]][[[")</code> should return true.");'
|
||||
- text: ' <code>isBalanced("][]][][[")</code> debería devolver verdadero.'
|
||||
testString: 'assert(!isBalanced(testCases[14]), "<code>isBalanced("][]][][[")</code> should return true.");'
|
||||
- text: ' <code>isBalanced("][][")</code> debe devolver verdadero.'
|
||||
testString: 'assert(!isBalanced(testCases[15]), "<code>isBalanced("][][")</code> should return true.");'
|
||||
- text: ' <code>isBalanced("[[]]][][][[]][")</code> debe devolver verdadero.'
|
||||
testString: 'assert(!isBalanced(testCases[16]), "<code>isBalanced("[[]]][][][[]][")</code> should return true.");'
|
||||
- text: <code>isBalanced("")</code> debe devolver true.
|
||||
testString: 'assert(isBalanced(testCases[17]), "<code>isBalanced("")</code> should return true.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function isBalanced (str) {
|
||||
// Good luck!
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
console.info('after the test');
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
function isBalanced (str) {
|
||||
if (str === ") return true;
|
||||
let a = str;
|
||||
let b;
|
||||
do {
|
||||
b = a;
|
||||
a = a.replace(/\[\]/g, ");
|
||||
} while (a !== b);
|
||||
return !a;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,130 @@
|
||||
---
|
||||
title: Circles of given radius through two points
|
||||
id: 5951815dd895584b06884620
|
||||
localeTitle: 5951815dd895584b06884620
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
<p> Dados dos puntos en un plano y un radio, generalmente se pueden dibujar dos círculos de un radio dado a través de los puntos. </p>
|
||||
Excepciones:
|
||||
Un radio de cero debe tratarse como si nunca describiera círculos (excepto en el caso de que los puntos coincidan).
|
||||
Si los puntos son coincidentes, se puede dibujar un número infinito de círculos con el punto en su circunferencia, a menos que el radio también sea igual a cero, lo que luego colapsa los círculos en un punto.
|
||||
Si los puntos forman un diámetro, devuelva un solo círculo.
|
||||
Si los puntos están demasiado separados, no se pueden dibujar círculos. Tarea:
|
||||
Implemente una función que tome dos puntos y un radio y devuelva los dos círculos a través de esos puntos. Para cada círculo resultante, proporcione las coordenadas para el centro de cada círculo redondeado a cuatro dígitos decimales. Devuelve cada coordenada como una matriz y las coordenadas como una matriz de matrices.
|
||||
Para casos de borde, devuelva lo siguiente:
|
||||
Si los puntos están en el diámetro, devuelva un punto. Sin embargo, si el radio también es cero, devuelve <code>"Radius Zero"</code> .
|
||||
Si los puntos coinciden, devuelva <code>"Coincident point. Infinite solutions"</code> .
|
||||
Si los puntos están más separados que el diámetro, regrese <code>"No intersection. Points further apart than circle diameter"</code> .
|
||||
Entradas de muestra:
|
||||
<pre>
|
||||
p1 p2 r
|
||||
0.1234, 0.9876 0.8765, 0.2345 2.0
|
||||
0.0000, 2.0000 0.0000, 0.0000 1.0
|
||||
0.1234, 0.9876 0.1234, 0.9876 2.0
|
||||
0.1234, 0.9876 0.8765, 0.2345 0.5
|
||||
0.1234, 0.9876 0.1234, 0.9876 0.0
|
||||
</pre>
|
||||
Ref:
|
||||
<a href="http://mathforum.org/library/drmath/view/53027.html" title="enlace: http://mathforum.org/library/drmath/view/53027.html">Encontrar el centro de un círculo a partir de 2 puntos y el radio</a> en el foro de Matemáticas @ Drexel
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>getCircles</code> es una función.
|
||||
testString: 'assert(typeof getCircles === "function", "<code>getCircles</code> is a function.");'
|
||||
- text: ' <code>getCircles([0.1234, 0.9876], [0.8765, 0.2345], 2.0)</code> debe devolver <code>[[1.8631, 1.9742], [-0.8632, -0.7521]]</code> .'
|
||||
testString: 'assert.deepEqual(getCircles(...testCases[0]), answers[0], "<code>getCircles([0.1234, 0.9876], [0.8765, 0.2345], 2.0)</code> should return <code>[[1.8631, 1.9742], [-0.8632, -0.7521]]</code>.");'
|
||||
- text: ' <code>getCircles([0.0000, 2.0000], [0.0000, 0.0000], 1.0)</code> debe devolver <code>[0, 1]</code> '
|
||||
testString: 'assert.deepEqual(getCircles(...testCases[1]), answers[1], "<code>getCircles([0.0000, 2.0000], [0.0000, 0.0000], 1.0)</code> should return <code>[0, 1]</code>");'
|
||||
- text: ' <code>getCircles([0.1234, 0.9876], [0.1234, 0.9876], 2.0)</code> debe devolver el <code>Coincident point. Infinite solutions</code> '
|
||||
testString: 'assert.deepEqual(getCircles(...testCases[2]), answers[2], "<code>getCircles([0.1234, 0.9876], [0.1234, 0.9876], 2.0)</code> should return <code>Coincident point. Infinite solutions</code>");'
|
||||
- text: ' <code>getCircles([0.1234, 0.9876], [0.8765, 0.2345], 0.5)</code> debe devolver <code>No intersection. Points further apart than circle diameter</code> '
|
||||
testString: 'assert.deepEqual(getCircles(...testCases[3]), answers[3], "<code>getCircles([0.1234, 0.9876], [0.8765, 0.2345], 0.5)</code> should return <code>No intersection. Points further apart than circle diameter</code>");'
|
||||
- text: ' <code>getCircles([0.1234, 0.9876], [0.1234, 0.9876], 0.0)</code> debe devolver <code>Radius Zero</code> '
|
||||
testString: 'assert.deepEqual(getCircles(...testCases[4]), answers[4], "<code>getCircles([0.1234, 0.9876], [0.1234, 0.9876], 0.0)</code> should return <code>Radius Zero</code>");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function getCircles (...args) {
|
||||
// Good luck!
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
console.info('after the test');
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
const hDist = (p1, p2) => Math.hypot(...p1.map((e, i) => e - p2[i])) / 2;
|
||||
const pAng = (p1, p2) => Math.atan(p1.map((e, i) => e - p2[i]).reduce((p, c) => c / p, 1));
|
||||
const solveF = (p, r) => t => [parseFloat((r * Math.cos(t) + p[0]).toFixed(4)), parseFloat((r * Math.sin(t) + p[1]).toFixed(4))];
|
||||
const diamPoints = (p1, p2) => p1.map((e, i) => parseFloat((e + (p2[i] - e) / 2).toFixed(4)));
|
||||
|
||||
function getCircles (...args) {
|
||||
const [p1, p2, s] = args;
|
||||
const solve = solveF(p1, s);
|
||||
const halfDist = hDist(p1, p2);
|
||||
|
||||
let msg = [];
|
||||
switch (Math.sign(s - halfDist)) {
|
||||
case 0:
|
||||
msg = s ? diamPoints(p1, p2) :
|
||||
'Radius Zero';
|
||||
break;
|
||||
case 1:
|
||||
if (!halfDist) {
|
||||
msg = 'Coincident point. Infinite solutions';
|
||||
}
|
||||
else {
|
||||
const theta = pAng(p1, p2);
|
||||
const theta2 = Math.acos(halfDist / s);
|
||||
[1, -1].map(e => solve(theta + e * theta2)).forEach(
|
||||
e => msg.push(e));
|
||||
}
|
||||
break;
|
||||
case -1:
|
||||
msg = 'No intersection. Points further apart than circle diameter';
|
||||
break;
|
||||
default:
|
||||
msg = 'Reached the default';
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,258 @@
|
||||
---
|
||||
title: Closest-pair problem
|
||||
id: 5951a53863c8a34f02bf1bdc
|
||||
localeTitle: 5951a53863c8a34f02bf1bdc
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Tarea:
|
||||
<p> Proporcione una función para encontrar los dos puntos más cercanos entre un conjunto de puntos dados en dos dimensiones, es decir, para resolver el problema del <a href="https://en.wikipedia.org/wiki/Closest pair of points problem" title="wp: problema de par de puntos más cercano">par de puntos más cercano</a> en el caso plano. </p><p> La solución directa es un algoritmo O (n <sup>2</sup> ) (que podemos llamar algoritmo de fuerza bruta); El pseudocódigo (utilizando índices) podría ser simplemente: </p>
|
||||
<pre>
|
||||
bruteForceClosestPair de P (1), P (2), ... P (N)
|
||||
si N <2 entonces
|
||||
retorno ∞
|
||||
otro
|
||||
minDistance ← | P (1) - P (2) |
|
||||
minPuntos ← {P (1), P (2)}
|
||||
foreach i ∈ [1, N-1]
|
||||
foreach j ∈ [i + 1, N]
|
||||
si | P (i) - P (j) | <minDistance luego
|
||||
minDistance ← | P (i) - P (j) |
|
||||
minPuntos ← {P (i), P (j)}
|
||||
endif
|
||||
endfor
|
||||
endfor
|
||||
return minDistance, minPoints
|
||||
endif
|
||||
</pre>
|
||||
<p> Un mejor algoritmo se basa en el enfoque recursivo de divide y vencerás, como se explica también en <a href="https://en.wikipedia.org/wiki/Closest pair of points problem#Planar_case" title="wp: problema de par de puntos más cercano # Planar_case">el problema del par de puntos más cercanos de Wikipedia</a> , que es O (n log n); Un pseudocódigo podría ser: </p>
|
||||
<pre>
|
||||
par más cercano de (xP, yP)
|
||||
donde xP es P (1) .. P (N) ordenada por la coordenada x, y
|
||||
yP es P (1) .. P (N) ordenada por la coordenada y (orden ascendente)
|
||||
si N ≤ 3 entonces
|
||||
devuelve los puntos más cercanos de xP utilizando el algoritmo de fuerza bruta
|
||||
más
|
||||
xL ← puntos de xP de 1 a ⌈N / 2⌉
|
||||
xR ← puntos de xP de ⌈N / 2⌉ + 1 a N
|
||||
xm ← xP (⌈N / 2⌉) <sub>x</sub>
|
||||
yL ← {p ∈ yP: p <sub>x</sub> ≤ xm}
|
||||
yR ← {p ∈ yP: p <sub>x</sub> > xm}
|
||||
(dL, pairL) ← closestPar de (xL, yL)
|
||||
(dR, pairR) ← par más cercano de (xR, yR)
|
||||
(dmin, pairMin) ← (dR, pairR)
|
||||
si dL <dR luego
|
||||
(dmin, pairMin) ← (dL, pairL)
|
||||
endif
|
||||
yS ← { p ∈ yP: | xm - p <sub>x</sub> | <dmin}
|
||||
nS ← número de puntos en yS
|
||||
(la par más cercana, más cercana) ← (dmin, pairMin)
|
||||
para i de 1 a nS - 1
|
||||
k ← i + 1
|
||||
mientras k ≤ nS e yS (k) <sub>y</sub> - yS (i) <sub>y</sub> <dmin
|
||||
si | yS (k) - yS (i) | <más cercano entonces
|
||||
(más cercano, más cercano) ← (| yS (k) - yS (i) |, {yS (k), yS (i)})
|
||||
endif
|
||||
k ← k + 1
|
||||
endwhile
|
||||
endfor
|
||||
return más cercano más cercano par
|
||||
endif
|
||||
</pre>
|
||||
Referencias y otras lecturas:
|
||||
<a href="https://en.wikipedia.org/wiki/Closest pair of points problem" title="wp: problema de par de puntos más cercano">Par de puntos</a> <a href="http://www.cs.mcgill.ca/~cs251/ClosestPair/ClosestPairDQ.html" title="enlace: http://www.cs.mcgill.ca/~cs251/ClosestPair/ClosestPairDQ.html">más cercanos</a> <a href="https://en.wikipedia.org/wiki/Closest pair of points problem" title="wp: problema de par de puntos más cercano">problema</a>
|
||||
<a href="http://www.cs.mcgill.ca/~cs251/ClosestPair/ClosestPairDQ.html" title="enlace: http://www.cs.mcgill.ca/~cs251/ClosestPair/ClosestPairDQ.html">Par más cercano (McGill)</a>
|
||||
<a href="http://www.cs.ucsb.edu/~suri/cs235/ClosestPair.pdf" title="enlace: http://www.cs.ucsb.edu/~suri/cs235/ClosestPair.pdf">Par más cercano (UCSB)</a>
|
||||
<a href="http://classes.cec.wustl.edu/~cse241/handouts/closestpair.pdf" title="enlace: http://classes.cec.wustl.edu/~cse241/handouts/closestpair.pdf">Par más cercano (WUStL)</a>
|
||||
<a href="http://www.cs.iupui.edu/~xkzou/teaching/CS580/Divide-and-conquer-closestPair.ppt" title="enlace: http://www.cs.iupui.edu/~xkzou/teaching/CS580/Divide-and-conquer-closestPair.ppt">Par más cercano (IUPUI)</a>
|
||||
<p> Para la entrada, espere que el argumento sea una matriz de objetos (puntos) con los miembros <code>x</code> e <code>y</code> establecidos en números. Para la salida, devuelva un objeto que contenga los pares clave: valor para la <code>distance</code> y el <code>pair</code> (es decir, el par de dos puntos más cercanos). </p>
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>getClosestPair</code> es una función.
|
||||
testString: 'assert(typeof getClosestPair === "function", "<code>getClosestPair</code> is a function.");'
|
||||
- text: La distancia debe ser la siguiente.
|
||||
testString: 'assert.equal(getClosestPair(points1).distance, answer1.distance, "Distance should be the following.");'
|
||||
- text: Los puntos deben ser los siguientes.
|
||||
testString: 'assert.deepEqual(JSON.parse(JSON.stringify(getClosestPair(points1))).pair, answer1.pair, "Points should be the following.");'
|
||||
- text: La distancia debe ser la siguiente.
|
||||
testString: 'assert.equal(getClosestPair(points2).distance, answer2.distance, "Distance should be the following.");'
|
||||
- text: Los puntos deben ser los siguientes.
|
||||
testString: 'assert.deepEqual(JSON.parse(JSON.stringify(getClosestPair(points2))).pair, answer2.pair, "Points should be the following.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
const Point = function (x, y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
};
|
||||
Point.prototype.getX = function () {
|
||||
return this.x;
|
||||
};
|
||||
Point.prototype.getY = function () {
|
||||
return this.y;
|
||||
};
|
||||
|
||||
function getClosestPair (pointsArr) {
|
||||
// Good luck!
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
console.info('after the test');
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
const Point = function (x, y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
};
|
||||
Point.prototype.getX = function () {
|
||||
return this.x;
|
||||
};
|
||||
Point.prototype.getY = function () {
|
||||
return this.y;
|
||||
};
|
||||
|
||||
const mergeSort = function mergeSort(points, comp) {
|
||||
if(points.length < 2) return points;
|
||||
|
||||
var n = points.length,
|
||||
i = 0,
|
||||
j = 0,
|
||||
leftN = Math.floor(n / 2),
|
||||
rightN = leftN;
|
||||
|
||||
var leftPart = mergeSort( points.slice(0, leftN), comp),
|
||||
rightPart = mergeSort( points.slice(rightN), comp );
|
||||
|
||||
var sortedPart = [];
|
||||
|
||||
while((i < leftPart.length) && (j < rightPart.length)) {
|
||||
if(comp(leftPart[i], rightPart[j]) < 0) {
|
||||
sortedPart.push(leftPart[i]);
|
||||
i += 1;
|
||||
}
|
||||
else {
|
||||
sortedPart.push(rightPart[j]);
|
||||
j += 1;
|
||||
}
|
||||
}
|
||||
while(i < leftPart.length) {
|
||||
sortedPart.push(leftPart[i]);
|
||||
i += 1;
|
||||
}
|
||||
while(j < rightPart.length) {
|
||||
sortedPart.push(rightPart[j]);
|
||||
j += 1;
|
||||
}
|
||||
return sortedPart;
|
||||
};
|
||||
|
||||
const closestPair = function _closestPair(Px, Py) {
|
||||
if(Px.length < 2) return { distance: Infinity, pair: [ new Point(0, 0), new Point(0, 0) ] };
|
||||
if(Px.length < 3) {
|
||||
//find euclid distance
|
||||
var d = Math.sqrt( Math.pow(Math.abs(Px[1].x - Px[0].x), 2) + Math.pow(Math.abs(Px[1].y - Px[0].y), 2) );
|
||||
return {
|
||||
distance: d,
|
||||
pair: [ Px[0], Px[1] ]
|
||||
};
|
||||
}
|
||||
|
||||
var n = Px.length,
|
||||
leftN = Math.floor(n / 2),
|
||||
rightN = leftN;
|
||||
|
||||
var Xl = Px.slice(0, leftN),
|
||||
Xr = Px.slice(rightN),
|
||||
Xm = Xl[leftN - 1],
|
||||
Yl = [],
|
||||
Yr = [];
|
||||
//separate Py
|
||||
for(var i = 0; i < Py.length; i += 1) {
|
||||
if(Py[i].x <= Xm.x)
|
||||
Yl.push(Py[i]);
|
||||
else
|
||||
Yr.push(Py[i]);
|
||||
}
|
||||
|
||||
var dLeft = _closestPair(Xl, Yl),
|
||||
dRight = _closestPair(Xr, Yr);
|
||||
|
||||
var minDelta = dLeft.distance,
|
||||
closestPair = dLeft.pair;
|
||||
if(dLeft.distance > dRight.distance) {
|
||||
minDelta = dRight.distance;
|
||||
closestPair = dRight.pair;
|
||||
}
|
||||
|
||||
//filter points around Xm within delta (minDelta)
|
||||
var closeY = [];
|
||||
for(i = 0; i < Py.length; i += 1) {
|
||||
if(Math.abs(Py[i].x - Xm.x) < minDelta) closeY.push(Py[i]);
|
||||
}
|
||||
//find min within delta. 8 steps max
|
||||
for(i = 0; i < closeY.length; i += 1) {
|
||||
for(var j = i + 1; j < Math.min( (i + 8), closeY.length ); j += 1) {
|
||||
var d = Math.sqrt( Math.pow(Math.abs(closeY[j].x - closeY[i].x), 2) + Math.pow(Math.abs(closeY[j].y - closeY[i].y), 2) );
|
||||
if(d < minDelta) {
|
||||
minDelta = d;
|
||||
closestPair = [ closeY[i], closeY[j] ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
distance: minDelta,
|
||||
pair: closestPair
|
||||
};
|
||||
};
|
||||
|
||||
function getClosestPair (points) {
|
||||
const sortX = function (a, b) { return (a.x < b.x) ? -1 : ((a.x > b.x) ? 1 : 0); }
|
||||
const sortY = function (a, b) { return (a.y < b.y) ? -1 : ((a.y > b.y) ? 1 : 0); }
|
||||
|
||||
const Px = mergeSort(points, sortX);
|
||||
const Py = mergeSort(points, sortY);
|
||||
|
||||
return closestPair(Px, Py);
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,105 @@
|
||||
---
|
||||
title: Combinations
|
||||
id: 5958469238c0d8d2632f46db
|
||||
localeTitle: 5958469238c0d8d2632f46db
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Tarea:
|
||||
<p> Dado los enteros no negativos <big>m</big> y <big>n</big> , genere todas las <a href="http://mathworld.wolfram.com/Combination.html" title="enlace: http://mathworld.wolfram.com/Combination.html">combinaciones</a> de tamaño <big>m</big> de los enteros de <big>0</big> (cero) a <big>n-1</big> en orden ordenado (cada combinación está ordenada y la tabla completa está ordenada). </p>
|
||||
Ejemplo:
|
||||
<p> <big>3</big> peine <big>5</big> es: </p>
|
||||
<pre>
|
||||
0 1 2
|
||||
0 1 3
|
||||
0 1 4
|
||||
0 2 2
|
||||
0 2 4
|
||||
0 3 4
|
||||
1 2 3
|
||||
1 2 4
|
||||
1 3 4
|
||||
2 3 4
|
||||
</pre>
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>combinations</code> son una función.
|
||||
testString: 'assert(typeof combinations === "function", "<code>combinations</code> is a function.");'
|
||||
- text: ' <code>combinations(3, 5)</code> deben devolver <code>[[0, 1, 2], [0, 1, 3], [0, 1, 4], [0, 2, 3], [0, 2, 4], [0, 3, 4], [1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]]</code> . '
|
||||
testString: 'assert.deepEqual(combinations(testInput1[0], testInput1[1]), testOutput1, "<code>combinations(3, 5)</code> should return <code>[[0, 1, 2], [0, 1, 3], [0, 1, 4], [0, 2, 3], [0, 2, 4], [0, 3, 4], [1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]]</code>.");'
|
||||
- text: ' <code>combinations(4, 6)</code> deben devolver <code>[[0,1,2,3], [0,1,2,4], [0,1,2,5], [0,1,3,4], [0,1,3,5], [0,1,4,5], [0,2,3,4], [0,2,3,5], [0,2,4,5], [0,3,4,5], [1,2,3,4], [1,2,3,5], [1,2,4,5], [1,3,4,5], [2,3,4,5]]</code> '
|
||||
testString: 'assert.deepEqual(combinations(testInput2[0], testInput2[1]), testOutput2, "<code>combinations(4, 6)</code> should return <code>[[0,1,2,3], [0,1,2,4], [0,1,2,5], [0,1,3,4], [0,1,3,5], [0,1,4,5], [0,2,3,4], [0,2,3,5], [0,2,4,5], [0,3,4,5], [1,2,3,4], [1,2,3,5], [1,2,4,5], [1,3,4,5], [2,3,4,5]]</code>");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function combinations (m, n) {
|
||||
// Good luck!
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
console.info('after the test');
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
function combinations (m, n) {
|
||||
const nArr = [...Array(n).keys()];
|
||||
|
||||
return (function generateCombinations (size, numArr) {
|
||||
const ret = [];
|
||||
|
||||
for (let i = 0; i < numArr.length; i++) {
|
||||
if (size === 1) {
|
||||
ret.push([numArr[i]]);
|
||||
}
|
||||
else {
|
||||
const sub = generateCombinations(size - 1, numArr.slice(i + 1, numArr.length));
|
||||
for (let subI = 0; subI < sub.length; subI++) {
|
||||
const next = sub[subI];
|
||||
next.unshift(numArr[i]);
|
||||
ret.push(next);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}(m, nArr));
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,92 @@
|
||||
---
|
||||
title: Comma quibbling
|
||||
id: 596e414344c3b2872167f0fe
|
||||
localeTitle: 596e414344c3b2872167f0fe
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
<p> La objeción de coma es una tarea establecida originalmente por Eric Lippert en su <a href="http://blogs.msdn.com/b/ericlippert/archive/2009/04/15/comma-quibbling.aspx" title="enlace: http://blogs.msdn.com/b/ericlippert/archive/2009/04/15/comma-quibbling.aspx">blog</a> . </p>
|
||||
Tarea: <p> Escriba una función para generar una salida de cadena que sea la concatenación de palabras de entrada de una lista / secuencia donde: </p>
|
||||
Una entrada sin palabras produce la cadena de salida de solo los dos caracteres de refuerzo "{}".
|
||||
Una entrada de una sola palabra, por ejemplo, ["ABC"], produce la cadena de salida de la palabra dentro de las dos llaves, por ejemplo, "{ABC}".
|
||||
Una entrada de dos palabras, por ejemplo, ["ABC", "DEF"], produce la cadena de salida de las dos palabras dentro de las dos llaves con las palabras separadas por la cadena "y", por ejemplo, "{ABC y DEF}".
|
||||
Una entrada de tres o más palabras, por ejemplo, ["ABC", "DEF", "G", "H"], produce la cadena de salida de todos menos la última palabra separada por "," con la última palabra separada por " y "y todo entre llaves; por ejemplo, "{ABC, DEF, G y H}".
|
||||
<p> Pruebe su función con la siguiente serie de entradas que muestran su salida aquí en esta página: </p>
|
||||
[] # (No hay palabras de entrada).
|
||||
["ABC"]
|
||||
["ABC", "DEF"]
|
||||
["ABC", "DEF", "G", "H"]
|
||||
<p> Nota: Suponga que las palabras son cadenas no vacías de caracteres en mayúscula para esta tarea. </p>
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>quibble</code> es una función.
|
||||
testString: 'assert(typeof quibble === "function", "<code>quibble</code> is a function.");'
|
||||
- text: ' <code>quibble(["ABC"])</code> debería devolver una cadena.'
|
||||
testString: 'assert(typeof quibble(["ABC"]) === "string", "<code>quibble(["ABC"])</code> should return a string.");'
|
||||
- text: ' <code>quibble([])</code> debe devolver "{}".'
|
||||
testString: 'assert.equal(quibble(testCases[0]), results[0], "<code>quibble([])</code> should return "{}".");'
|
||||
- text: ' <code>quibble(["ABC"])</code> debe devolver "{ABC}".'
|
||||
testString: 'assert.equal(quibble(testCases[1]), results[1], "<code>quibble(["ABC"])</code> should return "{ABC}".");'
|
||||
- text: ' <code>quibble(["ABC", "DEF"])</code> debe devolver "{ABC and DEF}".'
|
||||
testString: 'assert.equal(quibble(testCases[2]), results[2], "<code>quibble(["ABC", "DEF"])</code> should return "{ABC and DEF}".");'
|
||||
- text: ' <code>quibble(["ABC", "DEF", "G", "H"])</code> debe devolver "{ABC, DEF, G y H}".'
|
||||
testString: 'assert.equal(quibble(testCases[3]), results[3], "<code>quibble(["ABC", "DEF", "G", "H"])</code> should return "{ABC,DEF,G and H}".");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function quibble (words) {
|
||||
// Good luck!
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
console.info('after the test');
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
function quibble (words) {
|
||||
return "{" +
|
||||
words.slice(0, words.length - 1).join(",") +
|
||||
(words.length > 1 ? " and " : "") +
|
||||
(words[words.length - 1] || ") +
|
||||
"}";
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,107 @@
|
||||
---
|
||||
title: Compare a list of strings
|
||||
id: 596e457071c35c882915b3e4
|
||||
localeTitle: 596e457071c35c882915b3e4
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
<p> Dada una <a href="https://en.wikipedia.org/wiki/List_(abstract_data_type)" title="wp: List_ (abstract_data_type)">lista</a> de muchas cadenas arbitrarias, implemente una función para cada una de las siguientes condiciones: </p> prueba si todos son léxicamente iguales
|
||||
prueba si cada cadena es léxicamente menor que la siguiente (es decir, si la lista está en estricto orden ascendente)
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>allEqual</code> es una función.
|
||||
testString: 'assert(typeof allEqual === "function", "<code>allEqual</code> is a function.");'
|
||||
- text: <code>azSorted</code> es una función.
|
||||
testString: 'assert(typeof azSorted === "function", "<code>azSorted</code> is a function.");'
|
||||
- text: ' <code>allEqual(["AA", "AA", "AA", "AA"])</code> devuelve true.'
|
||||
testString: 'assert(allEqual(testCases[0]), "<code>allEqual(["AA", "AA", "AA", "AA"])</code> returns true.");'
|
||||
- text: ' <code>azSorted(["AA", "AA", "AA", "AA"])</code> devuelve falso.'
|
||||
testString: 'assert(!azSorted(testCases[0]), "<code>azSorted(["AA", "AA", "AA", "AA"])</code> returns false.");'
|
||||
- text: ' <code>allEqual(["AA", "ACB", "BB", "CC"])</code> devuelve falso.'
|
||||
testString: 'assert(!allEqual(testCases[1]), "<code>allEqual(["AA", "ACB", "BB", "CC"])</code> returns false.");'
|
||||
- text: ' <code>azSorted(["AA", "ACB", "BB", "CC"])</code> devuelve verdadero.'
|
||||
testString: 'assert(azSorted(testCases[1]), "<code>azSorted(["AA", "ACB", "BB", "CC"])</code> returns true.");'
|
||||
- text: ' <code>allEqual([])</code> devuelve true.'
|
||||
testString: 'assert(allEqual(testCases[2]), "<code>allEqual([])</code> returns true.");'
|
||||
- text: ' <code>azSorted([])</code> devuelve true.'
|
||||
testString: 'assert(azSorted(testCases[2]), "<code>azSorted([])</code> returns true.");'
|
||||
- text: ' <code>allEqual(["AA"])</code> devuelve true.'
|
||||
testString: 'assert(allEqual(testCases[3]), "<code>allEqual(["AA"])</code> returns true.");'
|
||||
- text: ' <code>azSorted(["AA"])</code> devuelve verdadero.'
|
||||
testString: 'assert(azSorted(testCases[3]), "<code>azSorted(["AA"])</code> returns true.");'
|
||||
- text: ' <code>allEqual(["BB", "AA"])</code> devuelve false. "
|
||||
testString: 'assert(!allEqual(testCases[4]), "<code>allEqual(["BB", "AA"])</code> returns false.");'
|
||||
- text: ' <code>azSorted(["BB", "AA"])</code> devuelve falso.'
|
||||
testString: 'assert(!azSorted(testCases[4]), "<code>azSorted(["BB", "AA"])</code> returns false.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function allEqual (arr) {
|
||||
// Good luck!
|
||||
return true;
|
||||
}
|
||||
|
||||
function azSorted (arr) {
|
||||
// Good luck!
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
console.info('after the test');
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
function allEqual(a) {
|
||||
let out = true;
|
||||
let i = 0;
|
||||
while (++i < a.length) {
|
||||
out = out && (a[i - 1] === a[i]);
|
||||
} return out;
|
||||
}
|
||||
|
||||
function azSorted(a) {
|
||||
let out = true;
|
||||
let i = 0;
|
||||
while (++i < a.length) {
|
||||
out = out && (a[i - 1] < a[i]);
|
||||
} return out;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,161 @@
|
||||
---
|
||||
title: Convert seconds to compound duration
|
||||
id: 596fd036dc1ab896c5db98b1
|
||||
localeTitle: 596fd036dc1ab896c5db98b1
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Tarea:
|
||||
<p> Implementar una función que: </p>
|
||||
toma un entero positivo que representa una duración en segundos como entrada (por ejemplo, <code>100</code> ), y
|
||||
devuelve una cadena que muestra la misma duración descompuesta en semanas, días, horas, minutos y segundos como se detalla a continuación (por ejemplo, " <code>1 min, 40 sec</code> ").
|
||||
<p> Demostrar que pasa los siguientes tres casos de prueba: </p><p style="font-size:115%; margin:1em 0 0 0"> Casos de prueba </p>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th> número de entrada </th>
|
||||
<th> número de salida </th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> 7259 </td>
|
||||
<td> <code>2 hr, 59 sec</code> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> 86400 </td>
|
||||
<td> <code>1 d</code> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> 6000000 </td>
|
||||
<td> <code>9 wk, 6 d, 10 hr, 40 min</code> </td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p style="font-size:115%; margin:1em 0 0 0"> Detalles </p>
|
||||
Se deben usar las siguientes cinco unidades:
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th> unidad </th>
|
||||
<th> sufijo utilizado en la salida </th>
|
||||
<th> conversión </th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> semana </td>
|
||||
<td> <code>wk</code> </td>
|
||||
<td> 1 semana = 7 días </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> día </td>
|
||||
<td> <code>d</code> </td>
|
||||
<td> 1 día = 24 horas </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> hora </td>
|
||||
<td> <code>hr</code> </td>
|
||||
<td> 1 hora = 60 minutos </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> minuto </td>
|
||||
<td> <code>min</code> </td>
|
||||
<td> 1 minuto = 60 segundos </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> segundo </td>
|
||||
<td> <code>sec</code> </td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
Sin embargo, solo incluya cantidades con valores que no sean cero en la salida (por ejemplo, devuelva " <code>1 d</code> " y no " <code>0 wk, 1 d, 0 hr, 0 min, 0 sec</code> "). Dé prioridad a las unidades más grandes sobre las más pequeñas como tanto como sea posible (p. ej., devuelva <code>2 min, 10 sec</code> y no <code>1 min, 70 sec</code> o <code>130 sec</code> ) Imite el formato que se muestra en los casos de prueba (cantidades ordenadas de unidad mayor a menor y separadas por comas + espacio; valor y unidad de cada cantidad separada por espacio).
|
||||
<p><hr style="margin:1em 0;"/></p>
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>convertSeconds</code> es una función.
|
||||
testString: 'assert(typeof convertSeconds === "function", "<code>convertSeconds</code> is a function.");'
|
||||
- text: ' <code>convertSeconds(7259)</code> debe devolver <code>2 hr, 59 sec</code> .'
|
||||
testString: 'assert.equal(convertSeconds(testCases[0]), results[0], "<code>convertSeconds(7259)</code> should return <code>2 hr, 59 sec</code>.");'
|
||||
- text: <code>convertSeconds(86400)</code> debe devolver <code>1 d</code> .
|
||||
testString: 'assert.equal(convertSeconds(testCases[1]), results[1], "<code>convertSeconds(86400)</code> should return <code>1 d</code>.");'
|
||||
- text: ' <code>convertSeconds(6000000)</code> debe devolver <code>9 wk, 6 d, 10 hr, 40 min</code> .'
|
||||
testString: 'assert.equal(convertSeconds(testCases[2]), results[2], "<code>convertSeconds(6000000)</code> should return <code>9 wk, 6 d, 10 hr, 40 min</code>.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function convertSeconds (sec) {
|
||||
// Good luck!
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
console.info('after the test');
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
function convertSeconds (sec) {
|
||||
const localNames = ['wk', 'd', 'hr', 'min', 'sec'];
|
||||
// compoundDuration :: [String] -> Int -> String
|
||||
const compoundDuration = (labels, intSeconds) =>
|
||||
weekParts(intSeconds)
|
||||
.map((v, i) => [v, labels[i]])
|
||||
.reduce((a, x) =>
|
||||
a.concat(x[0] ? [`${x[0]} ${x[1] || '?'}`] : []), []
|
||||
)
|
||||
.join(', ');
|
||||
|
||||
// weekParts :: Int -> [Int]
|
||||
const weekParts = intSeconds => [0, 7, 24, 60, 60]
|
||||
.reduceRight((a, x) => {
|
||||
const r = a.rem;
|
||||
const mod = x !== 0 ? r % x : r;
|
||||
|
||||
return {
|
||||
rem: (r - mod) / (x || 1),
|
||||
parts: [mod].concat(a.parts)
|
||||
};
|
||||
}, {
|
||||
rem: intSeconds,
|
||||
parts: []
|
||||
})
|
||||
.parts;
|
||||
|
||||
return compoundDuration(localNames, sec);
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,80 @@
|
||||
---
|
||||
title: Count occurrences of a substring
|
||||
id: 596fda99c69f779975a1b67d
|
||||
localeTitle: 596fda99c69f779975a1b67d
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Tarea:
|
||||
<p> Cree una función, o muestre una función incorporada, para contar el número de apariciones no superpuestas de una subcadena dentro de una cadena. </p><p> La función debe tomar dos argumentos: </p>
|
||||
el primer argumento es la cadena a buscar, y
|
||||
el segundo una subcadena a buscar.
|
||||
<p> Debe devolver un número entero. </p>
|
||||
<p> La coincidencia debe producir el mayor número de coincidencias no superpuestas. </p><p> En general, esto significa esencialmente hacer coincidir de izquierda a derecha o de derecha a izquierda. </p>
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>countSubstring</code> es una función.
|
||||
testString: 'assert(typeof countSubstring === "function", "<code>countSubstring</code> is a function.");'
|
||||
- text: ' <code>countSubstring("the three truths", "th")</code> debe devolver <code>3</code> '
|
||||
testString: 'assert.equal(countSubstring(testCases[0], searchString[0]), results[0], "<code>countSubstring("the three truths", "th")</code> should return <code>3</code>.");'
|
||||
- text: ' <code>countSubstring("ababababab", "abab")</code> debe devolver <code>2</code> '
|
||||
testString: 'assert.equal(countSubstring(testCases[1], searchString[1]), results[1], "<code>countSubstring("ababababab", "abab")</code> should return <code>2</code>.");'
|
||||
- text: ' <code>countSubstring("abaabba*bbaba*bbab", "a*b")</code> debe devolver <code>2</code> '
|
||||
testString: 'assert.equal(countSubstring(testCases[2], searchString[2]), results[2], "<code>countSubstring("abaabba*bbaba*bbab", "a*b")</code> should return <code>2</code>.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function countSubstring (str, subStr) {
|
||||
// Good luck!
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
console.info('after the test');
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
function countSubstring(str, subStr) {
|
||||
const escapedSubStr = subStr.replace(/[.+*?^$[\]{}()|/]/g, '\\$&');
|
||||
const matches = str.match(new RegExp(escapedSubStr, 'g'));
|
||||
return matches ? matches.length : 0;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,92 @@
|
||||
---
|
||||
title: Count the coins
|
||||
id: 59713bd26bdeb8a594fb9413
|
||||
localeTitle: 59713bd26bdeb8a594fb9413
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
<p> Hay cuatro tipos de monedas comunes en moneda <a href="https://en.wikipedia.org/wiki/United_States" title="enlace: https://en.wikipedia.org/wiki/United_States">estadounidense</a> : </p>
|
||||
trimestres (25 centavos)
|
||||
monedas de diez centavos (10 centavos)
|
||||
centavos (5 centavos) y
|
||||
centavos (1 centavo)
|
||||
<p> Hay seis formas de hacer cambio por 15 centavos: </p>
|
||||
Un centavo y un centavo
|
||||
Un centavo y 5 centavos
|
||||
3 centavos
|
||||
2 centavos y 5 centavos
|
||||
Un centavo y 10 centavos
|
||||
15 centavos
|
||||
Tarea:
|
||||
<p> Implemente una función para determinar cuántas maneras hay de hacer un cambio por un dólar usando estas monedas comunes. (1 dólar = 100 centavos). </p>
|
||||
Referencia:
|
||||
<a href="http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-11.html#%_sec_Temp_52" title="enlace: http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-11.html#%_sec_Temp_52">un algoritmo de MIT Press</a> .
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>countCoins</code> es una función.
|
||||
testString: 'assert(typeof countCoins === "function", "<code>countCoins</code> is a function.");'
|
||||
- text: <code>countCoints()</code> debe devolver 242.
|
||||
testString: 'assert.equal(countCoins(), 242, "<code>countCoints()</code> should return 242.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function countCoins () {
|
||||
// Good luck!
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
function countCoins () {
|
||||
let t = 100;
|
||||
const operands = [1, 5, 10, 25];
|
||||
const targetsLength = t + 1;
|
||||
const operandsLength = operands.length;
|
||||
t = [1];
|
||||
|
||||
for (let a = 0; a < operandsLength; a++) {
|
||||
for (let b = 1; b < targetsLength; b++) {
|
||||
// initialise undefined target
|
||||
t[b] = t[b] ? t[b] : 0;
|
||||
|
||||
// accumulate target + operand ways
|
||||
t[b] += (b < operands[a]) ? 0 : t[b - operands[a]];
|
||||
}
|
||||
}
|
||||
|
||||
return t[targetsLength - 1];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,164 @@
|
||||
---
|
||||
title: Cramer's rule
|
||||
id: 59713da0a428c1a62d7db430
|
||||
localeTitle: 59713da0a428c1a62d7db430
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
<p> En <a href="https://en.wikipedia.org/wiki/linear algebra" title="wp: álgebra lineal">álgebra lineal</a> , <a href="https://en.wikipedia.org/wiki/Cramer's rule" title="wp: la regla de cramer">la regla de Cramer</a> es una fórmula explícita para la solución de un <a href="https://en.wikipedia.org/wiki/system of linear equations" title="wp: sistema de ecuaciones lineales">sistema de ecuaciones lineales</a> con tantas ecuaciones como incógnitas, válida siempre que el sistema tenga una solución única. Expresa la solución en términos de los determinantes de la matriz del coeficiente (cuadrado) y de las matrices obtenidas de ella al reemplazar una columna por el vector de los lados derechos de las ecuaciones. </p>
|
||||
<p> Dado </p>
|
||||
<p> </p>
|
||||
<p> $ \ left \ {\ begin {matrix} a_1x + b_1y + c_1z & = {\ color {red} d_1} \\ a_2x + b_2y + c_2z & = {\ color {red} d_2} \\ a_3x + b_3y + c_3z & = {\ color {rojo} d_3} \ fin {matriz} \ derecha. $ </p>
|
||||
<p> que en formato matricial es </p><p></p>
|
||||
<p> $ \ begin {bmatrix} a_1 & b_1 & c_1 \\ a_2 & b_2 & c_2 \\ a_3 & b_3 & c_3 \ end {bmatrix} \ begin {bmatrix} x \\ y \\ z \ end {bmatrix} = \ begin {bmatrix} {\ color {rojo} d_1} \\ {\ color {rojo} d_2} \\ {\ color {rojo} d_3} \ fin {bmatrix}. $ </p>
|
||||
<p> Luego, los valores de $ x, y $ y $ z $ se pueden encontrar de la siguiente manera: </p><p></p>
|
||||
<p> $ x = \ frac {\ begin {vmatrix} {\ color {red} d_1} & b_1 & c_1 \\ {\ color {red} d_2} & b_2 & c_2 \\ {\ color {red} d_3} & b_3 & c_3 \ end {vmatrix}} {\ begin {vmatrix} a_1 & b_1 & c_1 \\ a_2 & b_2 & c_2 \\ a_3 & b_3 & c_3 \ end {vmatrix}}, \ quad y = \ frac {\ begin {vmatrix } a_1 & {\ color {red} d_1} & c_1 \\ a_2 & {\ color {red} d_2} & c_2 \\ a_3 & {\ color {red} d_3} & c_3 \ end {vmatrix}} {\ comenzar {vmatrix} a_1 & b_1 & c_1 \\ a_2 & b_2 & c_2 \\ a_3 & b_3 & c_3 \ end {vmatrix}}, \ text {and} z = \ frac {\ begin {vmatrix} a_1 & b_1 & {\ color {rojo} d_1} \\ a_2 & b_2 & {\ color {red} d_2} \\ a_3 & b_3 & {\ color {rojo} d_3} \ end {vmatrix}} {\ begin {vmatrix} a_1 & b_1 & c_1 \\ a_2 & b_2 & c_2 \\ a_3 & b_3 & c_3 \ end {vmatrix}}. $ </p>
|
||||
|
||||
Tarea
|
||||
<p> Dado el siguiente sistema de ecuaciones: </p><p> <big>
|
||||
$ \ begin {cases}
|
||||
2w-x + 5y + z = -3 \\
|
||||
3w + 2x + 2y-6z = -32 \\
|
||||
w + 3x + 3y-z = -47 \\
|
||||
5w-2x -3y + 3z = 49 \\
|
||||
\ fin {casos} $ <code>0</code></big> </p>
|
||||
<p> resuelve por <big>$ w $, $ x $, $ y $</big> y <big>$ z $</big> , usando la regla de Cramer. </p>
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>cramersRule</code> es una función.
|
||||
testString: 'assert(typeof cramersRule === "function", "<code>cramersRule</code> is a function.");'
|
||||
- text: ' <code>cramersRule([[2, -1, 5, 1], [3, 2, 2, -6], [1, 3, 3, -1], [5, -2, -3, 3]], [-3, -32, -47, 49])</code> debe devolver <code>[2, -12, -4, 1]</code> . '
|
||||
testString: 'assert.deepEqual(cramersRule(matrices[0], freeTerms[0]), answers[0], "<code>cramersRule([[2, -1, 5, 1], [3, 2, 2, -6], [1, 3, 3, -1], [5, -2, -3, 3]], [-3, -32, -47, 49])</code> should return <code>[2, -12, -4, 1]</code>.");'
|
||||
- text: ' <code>cramersRule([[3, 1, 1], [2, 2, 5], [1, -3, -4]], [3, -1, 2])</code> debe devolver <code>[1, 1, -1]</code> .
|
||||
testString: 'assert.deepEqual(cramersRule(matrices[1], freeTerms[1]), answers[1], "<code>cramersRule([[3, 1, 1], [2, 2, 5], [1, -3, -4]], [3, -1, 2])</code> should return <code>[1, 1, -1]</code>.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function cramersRule (matrix, freeTerms) {
|
||||
// Good luck!
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
console.info('after the test');
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
/**
|
||||
* Compute Cramer's Rule
|
||||
* @param {array} matrix x,y,z, etc. terms
|
||||
* @param {array} freeTerms
|
||||
* @return {array} solution for x,y,z, etc.
|
||||
*/
|
||||
function cramersRule(matrix, freeTerms) {
|
||||
const det = detr(matrix);
|
||||
const returnArray = [];
|
||||
let i;
|
||||
|
||||
for (i = 0; i < matrix[0].length; i++) {
|
||||
const tmpMatrix = insertInTerms(matrix, freeTerms, i);
|
||||
returnArray.push(detr(tmpMatrix) / det);
|
||||
}
|
||||
return returnArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts single dimensional array into
|
||||
* @param {array} matrix multidimensional array to have ins inserted into
|
||||
* @param {array} ins single dimensional array to be inserted vertically into matrix
|
||||
* @param {array} at zero based offset for ins to be inserted into matrix
|
||||
* @return {array} New multidimensional array with ins replacing the at column in matrix
|
||||
*/
|
||||
function insertInTerms(matrix, ins, at) {
|
||||
const tmpMatrix = clone(matrix);
|
||||
let i;
|
||||
for (i = 0; i < matrix.length; i++) {
|
||||
tmpMatrix[i][at] = ins[i];
|
||||
}
|
||||
return tmpMatrix;
|
||||
}
|
||||
/**
|
||||
* Compute the determinate of a matrix. No protection, assumes square matrix
|
||||
* function borrowed, and adapted from MIT Licensed numericjs library (www.numericjs.com)
|
||||
* @param {array} m Input Matrix (multidimensional array)
|
||||
* @return {number} result rounded to 2 decimal
|
||||
*/
|
||||
function detr(m) {
|
||||
let ret = 1;
|
||||
let j;
|
||||
let k;
|
||||
const A = clone(m);
|
||||
const n = m[0].length;
|
||||
let alpha;
|
||||
|
||||
for (j = 0; j < n - 1; j++) {
|
||||
k = j;
|
||||
for (let i = j + 1; i < n; i++) { if (Math.abs(A[i][j]) > Math.abs(A[k][j])) { k = i; } }
|
||||
if (k !== j) {
|
||||
const temp = A[k]; A[k] = A[j]; A[j] = temp;
|
||||
ret *= -1;
|
||||
}
|
||||
const Aj = A[j];
|
||||
for (let i = j + 1; i < n; i++) {
|
||||
const Ai = A[i];
|
||||
alpha = Ai[j] / Aj[j];
|
||||
for (k = j + 1; k < n - 1; k += 2) {
|
||||
const k1 = k + 1;
|
||||
Ai[k] -= Aj[k] * alpha;
|
||||
Ai[k1] -= Aj[k1] * alpha;
|
||||
}
|
||||
if (k !== n) { Ai[k] -= Aj[k] * alpha; }
|
||||
}
|
||||
if (Aj[j] === 0) { return 0; }
|
||||
ret *= Aj[j];
|
||||
}
|
||||
return Math.round(ret * A[j][j] * 100) / 100;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone two dimensional Array using ECMAScript 5 map function and EcmaScript 3 slice
|
||||
* @param {array} m Input matrix (multidimensional array) to clone
|
||||
* @return {array} New matrix copy
|
||||
*/
|
||||
function clone(m) {
|
||||
return m.map(a => a.slice());
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,82 @@
|
||||
---
|
||||
title: Date format
|
||||
id: 59669d08d75b60482359409f
|
||||
localeTitle: 59669d08d75b60482359409f
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Tarea:
|
||||
<p> Devuelve una matriz con la fecha actual en los formatos: </p>
|
||||
<p> - 2007-11-23 y </p>
|
||||
<p> - Domingo 23 de noviembre de 2007. </p>
|
||||
<p> Salida de ejemplo: <code>['2007-11-23', 'Sunday, November 23, 2007']</code> </p>
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>getDateFormats</code> es una función.
|
||||
testString: 'assert(typeof getDateFormats === "function", "<code>getDateFormats</code> is a function.");'
|
||||
- text: Debe devolver un objeto.
|
||||
testString: 'assert(typeof getDateFormats() === "object", "Should return an object.");'
|
||||
- text: Debe devolverse una matriz con 2 elementos.
|
||||
testString: 'assert(getDateFormats().length === 2, "Should returned an array with 2 elements.");'
|
||||
- text: Debe devolver la fecha correcta en el formato correcto.
|
||||
testString: 'assert.deepEqual(getDateFormats(), dates, equalsMessage);'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function getDateFormats () {
|
||||
// Good luck!
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
console.info('after the test');
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
function getDateFormats () {
|
||||
const date = new Date();
|
||||
const weekdays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
|
||||
const months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
|
||||
const fmt1 = `${date.getFullYear()}-${(1 + date.getMonth())}-${date.getDate()}`;
|
||||
const fmt2 = `${weekdays[date.getDay()]}, ${months[date.getMonth()]} ${date.getDate()}, ${date.getFullYear()}`;
|
||||
return [fmt1, fmt2];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,112 @@
|
||||
---
|
||||
title: Date manipulation
|
||||
id: 5966c21cf732a95f1b67dd28
|
||||
localeTitle: 5966c21cf732a95f1b67dd28
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Tarea:
|
||||
<p> Dada una cadena de fecha en EST, genera la fecha dada como una cadena con 12 horas agregadas a la hora. </p>
|
||||
<p> La zona horaria debe ser preservada. </p>
|
||||
<p> Ejemplo de entrada: </p>
|
||||
<p> <code>"March 7 2009 7:30pm EST"</code> </p>
|
||||
<p> Ejemplo de salida: </p>
|
||||
<p> <code>"March 8 2009 7:30am EST"</code> </p>
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>add12Hours</code> es una función.
|
||||
testString: 'assert(typeof add12Hours === "function", "<code>add12Hours</code> is a function.");'
|
||||
- text: <code>add12Hours(dateString)</code> debe devolver una cadena.
|
||||
testString: 'assert(typeof add12Hours(tests[0]) === "string", "<code>add12Hours(dateString)</code> should return a string.");'
|
||||
- text: ' <code>add12Hours("" + tests[0] + "")</code> debe devolver <code>"" + answers[0] + ""</code> '
|
||||
testString: 'assert(add12Hours(tests[0]) === answers[0], "<code>add12Hours("" + tests[0] + "")</code> should return <code>"" + answers[0] + ""</code>");'
|
||||
- text: Debería cambiar el día. <code>add12Hours("" + tests[1] + "")</code> debe devolver <code>"" + answers[1] + ""</code> '
|
||||
testString: 'assert(add12Hours(tests[1]) === answers[1], "Should handel day change. <code>add12Hours("" + tests[1] + "")</code> should return <code>"" + answers[1] + ""</code>");'
|
||||
- text: 'Debe cambiar el mes en un año bisiesto. <code>add12Hours("" + tests[2] + "")</code> debe devolver <code>"" + answers[2] + ""</code> '
|
||||
testString: 'assert(add12Hours(tests[2]) === answers[2], "Should handel month change in a leap years. <code>add12Hours("" + tests[2] + "")</code> should return <code>"" + answers[2] + ""</code>");'
|
||||
- text: 'Debería cambiar el mes en un año común. <code>add12Hours("" + tests[3] + "")</code> debe devolver <code>"" + answers[3] + ""</code> '
|
||||
testString: 'assert(add12Hours(tests[3]) === answers[3], "Should handel month change in a common years. <code>add12Hours("" + tests[3] + "")</code> should return <code>"" + answers[3] + ""</code>");'
|
||||
- text: Debería cambiar de año. <code>add12Hours("" + tests[4] + "")</code> debe devolver <code>"" + answers[4] + ""</code> '
|
||||
testString: 'assert(add12Hours(tests[4]) === answers[4], "Should handel year change. <code>add12Hours("" + tests[4] + "")</code> should return <code>"" + answers[4] + ""</code>");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function add12Hours (dateString) {
|
||||
// Good luck!
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
console.info('after the test');
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
function add12Hours (dateString) {
|
||||
const months = ['January', 'February', 'March', 'April', 'May', 'June',
|
||||
'July', 'August', 'September', 'October', 'November', 'December'];
|
||||
// Get the parts of the string
|
||||
const parts = dateString.split(' ');
|
||||
const month = months.indexOf(parts[0]);
|
||||
const day = parseInt(parts[1], 10);
|
||||
const year = parseInt(parts[2], 10);
|
||||
const time = parts[3].split(':');
|
||||
let hours = parseInt(time[0], 10);
|
||||
if (time[1].slice(-2) === 'pm') {
|
||||
hours += 12;
|
||||
}
|
||||
const minutes = parseInt(time[1].slice(0, -2), 10);
|
||||
|
||||
// Create a date with given parts, and updated hours
|
||||
const date = new Date();
|
||||
date.setFullYear(year, month, day);
|
||||
date.setHours(hours + 12); // Add 12 hours
|
||||
date.setMinutes(minutes);
|
||||
|
||||
let hoursOutput = date.getHours();
|
||||
let abbreviation = 'am';
|
||||
if (hoursOutput > 12) {
|
||||
hoursOutput -= 12;
|
||||
abbreviation = 'pm';
|
||||
}
|
||||
|
||||
return `${months[date.getMonth()]} ${date.getDate()} ${date.getFullYear()} ${hoursOutput}:${date.getMinutes()}${abbreviation} EST`;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,82 @@
|
||||
---
|
||||
title: Day of the week
|
||||
id: 5966f99c45e8976909a85575
|
||||
localeTitle: 5966f99c45e8976909a85575
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
<p> Una empresa decide que cada vez que caiga un domingo en Navidad, les dará a sus trabajadores todos los días feriados extra pagados para que, junto con los días festivos, los trabajadores no tengan que trabajar la semana siguiente (entre el 25 de diciembre y el primero de enero). </p>
|
||||
<p> Tarea: </p>
|
||||
<p> Escriba una función que tome un año de inicio y un año de finalización y devuelva un conjunto de todos los años en los que el 25 de diciembre será un domingo. </p>
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>findXmasSunday</code> es una función.
|
||||
testString: 'assert(typeof findXmasSunday === "function", "<code>findXmasSunday</code> is a function.");'
|
||||
- text: ' <code>findChristmasSunday(2000, 2100)</code> debería devolver una matriz.'
|
||||
testString: 'assert(typeof findXmasSunday(2000, 2100) === "object", "<code>findChristmasSunday(2000, 2100)</code> should return an array.");'
|
||||
- text: ' <code>findChristmasSunday(2008, 2121</code> debe devolver [1977, 1983, 1988, 1994, 2005, 2011, 2016]'
|
||||
testString: 'assert.deepEqual(findXmasSunday(1970, 2017), firstSolution, "<code>findChristmasSunday(2008, 2121</code> should return [1977, 1983, 1988, 1994, 2005, 2011, 2016]");'
|
||||
- text: ' <code>findChristmasSunday(2008, 2121</code> debe devolver [2011, 2016, 2022, 2033, 2039, 2044, 2050, 2061, 2072, 2078, 2089, 2095, 2101, 2107, 2112, 2118]'
|
||||
testString: 'assert.deepEqual(findXmasSunday(2008, 2121), secondSolution, "<code>findChristmasSunday(2008, 2121</code> should return [2011, 2016, 2022, 2033, 2039, 2044, 2050, 2061, 2067, 2072, 2078, 2089, 2095, 2101, 2107, 2112, 2118]");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function findXmasSunday (start, end) {
|
||||
// Good luck!
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
console.info('after the test');
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
function findXmasSunday (start, end) {
|
||||
const xmasSunday = [];
|
||||
for (let year = start; year <= end; year++) {
|
||||
const xmas = new Date(year, 11, 25);
|
||||
if (xmas.getDay() === 0) {
|
||||
xmasSunday.push(year);
|
||||
}
|
||||
}
|
||||
return xmasSunday;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,175 @@
|
||||
---
|
||||
title: Deal cards for FreeCell
|
||||
id: 59694356a6e7011f7f1c5f4e
|
||||
localeTitle: 59694356a6e7011f7f1c5f4e
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
<p> Free Cell es el juego de cartas solitario que Paul Alfille introdujo al sistema PLATO en 1978. Jim Horne, de Microsoft, cambió el nombre a FreeCell y reimplementó el juego para <a href="http://rosettacode.org/wiki/DOS" title="DOS">DOS</a> , luego <a href="http://rosettacode.org/wiki/Windows" title="Windows">Windows</a> . </p>
|
||||
<p> Esta versión introdujo 32000 ofertas numeradas. (Las <a href="http://www.solitairelaboratory.com/fcfaq.html" title="enlace: http://www.solitairelaboratory.com/fcfaq.html">preguntas frecuentes de FreeCell</a> cuentan esta historia). </p><p> A medida que el juego se hizo popular, Jim Horne reveló <a href="http://www.solitairelaboratory.com/mshuffle.txt" title="enlace: http://www.solitairelaboratory.com/mshuffle.txt">el algoritmo</a> y otras implementaciones de FreeCell comenzaron a reproducir los acuerdos de Microsoft. </p>
|
||||
<p> Estas ofertas están numeradas del 1 al 32000. </p>
|
||||
<p> Las versiones más nuevas de Microsoft tienen 1 millón de ofertas, numeradas del 1 al 1000000; Algunas implementaciones permiten números fuera de ese rango. </p><p> El algoritmo utiliza este <a href="http://rosettacode.org/wiki/linear congruential generator" title="generador lineal congruente">generador lineal congruente</a> de Microsoft C: </p> $ state_ {n + 1} \ equiv 214013 \ times state_n + 2531011 \ pmod {2 ^ {31}} $
|
||||
$ rand_n = state_n \ div 2 ^ {16} $
|
||||
$ rand_n $ está en el rango de 0 a 32767.
|
||||
<p> El algoritmo sigue: </p> Siembra el RNG con el número de la oferta.
|
||||
Crea una <a href="http://rosettacode.org/wiki/array" title="formación">serie</a> de 52 cartas: As of Clubs, As of Diamonds, As of Hearts, As of Spades, 2 of Clubs, 2 of Diamonds, y así sucesivamente a través de las filas: As, 2, 3, 4, 5, 6 , 7, 8, 9, 10, Jack, reina, rey. Los índices de matriz son de 0 a 51, con Ace of Clubs en 0 y King of Spades en 51.
|
||||
Hasta que la matriz esté vacía:
|
||||
Elija una tarjeta al azar en el índice ≡ siguiente número aleatorio (mod longitud de la matriz).
|
||||
Intercambia esta carta aleatoria con la última carta de la matriz.
|
||||
Eliminar esta tarjeta aleatoria de la matriz. (La longitud de la matriz se reduce en 1.)
|
||||
Repartir esta carta aleatoria.
|
||||
Reparte las 52 cartas, boca arriba, en 8 columnas. Las primeras 8 cartas van en 8 columnas, las siguientes 8 cartas van en las primeras 8 cartas, y así sucesivamente.
|
||||
Ejemplo:
|
||||
<p> Orden para repartir cartas </p>
|
||||
<p> <pre> 1 2 3 4 5 6 7 8
|
||||
9 10 11 12 13 14 15 16
|
||||
17 18 19 20 21 22 23 24
|
||||
25 26 27 28 29 30 31 32
|
||||
33 34 35 36 37 38 39 40
|
||||
41 42 43 44 45 46 47 48
|
||||
49 50 51 52 </pre></p>
|
||||
<p> Juego # 1 </p>
|
||||
<p> <pre> [
|
||||
['JD', '2D', '9H', 'JC', '5D', '7H', '7C', '5H'],
|
||||
['KD', 'KC', '9S', '5S', 'AD', 'QC', 'KH', '3H'],
|
||||
['2S', 'KS', '9D', 'QD', 'JS', 'AS', 'AH' , '3C'],
|
||||
['4C', '5C', 'TS', 'QH', '4H', 'AC', '4D', '7S'],
|
||||
['3S', 'TD' , '4S', 'TH', '8H', '2C', 'JH', '7D'],
|
||||
['6D', '8S', '8D', 'QS', '6C', '3D ',' 8C ',' TC '],
|
||||
[' 6S ',' 9C ',' 2H ',' 6H ']
|
||||
] </pre></p>
|
||||
<p> Juego # 617 </p>
|
||||
<p> <pre> [
|
||||
['7D', 'AD', '5C', '3S', '5S', '8C', '2D', 'AH'],
|
||||
['TD', '7S', 'QD', 'AC', '6D', '8H', 'AS', 'KH'],
|
||||
['TH', 'QC', '3H', '9D', '6S', '8D', '3D' , 'TC'],
|
||||
['KD', '5H', '9S', '3C', '8S', '7H', '4D', 'JS'],
|
||||
['4C', 'QS' , '9C', '9H', '7C', '6H', '2C', '2S'],
|
||||
['4S', 'TS', '2H', '5D', 'JC', '6C ',' JH ',' QH '],
|
||||
[' JD ',' KS ',' KC ',' 4H ']
|
||||
] </pre></p>
|
||||
Tarea:
|
||||
<p> Escriba una función para tomar un número de acuerdo y tarjetas de acuerdo en el mismo orden que este algoritmo. </p>
|
||||
<p> La función debe devolver una matriz bidimensional que representa la placa FreeCell. </p>
|
||||
<p> Las ofertas también pueden <a href="http://freecellgamesolutions.com/" title="enlace: http://freecellgamesolutions.com/">compararse con las soluciones FreeCell para 1000000 juegos</a> . </p>
|
||||
<p> (Invoca una solución de video y muestra el trato inicial.) </p>
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>dealFreeCell</code> es una función.
|
||||
testString: 'assert(typeof dealFreeCell === "function", "<code>dealFreeCell</code> is a function.");'
|
||||
- text: <code>dealFreeCell(seed)</code> debe devolver un objeto.
|
||||
testString: 'assert(typeof dealFreeCell(1) === "object", "<code>dealFreeCell(seed)</code> should return an object.");'
|
||||
- text: <code>dealFreeCell(seed)</code> debe devolver una matriz de longitud 7.
|
||||
testString: 'assert(dealFreeCell(1).length === 7, "<code>dealFreeCell(seed)</code> should return an array of length 7.");'
|
||||
- text: ' <code>dealFreeCell(1)</code> debe devolver una matriz idéntica al ejemplo "Juego # 1"'
|
||||
testString: 'assert.deepEqual(dealFreeCell(1), game1, "<code>dealFreeCell(1)</code> should return an array identical to example "Game #1"");'
|
||||
- text: ' <code>dealFreeCell(617)</code> debe devolver una matriz idéntica al ejemplo "Juego # 617"'
|
||||
testString: 'assert.deepEqual(dealFreeCell(617), game617, "<code>dealFreeCell(617)</code> should return an array identical to example "Game #617"");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function dealFreeCell (seed) {
|
||||
// Good luck!
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
console.info('after the test');
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
// RNG
|
||||
function FreeCellRNG (seed) {
|
||||
return {
|
||||
lastNum: seed,
|
||||
next() {
|
||||
this.lastNum = ((214013 * this.lastNum) + 2531011) % (Math.pow(2, 31));
|
||||
return this.lastNum >> 16;
|
||||
}
|
||||
};
|
||||
}
|
||||
// Get cards
|
||||
function getDeck() {
|
||||
const ranks = ['A', '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K'];
|
||||
const suits = ['C', 'D', 'H', 'S'];
|
||||
const cards = [];
|
||||
for (let i = 0; i < ranks.length; i += 1) {
|
||||
for (let j = 0; j < suits.length; j += 1) {
|
||||
cards.push(`${ranks[i]}${suits[j]}`);
|
||||
}
|
||||
}
|
||||
return cards;
|
||||
}
|
||||
function dealFreeCell(seed) {
|
||||
const rng = FreeCellRNG(seed);
|
||||
const deck = getDeck();
|
||||
|
||||
const deltCards = [[], [], [], [], [], [], []];
|
||||
let currentColumn = 0;
|
||||
let currentRow = 0;
|
||||
|
||||
let rand;
|
||||
let temp;
|
||||
let card;
|
||||
while (deck.length > 0) {
|
||||
// Choose a random card
|
||||
rand = rng.next() % deck.length;
|
||||
|
||||
// Swap this random card with the last card in the array
|
||||
temp = deck[deck.length - 1];
|
||||
deck[deck.length - 1] = deck[rand];
|
||||
deck[rand] = temp;
|
||||
|
||||
// Remove this card from the array
|
||||
card = deck.pop();
|
||||
|
||||
// Deal this card
|
||||
deltCards[currentRow].push(card);
|
||||
currentColumn += 1;
|
||||
if (currentColumn === 8) {
|
||||
currentColumn = 0;
|
||||
currentRow += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return deltCards;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,83 @@
|
||||
---
|
||||
title: Deepcopy
|
||||
id: 596a8888ab7c01048de257d5
|
||||
localeTitle: 596a8888ab7c01048de257d5
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Tarea:
|
||||
<p> Escribe una función que devuelva una copia profunda de un objeto dado. </p>
|
||||
<p> La copia no debe ser el mismo objeto que se le dio. </p>
|
||||
<p> Esta tarea no probará para: </p>
|
||||
Objetos con propiedades que son funciones
|
||||
Objetos de fecha u objeto con propiedades que son objetos de fecha
|
||||
RegEx u objeto con propiedades que son objetos de RegEx
|
||||
Copia de prototipo
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>deepcopy</code> debe ser una función.
|
||||
testString: 'assert(typeof deepcopy === "function", "<code>deepcopy</code> should be a function.");'
|
||||
- text: ' <code>deepcopy({test: "test"})</code> debe devolver un objeto.'
|
||||
testString: 'assert(typeof deepcopy(obj1) === "object", "<code>deepcopy({test: "test"})</code> should return an object.");'
|
||||
- text: No debe devolver el mismo objeto que se proporcionó.
|
||||
testString: 'assert(deepcopy(obj2) != obj2, "Should not return the same object that was provided.");'
|
||||
- text: 'Cuando se pasa un objeto que contiene una matriz, debe devolver una copia profunda del objeto'.
|
||||
testString: 'assert.deepEqual(deepcopy(obj2), obj2, "When passed an object containing an array, should return a deep copy of the object.");'
|
||||
- text: 'Cuando se pasa un objeto que contiene otro objeto, debe devolver una copia profunda del objeto'.
|
||||
testString: 'assert.deepEqual(deepcopy(obj3), obj3, "When passed an object containing another object, should return a deep copy of the object.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function deepcopy (obj) {
|
||||
// Good luck!
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
console.info('after the test');
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
function deepcopy(obj) {
|
||||
return JSON.parse(JSON.stringify(obj));
|
||||
}
|
||||
|
||||
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,118 @@
|
||||
---
|
||||
title: Define a primitive data type
|
||||
id: 597089c87eec450c68aa1643
|
||||
localeTitle: 597089c87eec450c68aa1643
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Tarea:
|
||||
<p> Defina un tipo que se comporte como un entero pero que tenga un valor válido más bajo de 1 y un valor válido más alto de 10. </p>
|
||||
Errores:
|
||||
Si intenta crear una instancia de un <code>Num</code> con un valor fuera de 1 - 10
|
||||
, debe lanzar un <code>TypeError</code> con un mensaje de error de <code>'Out of range'</code> .
|
||||
Si intenta crear una instancia de un <code>Num</code> con un valor que no es un número
|
||||
, debe lanzar un <code>TypeError</code> con un mensaje de error <code>'Not a Number'</code> .
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>Num</code> debería ser una función.
|
||||
testString: 'assert(typeof Num === "function", "<code>Num</code> should be a function.");'
|
||||
- text: <code>new Num(4)</code> debe devolver un objeto.
|
||||
testString: 'assert(typeof (new Num(4)) === "object", "<code>new Num(4)</code> should return an object.");'
|
||||
- text: <code>new Num(\'test\')</code> debe lanzar un TypeError con el mensaje \ 'Not a Number \'.
|
||||
testString: 'assert(throws(() => new Num("test"), TypeError, "Not a Number"), "<code>new Num(\"test\")</code> should throw a TypeError with message \"Not a Number\".");'
|
||||
- text: <code>new Num(0)</code> debe lanzar un TypeError con el mensaje \ 'Fuera de rango \'.
|
||||
testString: 'assert(throws(() => new Num(0), TypeError, "Out of range"), "<code>new Num(0)</code> should throw a TypeError with message \"Out of range\".");'
|
||||
- text: <code>new Num(-5)</code> debe lanzar un TypeError con el mensaje "Fuera de rango".
|
||||
testString: 'assert(throws(() => new Num(-5), TypeError, "Out of range"), "<code>new Num(-5)</code> should throw a TypeError with message \"Out of range\".");'
|
||||
- text: <code>new Num(10)</code> debe lanzar un TypeError con el mensaje \ 'Fuera de rango \'.
|
||||
testString: 'assert(throws(() => new Num(11), TypeError, "Out of range"), "<code>new Num(10)</code> should throw a TypeError with message \"Out of range\".");'
|
||||
- text: <code>new Num(20)</code> debe lanzar un TypeError con el mensaje \ 'Fuera de rango \'.
|
||||
testString: 'assert(throws(() => new Num(20), TypeError, "Out of range"), "<code>new Num(20)</code> should throw a TypeError with message \"Out of range\".");'
|
||||
- text: <code>new Num(3) + new Num(4)</code> debe ser igual a 7.
|
||||
testString: 'assert.equal(new Num(3) + new Num(4), 7, "<code>new Num(3) + new Num(4)</code> should equal 7.");'
|
||||
- text: <code>new Num(3) - new Num(4)</code> debe ser igual a -1.
|
||||
testString: 'assert.equal(new Num(3) - new Num(4), -1, "<code>new Num(3) - new Num(4)</code> should equal -1.");'
|
||||
- text: <code>new Num(3) * new Num(4)</code> debe ser igual a 12.
|
||||
testString: 'assert.equal(new Num(3) * new Num(4), 12, "<code>new Num(3) * new Num(4)</code> should equal 12.");'
|
||||
- text: <code>new Num(3) / new Num(4)</code> debe ser igual a 0.75.
|
||||
testString: 'assert.equal(new Num(3) / new Num(4), 0.75, "<code>new Num(3) / new Num(4)</code> should equal 0.75.");'
|
||||
- text: <code>new Num(3) < new Num(4)</code> debe ser verdadero.
|
||||
testString: 'assert(new Num(3) < new Num(4), "<code>new Num(3) < new Num(4)</code> should be true.");'
|
||||
- text: <code>new Num(3) > new Num(4)</code> debe ser falso.
|
||||
testString: 'assert(!(new Num(3) > new Num(4)), "<code>new Num(3) > new Num(4)</code> should be false.");'
|
||||
- text: <code>(new Num(5)).toString()</code> debe devolver \ '5 \'
|
||||
testString: 'assert.equal((new Num(5)).toString(), "5", "<code>(new Num(5)).toString()</code> should return \"5\"");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function Num (n) {
|
||||
// Good luck!
|
||||
return n;
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
function Num(n) {
|
||||
const num = Math.floor(n);
|
||||
if (isNaN(num)) {
|
||||
throw new TypeError('Not a Number');
|
||||
}
|
||||
if (num < 1 || num > 10) {
|
||||
throw new TypeError('Out of range');
|
||||
}
|
||||
|
||||
this._value = num;
|
||||
}
|
||||
Num.prototype.valueOf = function() { return this._value; };
|
||||
Num.prototype.toString = function () { return this._value.toString(); };
|
||||
|
||||
function throws(func, errorType, msg) {
|
||||
let hasThrown = false;
|
||||
let errorMsg = ";
|
||||
let correctType = false;
|
||||
try {
|
||||
func();
|
||||
}
|
||||
catch (e) {
|
||||
hasThrown = true;
|
||||
errorMsg = e.message;
|
||||
if (e instanceof errorType) {
|
||||
correctType = true;
|
||||
}
|
||||
}
|
||||
return hasThrown && correctType && msg === errorMsg;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,115 @@
|
||||
---
|
||||
title: Department Numbers
|
||||
id: 59f40b17e79dbf1ab720ed7a
|
||||
localeTitle: 59f40b17e79dbf1ab720ed7a
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
<p> Hay una ciudad altamente organizada que ha decidido asignar un número a cada uno de sus departamentos: </p>
|
||||
Policía del departamento
|
||||
Saneamiento departamento de
|
||||
Cuerpo de bomberos
|
||||
<p> Cada departamento puede tener un número entre 1 y 7 (inclusive). </p><p> Los tres números de departamento deben ser únicos (diferentes entre sí) y deben sumar hasta el número 12. </p><p> Al jefe de la policía no le gustan los números impares y quiere tener un número par para su departamento. </p>
|
||||
Tarea:
|
||||
<p> Escriba un programa que produzca todas las combinaciones válidas: </p>
|
||||
<p> [2, 3, 7] </p>
|
||||
<p> [2, 4, 6] </p>
|
||||
<p> [2, 6, 4] </p>
|
||||
<p> [2, 7, 3] </p>
|
||||
<p> [4, 1, 7] </p>
|
||||
<p> [4, 2, 6] </p>
|
||||
<p> [4, 3, 5] </p>
|
||||
<p> [4, 5, 3] </p>
|
||||
<p> [4, 6, 2] </p>
|
||||
<p> [4, 7, 1] </p>
|
||||
<p> [6, 1, 5] </p>
|
||||
<p> [6, 2, 4] </p>
|
||||
<p> [6, 4, 2] </p>
|
||||
<p> [6, 5, 1] </p>
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>combinations</code> deben ser una función.
|
||||
testString: 'assert(typeof combinations === "function", "<code>combinations</code> should be a function.");'
|
||||
- text: ' <code>combinations([1, 2, 3], 6)</code> deben devolver un Array.'
|
||||
testString: 'assert(Array.isArray(combinations([1, 2, 3], 6)), "<code>combinations([1, 2, 3], 6)</code> should return an Array.");'
|
||||
- text: ' <code>combinations([1, 2, 3, 4, 5, 6, 7], 12)</code> deben devolver una matriz de longitud 14.'
|
||||
testString: 'assert(combinations(nums, total).length === len, "<code>combinations([1, 2, 3, 4, 5, 6, 7], 12)</code> should return an array of length 14.");'
|
||||
- text: ' <code>combinations([1, 2, 3, 4, 5, 6, 7], 12)</code> deben devolver todas las combinaciones válidas.'
|
||||
testString: 'assert.deepEqual(combinations(nums, total), result, "<code>combinations([1, 2, 3, 4, 5, 6, 7], 12)</code> should return all valid combinations.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function combinations (possibleNumbers, total) {
|
||||
// Good luck!
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
console.info('after the test');
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
function combinations (possibleNumbers, total) {
|
||||
let firstNumber;
|
||||
let secondNumber;
|
||||
let thridNumber;
|
||||
const allCombinations = [];
|
||||
|
||||
for (let i = 0; i < possibleNumbers.length; i += 1) {
|
||||
firstNumber = possibleNumbers[i];
|
||||
|
||||
if (firstNumber % 2 === 0) {
|
||||
for (let j = 0; j < possibleNumbers.length; j += 1) {
|
||||
secondNumber = possibleNumbers[j];
|
||||
|
||||
if (j !== i && firstNumber + secondNumber <= total) {
|
||||
thridNumber = total - firstNumber - secondNumber;
|
||||
|
||||
if (thridNumber !== firstNumber && thridNumber !== secondNumber && possibleNumbers.includes(thridNumber)) {
|
||||
allCombinations.push([firstNumber, secondNumber, thridNumber]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return allCombinations;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,169 @@
|
||||
---
|
||||
title: Discordian date
|
||||
id: 59f4eafba0343628bb682785
|
||||
localeTitle: 59f4eafba0343628bb682785
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Tarea:
|
||||
<p> Convierte una fecha dada del <a href="https://en.wikipedia.org/wiki/Gregorian calendar" title="wp: calendario gregoriano">calendario gregoriano al calendario</a> <a href="https://en.wikipedia.org/wiki/Discordian calendar" title="wp: calendario discordiano">Discordiano</a> . </p>
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>discordianDate</code> es una función.
|
||||
testString: 'assert(typeof discordianDate === "function", "<code>discordianDate</code> is a function.");'
|
||||
- text: ' <code>discordianDate(new Date(2010, 6, 22))</code> debe devolver <code>"Pungenday, the 57th day of Confusion in the YOLD 3176"</code> .'
|
||||
testString: 'assert(discordianDate(new Date(2010, 6, 22)) === "Pungenday, the 57th day of Confusion in the YOLD 3176", "<code>discordianDate(new Date(2010, 6, 22))</code> should return <code>"Pungenday, the 57th day of Confusion in the YOLD 3176"</code>.");'
|
||||
- text: ' <code>discordianDate(new Date(2012, 1, 28))</code> debe devolver <code>"Prickle-Prickle, the 59th day of Chaos in the YOLD 3178"</code> .'
|
||||
testString: 'assert(discordianDate(new Date(2012, 1, 28)) === "Prickle-Prickle, the 59th day of Chaos in the YOLD 3178", "<code>discordianDate(new Date(2012, 1, 28))</code> should return <code>"Prickle-Prickle, the 59th day of Chaos in the YOLD 3178"</code>.");'
|
||||
- text: ' <code>discordianDate(new Date(2012, 1, 29))</code> debe devolver <code>"Setting Orange, the 60th day of Chaos in the YOLD 3178. Celebrate St. Tib\"s Day!"</code> .'
|
||||
testString: 'assert(discordianDate(new Date(2012, 1, 29)) === "Setting Orange, the 60th day of Chaos in the YOLD 3178. Celebrate St. Tib\"s Day!", "<code>discordianDate(new Date(2012, 1, 29))</code> should return <code>"Setting Orange, the 60th day of Chaos in the YOLD 3178. Celebrate St. Tib\"s Day!"</code>.");'
|
||||
- text: ' <code>discordianDate(new Date(2012, 2, 1))</code> debe devolver <code>"Setting Orange, the 60th day of Chaos in the YOLD 3178"</code> .'
|
||||
testString: 'assert(discordianDate(new Date(2012, 2, 1)) === "Setting Orange, the 60th day of Chaos in the YOLD 3178", "<code>discordianDate(new Date(2012, 2, 1))</code> should return <code>"Setting Orange, the 60th day of Chaos in the YOLD 3178"</code>.");'
|
||||
- text: ' <code>discordianDate(new Date(2010, 0, 5))</code> debe devolver <code>"Setting Orange, the 5th day of Chaos in the YOLD 3176. Celebrate Mungday!"</code> .
|
||||
testString: 'assert(discordianDate(new Date(2010, 0, 5)) === "Setting Orange, the 5th day of Chaos in the YOLD 3176. Celebrate Mungday!", "<code>discordianDate(new Date(2010, 0, 5))</code> should return <code>"Setting Orange, the 5th day of Chaos in the YOLD 3176. Celebrate Mungday!"</code>.");'
|
||||
- text: ' <code>discordianDate(new Date(2011, 4, 3))</code> debe devolver <code>"Pungenday, the 50th day of Discord in the YOLD 3177. Celebrate Discoflux!"</code> .
|
||||
testString: 'assert(discordianDate(new Date(2011, 4, 3)) === "Pungenday, the 50th day of Discord in the YOLD 3177. Celebrate Discoflux!", "<code>discordianDate(new Date(2011, 4, 3))</code> should return <code>"Pungenday, the 50th day of Discord in the YOLD 3177. Celebrate Discoflux!"</code>.");'
|
||||
- text: ' <code>discordianDate(new Date(2015, 9, 19))</code> debe devolver <code>"Boomtime, the 73rd day of Bureaucracy in the YOLD 3181"</code> .
|
||||
testString: 'assert(discordianDate(new Date(2015, 9, 19)) === "Boomtime, the 73rd day of Bureaucracy in the YOLD 3181", "<code>discordianDate(new Date(2015, 9, 19))</code> should return <code>"Boomtime, the 73rd day of Bureaucracy in the YOLD 3181"</code>.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function discordianDate (date) {
|
||||
// Good luck!
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
/**
|
||||
* All Hail Discordia! - this script prints Discordian date using system date.
|
||||
*
|
||||
* lang: JavaScript
|
||||
* author: jklu
|
||||
* contributors: JamesMcGuigan
|
||||
*
|
||||
* source: https://rosettacode.org/wiki/Discordian_date#JavaScript
|
||||
*/
|
||||
const seasons = [
|
||||
'Chaos', 'Discord', 'Confusion',
|
||||
'Bureaucracy', 'The Aftermath'
|
||||
];
|
||||
const weekday = [
|
||||
'Sweetmorn', 'Boomtime', 'Pungenday',
|
||||
'Prickle-Prickle', 'Setting Orange'
|
||||
];
|
||||
|
||||
const apostle = [
|
||||
'Mungday', 'Mojoday', 'Syaday',
|
||||
'Zaraday', 'Maladay'
|
||||
];
|
||||
|
||||
const holiday = [
|
||||
'Chaoflux', 'Discoflux', 'Confuflux',
|
||||
'Bureflux', 'Afflux'
|
||||
];
|
||||
|
||||
|
||||
Date.prototype.isLeapYear = function() {
|
||||
const year = this.getFullYear();
|
||||
if ((year & 3) !== 0) { return false; }
|
||||
return ((year % 100) !== 0 || (year % 400) === 0);
|
||||
};
|
||||
|
||||
// Get Day of Year
|
||||
Date.prototype.getDOY = function() {
|
||||
const dayCount = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];
|
||||
const mn = this.getMonth();
|
||||
const dn = this.getDate();
|
||||
let dayOfYear = dayCount[mn] + dn;
|
||||
if (mn > 1 && this.isLeapYear()) { dayOfYear += 1; }
|
||||
return dayOfYear;
|
||||
};
|
||||
|
||||
Date.prototype.isToday = function() {
|
||||
const today = new Date();
|
||||
return this.getDate() === today.getDate()
|
||||
&& this.getMonth() === today.getMonth()
|
||||
&& this.getFullYear() === today.getFullYear()
|
||||
;
|
||||
};
|
||||
|
||||
function discordianDate(date) {
|
||||
if (!date) { date = new Date(); }
|
||||
|
||||
const y = date.getFullYear();
|
||||
const yold = y + 1166;
|
||||
let dayOfYear = date.getDOY();
|
||||
let celebrateHoliday = null;
|
||||
|
||||
if (date.isLeapYear()) {
|
||||
if (dayOfYear === 60) {
|
||||
celebrateHoliday = 'St. Tib\'s Day';
|
||||
}
|
||||
else if (dayOfYear > 60) {
|
||||
dayOfYear--;
|
||||
}
|
||||
}
|
||||
dayOfYear--;
|
||||
|
||||
const divDay = Math.floor(dayOfYear / 73);
|
||||
|
||||
const seasonDay = (dayOfYear % 73) + 1;
|
||||
if (seasonDay === 5) {
|
||||
celebrateHoliday = apostle[divDay];
|
||||
}
|
||||
if (seasonDay === 50) {
|
||||
celebrateHoliday = holiday[divDay];
|
||||
}
|
||||
|
||||
const season = seasons[divDay];
|
||||
const dayOfWeek = weekday[dayOfYear % 5];
|
||||
|
||||
const nth = (seasonDay % 10 === 1) ? 'st'
|
||||
: (seasonDay % 10 === 2) ? 'nd'
|
||||
: (seasonDay % 10 === 3) ? 'rd'
|
||||
: 'th';
|
||||
|
||||
return "
|
||||
+ dayOfWeek
|
||||
+ ', the ' + seasonDay + nth
|
||||
+ ' day of ' + season
|
||||
+ ' in the YOLD ' + yold
|
||||
+ (celebrateHoliday ? '. Celebrate ' + celebrateHoliday + '!' : ")
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,92 @@
|
||||
---
|
||||
title: Element-wise operations
|
||||
id: 599c333915e0ea32d04d4bec
|
||||
localeTitle: 599c333915e0ea32d04d4bec
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
<p> Implementar operaciones básicas de matriz de matriz de elementos y matriz escalar. </p><p> Implementar: </p>
|
||||
<p> :: * Además </p>
|
||||
<p> :: * resta </p>
|
||||
<p> :: * multiplicación </p>
|
||||
<p> :: * división </p>
|
||||
<p> :: * exponenciación </p>
|
||||
<p> El primer parámetro será la operación a realizar, por ejemplo: "m_add" para la adición de matriz y "s_add" para la adición escalar. Los parámetros segundo y tercero serán las matrices sobre las que se realizarán las operaciones.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>operation</code> es una función.
|
||||
testString: 'assert(typeof operation === "function", "<code>operation</code> is a function.");'
|
||||
- text: ' <code>operation("m_add",[[1,2],[3,4]],[[1,2],[3,4]])</code> debe devolver <code>[[2,4],[6,8]]</code> .
|
||||
testString: 'assert.deepEqual(operation("m_add", [[1, 2], [3, 4]], [[1, 2], [3, 4]]), [[2, 4], [6, 8]], "<code>operation("m_add",[[1,2],[3,4]],[[1,2],[3,4]])</code> should return <code>[[2,4],[6,8]]</code>.");'
|
||||
- text: ' <code>operation("s_add",[[1,2],[3,4]],[[1,2],[3,4]])</code> debe devolver <code>[[3,4],[5,6]]</code> .
|
||||
testString: 'assert.deepEqual(operation("s_add", [[1, 2], [3, 4]], 2), [[3, 4], [5, 6]], "<code>operation("s_add",[[1,2],[3,4]],[[1,2],[3,4]])</code> should return <code>[[3,4],[5,6]]</code>.");'
|
||||
- text: ' <code>operation("m_sub",[[1,2],[3,4]],[[1,2],[3,4]])</code> debe devolver <code>[[0,0],[0,0]]</code> .
|
||||
testString: 'assert.deepEqual(operation("m_sub", [[1, 2], [3, 4]], [[1, 2], [3, 4]]), [[0, 0], [0, 0]], "<code>operation("m_sub",[[1,2],[3,4]],[[1,2],[3,4]])</code> should return <code>[[0,0],[0,0]]</code>.");'
|
||||
- text: ' <code>operation("m_mult",[[1,2],[3,4]],[[1,2],[3,4]])</code> debe devolver <code>[[1,4],[9,16]]</code> .
|
||||
testString: 'assert.deepEqual(operation("m_mult", [[1, 2], [3, 4]], [[1, 2], [3, 4]]), [[1, 4], [9, 16]], "<code>operation("m_mult",[[1,2],[3,4]],[[1,2],[3,4]])</code> should return <code>[[1,4],[9,16]]</code>.");'
|
||||
- text: ' <code>operation("m_div",[[1,2],[3,4]],[[1,2],[3,4]])</code> debe devolver <code>[[1,1],[1,1]]</code> .
|
||||
testString: 'assert.deepEqual(operation("m_div", [[1, 2], [3, 4]], [[1, 2], [3, 4]]), [[1, 1], [1, 1]], "<code>operation("m_div",[[1,2],[3,4]],[[1,2],[3,4]])</code> should return <code>[[1,1],[1,1]]</code>.");'
|
||||
- text: 'la <code>operation("m_exp",[[1,2],[3,4]],[[1,2],[3,4]])</code> debe devolver <code>[[1,4],[27,256]]</code> .'
|
||||
testString: 'assert.deepEqual(operation("m_exp", [[1, 2], [3, 4]], [[1, 2], [3, 4]]), [[1, 4], [27, 256]], "<code>operation("m_exp",[[1,2],[3,4]],[[1,2],[3,4]])</code> should return <code>[[1,4],[27,256]]</code>.");'
|
||||
- text: ' <code>operation("m_add",[[1,2,3,4],[5,6,7,8]],[[9,10,11,12],[13,14,15,16]])</code> debe devolver <code>[[10,12,14,16],[18,20,22,24]]</code> . '
|
||||
testString: 'assert.deepEqual(operation("m_add", [[1, 2, 3, 4], [5, 6, 7, 8]], [[9, 10, 11, 12], [13, 14, 15, 16]]), [[10, 12, 14, 16], [18, 20, 22, 24]], "<code>operation("m_add",[[1,2,3,4],[5,6,7,8]],[[9,10,11,12],[13,14,15,16]])</code> should return <code>[[10,12,14,16],[18,20,22,24]]</code>.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function operation (op, arr1, arr2) {
|
||||
// Good luck!
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
function operation(op, arr1, arr2) {
|
||||
const ops = {
|
||||
add: ((a, b) => a + b),
|
||||
sub: ((a, b) => a - b),
|
||||
mult: ((a, b) => a * b),
|
||||
div: ((a, b) => a / b),
|
||||
exp: ((a, b) => Math.pow(a, b))
|
||||
};
|
||||
const ifm = op.startsWith('m');
|
||||
const doOp = ops[op.substring(2)];
|
||||
for (let i = 0; i < arr1.length; i++) {
|
||||
for (let j = 0; j < arr1[0].length; j++) {
|
||||
arr1[i][j] = doOp(arr1[i][j], (ifm) ? (arr2[i][j]) : (arr2));
|
||||
}
|
||||
}
|
||||
return arr1;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</section>
|
@@ -0,0 +1,99 @@
|
||||
---
|
||||
title: Emirp primes
|
||||
id: 599d0ba974141b0f508b37d5
|
||||
localeTitle: 599d0ba974141b0f508b37d5
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
<p> Un emirp (primo deletreado al revés) son primos que cuando se invierten (en su representación decimal) son primos diferentes. </p>
|
||||
<p> Escriba una función que debería ser capaz de: Mostrar los primeros <b>n</b> eprimes números. Mostrar los números de eprimes en un rango. Mostrar el número de eprimes en un rango. Mostrar el <b>n <sup>número de</sup></b> eprimes. <p> La función debe tener dos parámetros. El primero recibirá <b>n</b> o el rango como una matriz. El segundo recibirá un valor booleano, que especifica si la función devuelve los eprimes como una matriz o un único número (el número de números primos en el rango o la <b><sup>enésima</sup></b> primo). De acuerdo con los parámetros, la función debe devolver una matriz o un número.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>emirps</code> es una función.
|
||||
testString: 'assert(typeof emirps === "function", "<code>emirps</code> is a function.");'
|
||||
- text: ' <code>emirps(20,true)</code> debe devolver <code>[13,17,31,37,71,73,79,97,107,113,149,157,167,179,199,311,337,347,359,389]</code> '
|
||||
testString: 'assert.deepEqual(emirps(20, true), [13, 17, 31, 37, 71, 73, 79, 97, 107, 113, 149, 157, 167, 179, 199, 311, 337, 347, 359, 389], "<code>emirps(20,true)</code> should return <code>[13,17,31,37,71,73,79,97,107,113,149,157,167,179,199,311,337,347,359,389]</code>");'
|
||||
- text: <code>emirps(10000)</code> deben devolver <code>948349</code>
|
||||
testString: 'assert.deepEqual(emirps(10000), 948349, "<code>emirps(10000)</code> should return <code>948349</code>");'
|
||||
- text: ' <code>emirps([7700,8000],true)</code> debe devolver <code>[7717,7757,7817,7841,7867,7879,7901,7927,7949,7951,7963]</code> '
|
||||
testString: 'assert.deepEqual(emirps([7700, 8000], true), [7717, 7757, 7817, 7841, 7867, 7879, 7901, 7927, 7949, 7951, 7963], "<code>emirps([7700,8000],true)</code> should return <code>[7717,7757,7817,7841,7867,7879,7901,7927,7949,7951,7963]</code>");'
|
||||
- text: ' <code>emirps([7700,8000],true)</code> debe devolver <code>11</code> '
|
||||
testString: 'assert.deepEqual(emirps([7700, 8000], false), 11, "<code>emirps([7700,8000],true)</code> should return <code>11</code>");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function emirps(n) {
|
||||
// Good luck!
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
|
||||
```js
|
||||
// noprotect
|
||||
function emirps(num, showEmirps)
|
||||
{
|
||||
const is_prime = function(n)
|
||||
{
|
||||
if (!(n % 2) || !(n % 3)) return false;
|
||||
let p = 1;
|
||||
while (p * p < n)
|
||||
{ if (n % (p += 4) == 0 || n % (p += 2) == 0)
|
||||
{ return false; } }
|
||||
return true;
|
||||
};
|
||||
const is_emirp = function(n) {
|
||||
const r = parseInt(n.toString().split('').reverse().join(''));
|
||||
return r != n && is_prime(n) && is_prime(r);
|
||||
};
|
||||
|
||||
let i,
|
||||
arr = [];
|
||||
if (typeof num === 'number') {
|
||||
for (i = 0; arr.length < num; i++) if (is_emirp(i)) arr.push(i);
|
||||
// first x emirps
|
||||
if (showEmirps) return arr;
|
||||
// xth emirp
|
||||
return arr.pop();
|
||||
}
|
||||
|
||||
if (Array.isArray(num)) {
|
||||
for (i = num[0]; i <= num[1]; i++) if (is_emirp(i)) arr.push(i);
|
||||
// emirps between x .. y
|
||||
if (showEmirps) return arr;
|
||||
// number of emirps between x .. y
|
||||
return arr.length;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</section>
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user